// Update is called once per frame void Update() { if (GameProperties.isSinglePlayer || networkView.isMine) { // make game frame rate independent int maxSpeed = ((int)(1000 * Time.deltaTime * Data.Data.maxSpeed )); BoardLocation startPos = Data.Data.boardLocation.Clone(); /**IntVector2 newDirection = new IntVector2( 0, 0 ); // compute the attempted direction if ( Input.GetKey( KeyCode.LeftArrow ) ) newDirection = new IntVector2( newDirection.x -1, newDirection.y ); else if ( Input.GetKey( KeyCode.RightArrow ) ) newDirection = new IntVector2( newDirection.x + 1, newDirection.y ); else if ( Input.GetKey( KeyCode.DownArrow ) ) newDirection = new IntVector2( newDirection.x, newDirection.y - 1); else if ( Input.GetKey( KeyCode.UpArrow ) ) newDirection = new IntVector2( newDirection.x, newDirection.y + 1 );*/ IntVector2 newDirection = new IntVector2(direction.x, direction.y); if ( newDirection.x + newDirection.y != 0 ) { // decide if attempted direction is a valid one based on whether or not it would effect mr // pacman were it executed newDirection.Normalize( ); newDirection *= maxSpeed; BoardLocation posAfter = Board.tryMove( startPos, newDirection ); if ( BoardLocation.SqrDistance( posAfter, startPos ) > 0 ) { // valid velocity change. Data.Data.direction = newDirection; } } Data.Data.direction.Normalize( ); Data.Data.direction *= maxSpeed; Data.Data.boardLocation = Board.tryMove( Data.Data.boardLocation, Data.Data.direction ); } }
public IntVector2 moveTowardsBFS( BoardObject boardObjectData, HashSet<IntVector2> targets, int maxSpeed, out int distance, bool canReverse ) { BoardLocation pos = boardObjectData.boardLocation.Clone(); // get grid positions IntVector2 thisPos = pos.location; HashSet<IntVector2> visited = new HashSet<IntVector2>(); Dictionary<IntVector2, IntVector2> previous = new Dictionary<IntVector2, IntVector2>(); LinkedList<IntVector2> queue = new LinkedList<IntVector2>(); queue.AddLast( thisPos ); IntVector2 reverseDir = boardObjectData.direction.Normalized(); reverseDir = reverseDir * -1; IntVector2 closestReachable = null; int closestDistance = int.MaxValue; while ( queue.Count > 0 ) { IntVector2 p = queue.First.Value; queue.RemoveFirst(); foreach ( IntVector2 target in targets ) { if ( IntVector2.OrthogonalDistance( p, target ) < closestDistance ) { closestReachable = p.Clone(); closestDistance = IntVector2.OrthogonalDistance( p, target ); } } // found a destination if ( targets.Contains( p ) ) break; foreach ( IntVector2 dir in Constants.directions ) { if ( !canReverse && p.Equals( pos.location ) && dir.Equals( reverseDir ) ) { // not allowed continue; } IntVector2 posToVisit = dir + p; if ( !isOpen( posToVisit ) ) continue; if ( visited.Contains( posToVisit ) ) continue; visited.Add( posToVisit ); previous[posToVisit] = p; queue.AddLast( posToVisit ); } } LinkedList<IntVector2> path = new LinkedList<IntVector2>(); IntVector2 curr = closestReachable; try { while ( !curr.Equals( thisPos ) && previous.ContainsKey( curr ) ) { path.AddFirst( curr ); curr = previous[curr]; } } catch ( KeyNotFoundException e ) { int x = 0; x++; } distance = path.Count; // there is a path and its length is not 0 if ( path.Count > 0 ) { // head in the direction of first IntVector2 direction = new IntVector2( path.First.Value.x, path.First.Value.y ) - new IntVector2( thisPos.x, thisPos.y ); direction.Normalize(); direction *= maxSpeed; // direction will be orthogonal BoardLocation afterMove = tryMove( pos, direction ); if ( BoardLocation.SqrDistance( afterMove, pos ) > maxSpeed * maxSpeed / 4 ) { // move there return direction; } } //otherwise, we are at our target. Any move will suffice distance = int.MaxValue; return new IntVector2(0, 0); }