void FindPacManAsInky() { WalkableTile futurePos = null; for (int i = 2; i >= 0; i--) { var key = Utils.TilePosToKey(StageController.instance.pacMan.tile + StageController.instance.pacMan.dirVector * i); if (StageController.instance.walkableTiles.ContainsKey(key) && StageController.instance.walkableTiles[key].IsGhostBase == false) { futurePos = StageController.instance.walkableTiles[key]; break; } } var diff = futurePos.pos - StageController.instance.ghosts[0].tile.pos; var targetTile = StageController.instance.FindClosestWalkableTile(futurePos.pos + diff * 2); if (targetTile == null) { Debug.LogWarning("No target tile found"); FallBackMovement(); return; } Debug.DrawLine(transform.parent.TransformPoint((Vector2)tile.pos), transform.parent.TransformPoint((Vector2)targetTile.pos), Color.cyan, 0.25f); var result = Pathfinder.GetPathAstar(tile, targetTile, (dismissDirection) ? Vector2Int.zero : dirVector); dismissDirection = false; TreatPathFindResult(result); }
void SetPinky() { tile = spawnTile = StageController.instance.walkableTiles[Utils.TilePosToKey(new Vector2Int(16, 16))]; direction = Direction.down; cornerTile = StageController.instance.walkableTiles[Utils.TilePosToKey(new Vector2Int(3, 29))]; }
//------------------------------------------------------------------------------------------------------------------/ void Awake() { foreach (var pos in tilemap.cellBounds.allPositionsWithin) { var localPosition = new Vector3Int(pos.x, pos.y, pos.z); var flatPosition = new Vector2Int(localPosition.x, localPosition.y); if (tilemap.HasTile(localPosition)) { var tile = tilemap.GetTile(localPosition); if (tile.name == string.Empty) { continue; } var prefix = tile.name.Substring(0, 2).ToUpper(); TileBase implementation = default; switch (prefix) { case "WK": implementation = new WalkableTile(flatPosition, 0); break; } tiles.Add(flatPosition, implementation); } } }
void SetClyde() { tile = spawnTile = StageController.instance.walkableTiles[Utils.TilePosToKey(new Vector2Int(18, 16))]; direction = Direction.up; cornerTile = StageController.instance.walkableTiles[Utils.TilePosToKey(new Vector2Int(3, 1))]; }
void TreatPathFindResult(List <WalkableTile> result) { if (result == null || result.Count == 0) { Debug.LogWarning("no result found!"); FallBackMovement(); return; } if (result.Count == 1) { Debug.LogWarning("Same tile!"); FallBackMovement(); return; } Direction newDir; if (tile.FindTileInConn(result[1], out newDir)) { tileTarget = result[1]; Direction = newDir; } else { Debug.LogWarning("Conn Invalid!"); FallBackMovement(); } }
void FallBackMovement() { Debug.Log("FallBackMovement"); Direction newDir; tileTarget = tile.NextInDirection(direction, out newDir); Direction = newDir; }
void SetBlinky() { tile = StageController.instance.walkableTiles[Utils.TilePosToKey(new Vector2Int(16, 19))]; Direction = Direction.left; spawnTile = StageController.instance.walkableTiles[Utils.TilePosToKey(new Vector2Int(16, 16))]; cornerTile = StageController.instance.walkableTiles[Utils.TilePosToKey(new Vector2Int(28, 29))]; }
void MoveUpAndDown() { tileTarget = tile.conns[Utils.ConnIndexByDir(Direction)]; if (tileTarget != null && tileTarget.type == TileType.GhostArea) { return; } Direction = Utils.InverseDirection(Direction); tileTarget = tile.conns[Utils.ConnIndexByDir(Direction)]; }
public static List <WalkableTile> GetPathAstar(WalkableTile start, WalkableTile end, Vector2Int dir, bool isGhostEaten = false) { enableGhostArea = isGhostEaten; var result = AstarSearch(start, end.pos, dir); if (result == null) { return(null); } return(BuildPath(result)); }
internal bool FindTileInConn(WalkableTile tile, out Direction dir) { for (int i = 0; i < conns.Length; i++) { if (conns[i] == tile) { dir = Utils.DirectionByConnIndex(i); return(true); } } dir = Direction.up; return(false); }
public void SetPathNode(WalkableTile parent, Vector2Int target) { this.parent = parent; if (parent != null) { dir = pos - parent.pos; G = parent.G + 1; } H = Mathf.RoundToInt(Vector2.Distance(pos, target)); //var temp = tile.pos - target; //H = Mathf.Abs(temp.x) + Mathf.Abs(temp.y); F = G + H; }
void FindExit() { var result = Pathfinder.GetPathAstar(tile, StageController.instance.ghostAreaExit, Vector2Int.zero, true); if (result != null && result.Count < 2) { inBetwen = 0.5f; tileTarget = tile.conns[Utils.ConnIndexByDir(Direction.left)]; ChangeToStageMoment(true); } else { TreatPathFindResult(result); } }
private static WalkableTile AstarSearch(WalkableTile start, Vector2Int endPos, Vector2Int startDir) { start.SetPathNode(null, endPos); start.dir = startDir; var openSet = new List <WalkableTile>(); var closeSet = new List <WalkableTile>();//TODO REMOVE? maxLoops = 0; openSet.Add(start); while (openSet.Count > 0 && maxLoops < SEARCH_LIMIT) { maxLoops++; var tile = openSet[0]; openSet.RemoveAt(0); closeSet.Add(tile); if (tile.pos == endPos)//Found! { #if PATHFIND_LOG Debug.LogWarning("TILE FOUND " + maxLoops); #endif return(tile); } int i = tile.IsUpLocked ? 1 : 0;//Skip Up node for (; i < tile.conns.Length; i++) { if (tile.conns[i] != null && (enableGhostArea == true || tile.conns[i].IsGhostBase == false) && tile.pos != tile.conns[i].pos + tile.dir && closeSet.Contains(tile.conns[i]) == false && openSet.Contains(tile.conns[i]) == false) { tile.conns[i].SetPathNode(tile, endPos); openSet.Add(tile.conns[i]); } } openSet = openSet.OrderBy(n => n.F).ToList(); } if (maxLoops == SEARCH_LIMIT) { Debug.LogWarning("Limit reached!"); } else { Debug.LogWarning("Not found!"); } return(null); }
void OnTileReached() { tile = tileTarget; inBetwen -= 1; //Wrap if (tile.type == TileType.Wrap) { tile = tile.conns[Utils.ConnIndexByDir(direction)]; } if (dismissDirection == false && tile.connType != ConnType.Multi && Status != GhostState.InHouse) { Direction newDir; tileTarget = tile.NextInDirection(direction, out newDir); Direction = newDir; return; } if (Status == GhostState.Chasing) { ChasePacMan(); } else if (Status == GhostState.Frightened) { AvoidPacMan(); } else if (Status == GhostState.Eaten) { FindSpawn(); } else if (Status == GhostState.Exiting) { FindExit(); } else if (Status == GhostState.InHouse) { MoveUpAndDown(); } else { FindCorner(); } }
// Update is called once per frame private void Update() { if (!AllowTurnInteraction()) { return; } //Check that we have a valid touch if (!TouchInput.TouchIsValid(TouchDefines.movementTouchID)) { return; } //Get touch Touch moveTouch = Input.GetTouch(TouchDefines.movementTouchID); //Only move once the touch has ended if (moveTouch.phase != TouchPhase.Ended) { return; } //Get the direction that the touch has moved Vector2 swipeDirection = TouchInput.GetMainSwipeDirection(moveTouch); Vector3 moveDirection = new Vector3(swipeDirection.x, 0, swipeDirection.y); //Check if where we want to move to has a tile that we can go to RaycastHit rayhit; if (Physics.Raycast(transform.position, moveDirection, out rayhit, GameStateManager.tileMoveAmount)) { //Get if we have hit a tile the move to that tiles center WalkableTile hitTile = rayhit.collider.gameObject.GetComponent <WalkableTile>(); if (hitTile) { //Rotate and move to tile gameObject.transform.LookAt(hitTile.transform); StartCoroutine(MoveOverTime(hitTile.transform.position, turnDuration)); //End the turn after time StartCoroutine(EndTurnAfterTime(GameStateManager.GameTurn.TURN_PLAYER, turnDuration)); } } }
private static List <WalkableTile> BuildPath(WalkableTile tile) { var shortPath = new List <WalkableTile>(); maxLoops = 0; while (tile != null && maxLoops < SEARCH_LIMIT) { maxLoops++; shortPath.Insert(0, tile); tile = tile.parent; } #if PATHFIND_LOG Debug.LogWarning("PATH SIZE " + shortPath.Count); #endif return(shortPath); //shortPath.Reverse(); }
void AvoidPacMan() { var pacManTile = StageController.instance.walkableTiles[Utils.TilePosToKey(StageController.instance.pacMan.tile)]; var result = Pathfinder.GetPathAstar(tile, pacManTile, (dismissDirection) ? Vector2Int.zero : dirVector); dismissDirection = false; if (result == null || result.Count == 0) { Debug.LogWarning("no result found!"); FallBackMovement(); return; } if (result.Count == 1) { Debug.LogWarning("Same tile!"); FallBackMovement(); return; } var inverDirInd = Utils.ConnIndexByDir(Utils.InverseDirection(Direction)); Direction newDir; if (tile.FindTileInConn(result[1], out newDir)) { var pacManDirInd = Utils.ConnIndexByDir(newDir); for (int i = 0; i < tile.conns.Length; i++) { if (i != inverDirInd && i != pacManDirInd && tile.conns[i] != null && tile.conns[i].IsGhostBase == false) { tileTarget = tile.conns[i]; Direction = Utils.DirectionByConnIndex(i); return; } } } else { Debug.LogWarning("Conn Invalid!"); FallBackMovement(); } }
void CreateTile(Vector2Int tile, TileType id) { if (id == TileType.Wall) { return; } GameObject prefab = null; GameObject go = null; if (id == TileType.Pellet || id == TileType.Wrap) { prefab = prefabPellet; } if (id == TileType.Powerup) { prefab = prefabPowerUp; } if (prefab != null) { go = GameObject.Instantiate(prefab, pelletsContainer); go.transform.localPosition = (Vector2)tile; #if UNITY_EDITOR go.name = TileType.Pellet.ToString() + tile.ToString(); #endif } var wTile = new WalkableTile(tile, id, go); if (id == TileType.Tunnel || id == TileType.Wrap) { wTile.IsTunnel = true; } if ((tile.x == 14 || tile.x == 17) && (tile.y == 7 || tile.y == 19)) { wTile.IsUpLocked = true; } walkableTiles.Add(Utils.TilePosToKey(tile), wTile); }
void FindPacManAsPinky() { WalkableTile futurePos = null; for (int i = 4; i >= 0; i--) { var key = Utils.TilePosToKey(StageController.instance.pacMan.tile + StageController.instance.pacMan.dirVector * i); if (StageController.instance.walkableTiles.ContainsKey(key) && StageController.instance.walkableTiles[key].IsGhostBase == false) { futurePos = StageController.instance.walkableTiles[key]; break; } } Debug.DrawLine(transform.parent.TransformPoint((Vector2)tile.pos), transform.parent.TransformPoint((Vector2)futurePos.pos), Color.magenta, 0.25f); var result = Pathfinder.GetPathAstar(tile, futurePos, (dismissDirection) ? Vector2Int.zero : dirVector); dismissDirection = false; TreatPathFindResult(result); }
private static WalkableTile[,] initializeWalkable(GameMap map) { WalkableTile[,] walkables = new WalkableTile[map.getWidth(), map.getHeight()]; foreach (Room room in map.getRooms()) { foreach (Position wallPos in room.getWallPositions()) { walkables[wallPos.getX(), wallPos.getY()] = new WalkableTile(WalkableTile.Wall); } foreach (Position floorPos in room.getFloorPositions()) { walkables[floorPos.getX(), floorPos.getY()] = new WalkableTile(WalkableTile.Floor); } } foreach (Hallway hall in map.getHallways()) { foreach (Position wallPos in hall.getWallPositions()) { walkables[wallPos.getX(), wallPos.getY()] = new WalkableTile(WalkableTile.Wall); } foreach (Position floorPos in hall.getPath()) { walkables[floorPos.getX(), floorPos.getY()] = new WalkableTile(WalkableTile.Floor); } } for (int x = 0; x < walkables.GetLength(0); x++) { for (int y = 0; y < walkables.GetLength(1); y++) { if (walkables[x, y] != null) { continue; } walkables[x, y] = new WalkableTile(WalkableTile.Nothing); } } return(walkables); }
internal void SetReady() { Status = GhostState.Waiting; Show(); switch (type) { case GhostType.Blinky: SetBlinky(); break; case GhostType.Pinky: SetPinky(); break; case GhostType.Inky: SetInky(); break; case GhostType.Clyde: SetClyde(); break; } inBetwen = 0.5f; Direction newDir; tileTarget = tile.NextInDirection(direction, out newDir); PositionUpdate(); spriteRenderer.sprite = movementsSprites[2]; }
/// <summary> /// Work out the new state for the AI to be in /// </summary> /// <returns>New State</returns> private void UpdateAI(GameStateManager.GameTurn newTurn) { //If it is not our turn then return if (newTurn != GameStateManager.GameTurn.TURN_AI) { return; } //Null Check Player and early out if (!playerObject) { return; } //Get a new state, based on current conditions currentAIState = GetNewAIState(); //Set the prev target pos to the current pos, //so we can check if the target pos hasn't moved prevTargetPos = targetPos; switch (currentAIState) { case AI_STATE.AI_STATE_SEEK_TO_PLAYER: { //Set our target position to be the player targetPos = playerObject.transform.position; //Update the last known player position, set it to our y pos //as neither object moves in the y direction lastKnownPlayerPos = new Vector3(targetPos.x, transform.position.y, targetPos.z); break; } case AI_STATE.AI_STATE_SEEK_TO_LAST_POS: { //Set the target pos to the players //last know position targetPos = lastKnownPlayerPos; break; } case AI_STATE.AI_STATE_WANDER: { //Find a point on the map that we should //go to, then set it as our target pos targetPos = GetWanderTargetPos(); break; } } //If the target pos is not the same as the previous //and it is not the current pos //target pos find a route to the target if (targetPos != prevTargetPos && targetPos != transform.position) { lastPathfindResults = pathfinder.GetAStarPath(transform.position, targetPos); } //Check that we have a path to follow if (lastPathfindResults.Count > 0) { //Get the next pos from the list and keep our y the same //because the grid is flat to the x/z plane Vector3 nextPos = lastPathfindResults[0].transform.position; nextPos.y = transform.position.y; //Rotate and move towards next position transform.LookAt(nextPos); //Check that the tile at the next pos is not occupied by the player WalkableTile nextTile = lastPathfindResults[0].GetComponentInChildren <WalkableTile>(); if (nextTile) { if (!nextTile.IsOccupied || nextTile.Occupier.GetComponent <PlayerMovement>()) { //Attempt to reserve the space and only move if we do this succcessfully if (nextTile.AttemptToReserve(this.gameObject)) { StartCoroutine(MoveOverTime(nextPos, turnDuration)); } } } //Remove the pos from the list so we don't //visit it again lastPathfindResults.RemoveAt(0); } //Debug Test for State Debug.Log("FOX :: " + currentAIState.ToString()); //End the turn after turn timer is up - call event StartCoroutine(EndTurnAfterTime(GameStateManager.GameTurn.TURN_AI, turnDuration)); }
void ConnectTiles() { int key; bool gambi = false; foreach (var tile in walkableTiles) { key = Utils.TilePosToKey(tile.Value.pos + Utils.VectorByDir(Direction.up)); if (walkableTiles.ContainsKey(key)) { tile.Value.conns[DirectionInt.UP] = walkableTiles[key]; } key = Utils.TilePosToKey(tile.Value.pos + Utils.VectorByDir(Direction.down)); if (walkableTiles.ContainsKey(key)) { tile.Value.conns[DirectionInt.DONW] = walkableTiles[key]; } key = Utils.TilePosToKey(tile.Value.pos + Utils.VectorByDir(Direction.left)); if (walkableTiles.ContainsKey(key)) { tile.Value.conns[DirectionInt.LEFT] = walkableTiles[key]; } key = Utils.TilePosToKey(tile.Value.pos + Utils.VectorByDir(Direction.right)); if (walkableTiles.ContainsKey(key)) { tile.Value.conns[DirectionInt.RIGHT] = walkableTiles[key]; } if (tile.Value.type == TileType.GhostGate) { if (gambi == true) { ghostAreaExit = tile.Value.conns[0]; continue; } for (int i = 0; i < tile.Value.conns.Length; i++) { tile.Value.conns[i] = null; } gambi = true; } } var wrapTiles = new List <WalkableTile>(); foreach (var tile in walkableTiles) { tile.Value.UpdateConnType(); if (tile.Value.type == TileType.Wrap) { wrapTiles.Add(tile.Value); } } //TODO turn it to a generic wrapTiles[0].conns[Utils.ConnIndexByDir(Direction.left)] = wrapTiles[1]; wrapTiles[1].conns[Utils.ConnIndexByDir(Direction.right)] = wrapTiles[0]; }