Exemplo n.º 1
0
    // -----------------------------------------------------------------------------------------------------------------
    public CTile.EDirection SetPlayerDestination(CTile cur_tile, CTile.EDirection dir)
    {
        CTile.EDirection   dir_next            = CTile.DIR_EX[(int)dir].m_next;
        CTile.EDirection   dir_next_next       = CTile.DIR_EX[(int)dir_next].m_next;
        CTile.EDirection   dir_prev            = CTile.DIR_EX[(int)dir].m_prev;
        CTile.EDirection   dir_prev_prev       = CTile.DIR_EX[(int)dir_prev].m_prev;
        CTile.EDirection   dir_back            = CTile.DIR_EX[(int)dir].m_opposite;
        CTile.EDirection[] dir_selection_order = { dir, dir_next, dir_prev, dir_next_next, dir_prev_prev, dir_back };

        CTile.EDirection final_dir = dir;
        foreach (CTile.EDirection d in dir_selection_order)
        {
            m_dest_tile = cur_tile.GetNeighbor(d);
            if (m_dest_tile != null &&
                !m_level_tags.IsTagSet(m_dest_tile, (int)CTile.ETag.T_BORDER))
            {
                final_dir = d;
                break;
            }
        }

        utils.Assert(m_dest_tile != null, "Destination tile is null");

        m_direction = dir;
        m_player.SetDestination(m_dest_tile.GetPosition());

//        utils.Log("Set player destination :: cur={0}:{1} dest={2}:{3} dir={4}",
//            cur_tile.m_x, cur_tile.m_z, m_dest_tile.m_x, m_dest_tile.m_z, dir);
        return(final_dir);
    }
Exemplo n.º 2
0
    // -----------------------------------------------------------------------------------------------------------------
    public CTile GetTileByOffset(CTile t, CTile.EDirection dir, int offset)
    {
        int x = 0, z = 0;

        t.GetTilePosXZByOffset(dir, offset, ref x, ref z);
        return(GetTileByPosXZ(x, z));
    }
Exemplo n.º 3
0
 // -------------------------------------------------------------------------------------------------------------
 public CDirectionEx(float angle, EDirection opposite, EDirection next, EDirection prev)
 {
     m_opposite = opposite;
     m_next     = next;
     m_prev     = prev;
     m_angle    = angle;
     m_pos.Set((float)Math.Cos(angle), (float)Math.Sin(angle));
 }
Exemplo n.º 4
0
    // -----------------------------------------------------------------------------------------------------------------
    public void GetTilePosXZByOffset(CTile.EDirection dir, int offset, ref int x, ref int z)
    {
        // Convert negative offset to positive by inverting direction
        if (offset < 0)
        {
            offset = -offset;
            dir    = CTile.DIR_EX[(int)dir].m_opposite;
        }

        // Handle positive offset
        int z_parity             = utils.GetParity(m_idx.y);
        int off_parity           = utils.GetParity(offset);
        int z_parity_inv         = ((z_parity == 0) ? 1 : 0);
        int half_offset_positive = (offset + z_parity) / 2;
        int half_offset_negative = offset / 2 + ((off_parity == 1) ? z_parity_inv : 0);

        if (dir == CTile.EDirection.DIR_3)            // 3: right
        {
            x = m_idx.x + offset;
            z = m_idx.y;
        }
        else if (dir == CTile.EDirection.DIR_9)      // 9: left
        {
            x = m_idx.x - offset;
            z = m_idx.y;
        }
        else if (dir == CTile.EDirection.DIR_1)      // 1: right - up
        {
            x = m_idx.x + half_offset_positive;
            z = m_idx.y + offset;
        }
        else if (dir == CTile.EDirection.DIR_5)      // 5: right - down
        {
            x = m_idx.x + half_offset_positive;
            z = m_idx.y - offset;
        }
        else if (dir == CTile.EDirection.DIR_7)      // 7: left - down
        {
            x = m_idx.x - half_offset_negative;
            z = m_idx.y - offset;
        }
        else if (dir == CTile.EDirection.DIR_11)     // 11: left - up
        {
            x = m_idx.x - half_offset_negative;
            z = m_idx.y + offset;
        }
        else                                         // ???: should not happen
        {
            x = z = 0;
            utils.Assert(true, "Invalid direction");
        }
    }
Exemplo n.º 5
0
    // -----------------------------------------------------------------------------------------------------------------
    public void SetPlayerPosition(int tile_x, int tile_z, CTile.EDirection dir)
    {
        // Current tile
        CTile t = m_level.GetTileByPosXZ(tile_x, tile_z);

        utils.Assert(t != null, "No source tile :: pos={0}:{1}", tile_x, tile_z);

        // Initial position and rotation
        Vector3 pos = t.GetPosition();

        m_player.transform.position    = new Vector3(pos.x, pos.y + 0.5f, pos.z);
        m_player.transform.eulerAngles = new Vector3(0.0f, CTile.DIR_EX[(int)m_direction].m_angle, 0.0f);

        // Destination
        SetPlayerDestination(t, dir);

        // Player trail
        m_path.Reset();
    }
