// ----------------------------------------------------------------------------------------------------------------- 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(); } }
// ----------------------------------------------------------------------------------------------------------------- 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); }