private bool HandleCollision(Bomb other) { bool moving1 = IsMoving(); bool moving2 = other.IsMoving(); Debug.Assert(moving1 || moving2); if (moving1 && moving2) { if (direction == Util.Opposite(other.direction)) // moving in opposite directions { bool backBlocked1 = HasJellyBlockingObstacle(Util.Opposite(direction)); bool backBlocked2 = other.HasJellyBlockingObstacle(Util.Opposite(other.direction)); bool cell2cell = CheckCell2CellCollision(other); bool bounds2cell = CheckBounds2CellCollision(other); bool cell2bounds = CheckCell2BoundsCollision(other); bool bounds2bounds = CheckBounds2BoundsCollision(other); if (backBlocked1 && backBlocked2) { if (cell2cell) { switch (direction) { case Direction.LEFT: case Direction.RIGHT: { float shift = 0.5f * OverlapX(other); MoveBackX(shift); other.MoveBackX(shift); break; } case Direction.UP: case Direction.DOWN: { float shift = 0.5f * OverlapY(other); MoveBackY(shift); other.MoveBackY(shift); break; } } } } else if (backBlocked1) { if (bounds2cell) { HandleObstacleCollistion(other); if (bounds2bounds) { other.HandleObstacleCollistion(this); } return(true); } } else if (backBlocked2) { if (cell2bounds) { other.HandleObstacleCollistion(this); if (bounds2bounds) { HandleObstacleCollistion(other); } return(true); } } else { if (!bounds2bounds) { return(false); } } HandleObstacleCollistion(other); other.HandleObstacleCollistion(this); return(true); } else if (direction == other.direction) { if (IsMovingTowards(other)) { HandleObstacleCollistion(other); return(true); } other.HandleObstacleCollistion(this); return(true); } else // perpendicular directions { if (CheckBounds2CellCollision(other)) { if (IsMovingTowards(other)) { HandleObstacleCollistion(other); return(true); } } else if (other.CheckBounds2CellCollision(this)) { if (other.IsMovingTowards(this)) { other.HandleObstacleCollistion(this); return(true); } } if (CheckBounds2BoundsCollision(this)) { if (IsMovingTowards(other)) { HandleObstacleCollistion(other); return(true); } if (other.IsMovingTowards(this)) { other.HandleObstacleCollistion(this); return(true); } } } return(false); } if (moving1) { if (IsMovingTowards(other)) { return(HandleObstacleCollistion(other)); } return(false); } if (moving2) { if (other.IsMovingTowards(this)) { return(other.HandleObstacleCollistion(this)); } return(false); } return(false); }
private bool HandleCollision(Bomb other) { bool moving1 = IsMoving(); bool moving2 = other.IsMoving(); Debug.Assert(moving1 || moving2); if (moving1 && moving2) { if (direction == Util.Opposite(other.direction)) // moving in opposite directions { bool backBlocked1 = HasJellyBlockingObstacle(Util.Opposite(direction)); bool backBlocked2 = other.HasJellyBlockingObstacle(Util.Opposite(other.direction)); bool cell2cell = CheckCell2CellCollision(other); bool bounds2cell = CheckBounds2CellCollision(other); bool cell2bounds = CheckCell2BoundsCollision(other); bool bounds2bounds = CheckBounds2BoundsCollision(other); if (backBlocked1 && backBlocked2) { if (cell2cell) { switch (direction) { case Direction.LEFT: case Direction.RIGHT: { float shift = 0.5f * OverlapX(other); MoveBackX(shift); other.MoveBackX(shift); break; } case Direction.UP: case Direction.DOWN: { float shift = 0.5f * OverlapY(other); MoveBackY(shift); other.MoveBackY(shift); break; } } } } else if (backBlocked1) { if (bounds2cell) { HandleObstacleCollistion(other); if (bounds2bounds) { other.HandleObstacleCollistion(this); } return true; } } else if (backBlocked2) { if (cell2bounds) { other.HandleObstacleCollistion(this); if (bounds2bounds) { HandleObstacleCollistion(other); } return true; } } else { if (!bounds2bounds) { return false; } } HandleObstacleCollistion(other); other.HandleObstacleCollistion(this); return true; } else if (direction == other.direction) { if (IsMovingTowards(other)) { HandleObstacleCollistion(other); return true; } other.HandleObstacleCollistion(this); return true; } else // perpendicular directions { if (CheckBounds2CellCollision(other)) { if (IsMovingTowards(other)) { HandleObstacleCollistion(other); return true; } } else if (other.CheckBounds2CellCollision(this)) { if (other.IsMovingTowards(this)) { other.HandleObstacleCollistion(this); return true; } } if (CheckBounds2BoundsCollision(this)) { if (IsMovingTowards(other)) { HandleObstacleCollistion(other); return true; } if (other.IsMovingTowards(this)) { other.HandleObstacleCollistion(this); return true; } } } return false; } if (moving1) { if (IsMovingTowards(other)) { return HandleObstacleCollistion(other); } return false; } if (moving2) { if (other.IsMovingTowards(this)) { return other.HandleObstacleCollistion(this); } return false; } return false; }
internal bool HandleCollision(Bomb bomb) { if (IsMoving()) { if (bomb.IsMoving()) { return HandlePlayerMovingBombMovingCollision(bomb); } return HandlePlayerMovingBombStillCollision(bomb); } if (bomb.IsMoving()) { return HandlePlayerStillBombMovingCollision(bomb); } return HandlePlayerStillBombStillCollision(bomb); }
/* Player is still, bomb is still */ private bool HandlePlayerStillBombStillCollision(Bomb bomb) { Debug.Assert(!IsMoving()); Debug.Assert(!bomb.IsMoving()); return false; }
/* Player is still, bomb is moving */ private bool HandlePlayerStillBombMovingCollision(Bomb bomb) { Debug.Assert(!IsMoving()); Debug.Assert(bomb.IsMoving()); if (CheckCell2BoundsCollision(bomb)) // player`s cell should collide bomb`s bounds { if (bomb.IsMovingTowards(this)) // bomb is moving towards the player { bomb.HandleObstacleCollistion(this); return true; } } return false; }
/* Player is moving, bomb is still */ private bool HandlePlayerMovingBombStillCollision(Bomb bomb) { Debug.Assert(IsMoving()); Debug.Assert(!bomb.IsMoving()); if (CheckCell2CellCollision(bomb)) // player and bomb share the cell { return false; } if (CheckBounds2CellCollision(bomb)) // player bounds collide bomb`s cell { if (IsMovingTowards(bomb)) // check if player is moving towards the bomb { if (HasKick()) { TryKick(bomb); } else { MoveOutOfCell(bomb); } return true; } } return false; }
/* Player is moving, bomb is moving */ private bool HandlePlayerMovingBombMovingCollision(Bomb bomb) { Debug.Assert(IsMoving()); Debug.Assert(bomb.IsMoving()); bool hasKick = HasKick(); if (direction == Util.Opposite(bomb.direction)) // moving in opposite directions { if (IsMovingTowards(bomb)) { if (CheckCell2BoundsCollision(bomb) || CheckBounds2CellCollision(bomb)) { if (hasKick) { // move bomb out of player`s cell bomb.MoveOutOfCell(this); // kick in the moving direction TryKick(bomb); return true; } // treat player as an obstacle bomb.HandleObstacleCollistion(this); // make sure player is out of bomb`s cell MoveOutOfCell(bomb); return true; } } } else if (direction == bomb.direction) // moving in the same direction { if (bomb.IsMovingTowards(this)) // bomb`s following player? { if (bomb.CheckBounds2CellCollision(this)) // bomb bounds should collide player`s cell { // treat player as an obstacle bomb.HandleObstacleCollistion(this); return true; } } else if (IsMovingTowards(bomb)) // player`s following bomb { if (CheckCell2BoundsCollision(bomb) || CheckBounds2CellCollision(bomb)) { if (hasKick) { // kick in the moving direction TryKick(bomb); return true; } // make sure player is out of bomb`s cell MoveOutOfCell(bomb); return true; } } } else // player and bomb move in perpendicular directions { if (CheckCell2CellCollision(bomb)) { return false; } if (CheckBounds2CellCollision(bomb) && CheckBounds2BoundsCollision(bomb)) { if (IsMovingTowards(bomb)) { if (hasKick) { TryKick(bomb); } MoveOutOfCell(bomb); return true; } } if (bomb.CheckBounds2BoundsCollision(this)) { if (bomb.IsMovingTowards(this)) { bomb.HandleObstacleCollistion(this); return true; } } } return false; }