Exemplo n.º 6
0
    // -----------------------------------------------------------------------------------------------------------------
    private void Update()
    {
        // Turn right
        if (Input.GetKeyDown("right"))
        {
            m_direction = CTile.DIR_EX[(int)m_direction].m_next;

            // Turn left
        }
        else if (Input.GetKeyDown("left"))
        {
            m_direction = CTile.DIR_EX[(int)m_direction].m_prev;
        }

        // Current player position & underlying tile
        Vector3 cur_pos  = m_player.transform.position;
        CTile   cur_tile = m_level.GetTileByCoord(cur_pos.x, cur_pos.z);

        // Update compas
        m_compas.SetPosition(cur_pos);

        // Active tile is changed
        if (cur_tile != m_prev_frame_tile && m_prev_frame_tile != null)
        {
            // Update current and previously visited tiles
            m_prev_tile = m_prev_frame_tile;
            m_level_tags.SetTag(m_prev_tile, (int)CTile.ETag.T_VISITED);
            m_level_tags.SetTag(cur_tile, (int)CTile.ETag.T_CURRENT);

            // Update destination path
            m_level_tags.ClearTag((int)CTile.ETag.T_DEST_PATH);
            CTile t_glow = cur_tile;
            while (true)
            {
                t_glow = t_glow.GetNeighbor(m_direction);
                if (t_glow == null ||
                    !m_level_tags.SetTag(t_glow, (int)CTile.ETag.T_DEST_PATH))
                {
                    break;
                }
            }

            // Update trail - finalize border vertex between tiles
            Vector3 tile_border = m_prev_frame_tile.GetPosition() + (cur_tile.GetPosition() - m_prev_frame_tile.GetPosition()) / 2;
            tile_border.y += 0.5f;
            m_path.AddVertex(tile_border, true);

            // Active tile was not changed
        }
        else
        {
            // Update trail - update head vertex
            m_path.AddVertex(cur_pos, false);
        }

        // Destination tile is reached
        CTile.ERelPosition rel_pos = cur_tile.GetRelPosition(m_dest_tile, m_direction);
        if (rel_pos == CTile.ERelPosition.RP_CURRENT ||
            rel_pos == CTile.ERelPosition.RP_BEHIND ||
            rel_pos == CTile.ERelPosition.RP_NONE)
        {
            m_direction       = SetPlayerDestination(cur_tile, m_direction);
            m_prev_frame_tile = cur_tile;
        }

        // Save tile of previous frame
        m_prev_frame_tile = cur_tile;

        // Eat apple
        if (m_level_tags.IsTagSet(cur_tile, (int)CTile.ETag.T_APPLE))
        {
            m_level_tags.UnsetTag(cur_tile, (int)CTile.ETag.T_APPLE);
            m_tail.AddSegment();
            m_config.score++;
        }

        // Create new apple
        if (m_level_tags.GetTagCnt((int)CTile.ETag.T_APPLE) == 0)
        {
            CTile t = CreateApple();
            m_compas.SetDestination(t.GetPosition());
        }

        // Apply level changeset
        Hashtable changeset = m_level_tags.GetChangeset();

        if (changeset.Count > 0)
        {
            // Update all tiles in changeset
            foreach (DictionaryEntry entry in changeset)
            {
                CTile tile = (CTile)entry.Key;
                UpdateLevelMaterial(tile);
                UpdateLevelGameplay(tile);
            }

            // Clear changeset
            changeset.Clear();
        }
    }
Exemplo n.º 7
0
    // -----------------------------------------------------------------------------------------------------------------
    private void BuildTiles()
    {
        Texture2D heightmap = m_config.heightmap;
        float     tile_gap  = m_config.tile_gap_size;
        float     tile_unit = m_config.tile_unit_size;
        float     tw        = m_config.tile_mesh.GetBounds().x;
        float     th        = m_config.tile_mesh.GetBounds().z;

        // Tile width
        m_tile_width    = tw + tile_gap;
        m_tile_width_50 = m_tile_width * 0.5f;

        // Tile height
        m_tile_height    = th + tile_gap;
        m_tile_height_75 = m_tile_height * 0.75f;
        m_tile_height_50 = m_tile_height * 0.5f;
        m_tile_height_25 = m_tile_height * 0.25f;

        // Level size
        m_width  = heightmap.width;
        m_height = heightmap.height;

        utils.Log("Tile :: width={0:F2} height={1:F2} gap={2:F2} unit={3:F2}", tw, th, tile_gap, tile_unit);
        utils.Log("Map :: width={0} height={1}", heightmap.width, heightmap.height);

        // Init tags
        m_tag_owner = new CTag.COwner((int)CTile.ETag.T_MAX);
        m_tag_owner.InitTag((int)CTile.ETag.T_CURRENT, "current", 1, CTag.ELimitPolicy.LP_QUEUE);
        m_tag_owner.InitTag((int)CTile.ETag.T_VISITED, "visited", 10, CTag.ELimitPolicy.LP_QUEUE);
        m_tag_owner.InitTag((int)CTile.ETag.T_DEST_PATH, "dest-path", 25, CTag.ELimitPolicy.LP_DENY);
        m_tag_owner.InitTag((int)CTile.ETag.T_DEFAULT, "default");
        m_tag_owner.InitTag((int)CTile.ETag.T_APPLE, "apple");
        m_tag_owner.InitTag((int)CTile.ETag.T_BORDER, "border");
        m_tag_owner.InitTag((int)CTile.ETag.T_TAIL, "tail");

        // Build tiles
        m_tiles = new CTile[m_width, m_height];
        for (int z = 0; z < m_height; z++)
        {
            for (int x = 0; x < m_width; x++)
            {
                CreateTile(x, z, heightmap);
            }
        }

        // Link together neightbor tiles
        for (int z = 0; z < m_height; z++)
        {
            for (int x = 0; x < m_width; x++)
            {
                CTile t = m_tiles[x, z];
                for (int idx = (int)CTile.EDirection.DIR_1; idx < (int)CTile.EDirection.DIR_MAX; idx++)
                {
                    CTile.EDirection dir = (CTile.EDirection)idx;
                    t.SetNeighbor(dir, GetTileByOffset(t, dir, 1));
                }
            }
        }

        // Create vertical border
        for (int z = 0; z < m_height; z++)
        {
            m_tag_owner.SetTag(m_tiles[0, z], (int)CTile.ETag.T_BORDER);
            m_tag_owner.SetTag(m_tiles[m_width - 1, z], (int)CTile.ETag.T_BORDER);
        }

        // Create horizontal border
        for (int x = 0; x < m_height; x++)
        {
            m_tag_owner.SetTag(m_tiles[x, 0], (int)CTile.ETag.T_BORDER);
            m_tag_owner.SetTag(m_tiles[x, m_height - 1], (int)CTile.ETag.T_BORDER);
        }
    }
Exemplo n.º 8
0
    // -----------------------------------------------------------------------------------------------------------------
    public CTile.ERelPosition GetRelPosition(CTile target, CTile.EDirection dir)
    {
        // Easy case - target is reached
        CTile.ERelPosition rel_pos = CTile.ERelPosition.RP_NONE;
        if (target == this)
        {
            rel_pos = CTile.ERelPosition.RP_CURRENT;

            // Medium case - horizontal/vertical
        }
        else if (dir == CTile.EDirection.DIR_3)              // 3: right
        {
            if (target.m_idx.y == m_idx.y)
            {
                rel_pos = (target.m_idx.x > m_idx.x) ?
                          CTile.ERelPosition.RP_FORWARD :
                          CTile.ERelPosition.RP_BEHIND;
            }
        }
        else if (dir == CTile.EDirection.DIR_9)              // 9: left
        {
            if (target.m_idx.y == m_idx.y)
            {
                rel_pos = (target.m_idx.x < m_idx.x) ?
                          CTile.ERelPosition.RP_FORWARD :
                          CTile.ERelPosition.RP_BEHIND;
            }

            // Hard case - diagonal
        }
        else
        {
            // Diff to destination
            int z_diff = target.m_idx.y - m_idx.y;
            int x_diff = target.m_idx.x - m_idx.x;

            // Initial relative position is set to behind and offset is set to negative
            int offset = (z_diff < 0) ? z_diff : -z_diff;
            rel_pos = CTile.ERelPosition.RP_BEHIND;

            // Update relative position
            if (dir == CTile.EDirection.DIR_1)                // 1: right - up
            {
                if (x_diff >= 0 && z_diff > 0)
                {
                    rel_pos = CTile.ERelPosition.RP_FORWARD;
                }
            }
            else if (dir == CTile.EDirection.DIR_5)          // 5: right - down
            {
                if (x_diff >= 0 && z_diff < 0)
                {
                    rel_pos = CTile.ERelPosition.RP_FORWARD;
                }
            }
            else if (dir == CTile.EDirection.DIR_7)          // 7: left - down
            {
                if (x_diff <= 0 && z_diff < 0)
                {
                    rel_pos = CTile.ERelPosition.RP_FORWARD;
                }
            }
            else if (dir == CTile.EDirection.DIR_11)         // 11: left - up
            {
                if (x_diff <= 0 && z_diff > 0)
                {
                    rel_pos = CTile.ERelPosition.RP_FORWARD;
                }
            }
            else
            {
                utils.Assert(true, "Invalid diff");             // ???: should not happen
            }

            // If relative position was changed then offset should be inverted
            if (rel_pos == CTile.ERelPosition.RP_FORWARD)
            {
                offset = -offset;
            }

            // Find coordinates of correct tile with given offset
            int x = 0, z = 0;
            GetTilePosXZByOffset(dir, offset, ref x, ref z);

            // If correct tile is not our target tile then ignore
            if (x != target.m_idx.x || z != target.m_idx.y)
            {
                rel_pos = CTile.ERelPosition.RP_NONE;
            }
        }
        return(rel_pos);
    }