/// <summary> /// Whether or not this object should collide with another object. /// </summary> /// <param name="other">The other object to check for a collision /// against.</param> /// <param name="region">The region of collision. An empty bounding box /// if the objects do not collide.</param> /// <returns>True if the objects should collide, false otherwise.</returns> internal bool ShouldCollide(GameObject other, out BBox region) { region = BBox.Intersect(other.BBox); return !region.IsEmpty(); }
/** * Handle collision events. **/ public override void Collide(GameObject other, BBox region) { if (!HasCollided && (!other.Equals(owner))) { OnCollision(); /**base.Collide(other, region);**/ } }
/// <summary> /// Resolves the collision in a region between this object /// and another. /// </summary> /// <param name="other">The other object being collided with.</param> /// <param name="region">The region of collision.</param> public virtual void Collide(GameObject other, BBox region) { }
public BoomStick(GameObject owner, Vector2 position, Vector2 initialVelocity, Texture2D Texture) : base(owner, position, new Vector2(ORIGIN_X, ORIGIN_Y), // Origin initialVelocity, new Vector2(MAX_SPEED_X, MAX_SPEED_Y), new Vector2(ACCELERATION_X, ACCELERATION_Y), new Vector2(ACCELERATION_X, ACCELERATION_Y), Texture, DIR + ONFIREXML, DIR + INFLIGHTXML, DIR + ONCOLLISIONXML, ROTATION, ROTATION_SPEED, 1.0, PARTICLE_SCALING ) { OnFire(); }
/// <summary> /// Creates a new projectile. /// </summary> /// <param name="owner">The object that fired the projectile.</param> /// <param name="position">The initial position of the projectile.</param> /// <param name="origin">The origin point of the projectile.</param> /// <param name="initialVelocity">The initial velocity of the projectile.</param> /// <param name="maxSpeed">The maximum speed of the projectile.</param> /// <param name="acceleration">The acceleration of the projectile.</param> /// <param name="deceleration">The deccceleration of the projectile.</param> /// <param name="texture">The texture of the projectile.</param> /// <param name="OnFireFX_XML">The relative path to the XML file from which the /// effects for firing a projectile are loaded.</param> /// <param name="InFlightFX_XML">The relative path to the XML file from which the /// effects used for an in-flight particle are loaded.</param> /// <param name="OnCollisionFX_XML">The relative path to the XML file from which the /// effects used for a projectile that has collided with a surface are loaded.</param> /// <param name="rotation">The initial rotation of the projectile.</param> /// <param name="rotationVelocity">The speed at which the projectile spins. /// Negative for counter-clockwise, positive for clockwise, 0 for no spinning.</param> /// <param name="particleLevel"></param> /// <param name="particleScaling"></param> public Projectile( GameObject owner, Vector2 position, Vector2 origin, Vector2 initialVelocity, Vector2 maxSpeed, Vector2 acceleration, Vector2 deceleration, Texture2D texture, String OnFireFX_XML, String InFlightFX_XML, String OnCollisionFX_XML, float rotation, //TODO: Create global default values for rotation, float rotationVelocity, // rotationSpeed and particleLevel (possible from GameObject constants) double particleLevel = 1.0, double particleScaling = 1.0) : base(position, origin, initialVelocity, maxSpeed, acceleration, deceleration, texture, rotation, rotationVelocity) { this.owner = owner; OnFireFXEmitter = new XNAEmitter(/**parent,**/ position, OnFireFX_XML, particleLevel, particleScaling); InFlightFXEmitter = new XNAEmitter(/**parent,**/ position, InFlightFX_XML, particleLevel, particleScaling); OnCollisionFXEmitter = new XNAEmitter(/**parent,**/ position, OnCollisionFX_XML, particleLevel, particleScaling); }
/// <summary> /// Get all the walls that intersect with the given object. /// </summary> /// <param name="obj">The object.</param> /// <returns>All the walls that collide with the object.</returns> public List<Tile> GetIntersectingWalls(GameObject obj) { List<Tile> intersects = new List<Tile>(); Vector2 tileCoords = GetTileCoordsByPixel(obj.BBox.Position); float colSpan = GetColSpan(obj); float rowSpan = GetRowSpan(obj); for (int x = (int)tileCoords.X; x <= tileCoords.X + rowSpan; x++) for (int y = (int)tileCoords.Y; y <= tileCoords.Y + colSpan; y++) if (WallAt(x, y)) intersects.Add(tiles[x, y]); return intersects; }
/// <summary> /// Adds the given object to the given room of the world. /// </summary> /// <param name="obj">The object to be put in the room.</param> /// <param name="room">The room for the object to be put in.</param> private void Add(GameObject obj, Room room) { room.Add(obj); }
/// <summary> /// Returns the nearest of the 8 directions in which /// the target lies. /// </summary> /// <param name="target">A gameobject to target</param> /// <returns></returns> internal Direction NearestDirToTarget(GameObject target) { float xDelta, yDelta; double theta, thetaHat; xDelta = BBox.Center.X - target.BBox.Center.X; yDelta = BBox.Center.Y - target.BBox.Center.Y; theta = Math.Atan2(yDelta, xDelta); thetaHat = Math.Round(theta / (Math.PI / 4)); return DirectionOperations.FromRadians(thetaHat * (Math.PI / 4),4); }
/// <summary> /// Hide from target: Attempts to put a wall /// between itself and target. If no wall available, /// runs to furthest corner. /// </summary> /// <param name="target"></param> internal void Hide(GameObject target, Room room) { }
/// <summary> /// Return whether or not the given object is out of bounds. /// </summary> /// <param name="obj">The object to check.</param> /// <param name="violationDirection">The direction in which the object is out of bounds, /// or Direction.None if the object is not out of bounds.</param> /// <returns>True if the object is out of bounds, false otherwise.</returns> public bool OutOfBounds(GameObject obj, out Direction violationDirection) { violationDirection = Direction.None; // get the direction in which the object is out of bounds, if any at all // priority: West > North > East > South if (obj.Position.X < 0) violationDirection = Direction.West; else if (obj.Position.Y < 0) violationDirection = Direction.North; else if (obj.Position.X + obj.BBox.Width >= GetWidthInPixels()) violationDirection = Direction.East; else if (obj.Position.Y + obj.BBox.Height >= GetHeightInPixels()) violationDirection = Direction.South; return violationDirection == Direction.None; }
/// <summary> /// Removes the given object from the room after the update has finished. /// Safer than Remove to call during an update. /// </summary> /// <param name="obj">The object to be removed.</param> public void RemoveAfterUpdate(GameObject obj) { removedObjects.Add(obj); }
/// <summary> /// Removes the given object from the room. /// </summary> /// <param name="obj">The object to be removed from the room.</param> public void Remove(GameObject obj) { objects.Remove(obj); }
/// <summary> /// Adds given object to the room after the update has finished. /// Safer than Add to call during an update. /// </summary> public void AddAfterUpdate(GameObject obj) { addedObjects.Add(obj); }
/// <summary> /// Adds the given object to the objects list. /// </summary> /// <param name="obj">The object to be put in the room.</param> public void Add(GameObject obj) { objects.Add(obj); }
/// <summary> /// Finds the nearest valid point in the current room /// from which enemy can fire at specified target, then /// return the direction its in. /// Firing occurs in the eight directions specified /// by the Direction class. /// </summary> /// <param name="target"></param> /// <param name="room"></param> internal void MoveToNearestFirePoint(GameObject target, GameTime gameTime, Room room) { float xDelta, yDelta, xyDelta; double theta; Vector2 moveVector; xDelta = BBox.Center.X - target.BBox.Center.X; yDelta = BBox.Center.Y - target.BBox.Center.Y; xyDelta = Math.Abs(xDelta) - Math.Abs(yDelta); if (xyDelta < Math.Abs(xDelta) && xyDelta < Math.Abs(yDelta)) { if (Math.Abs(xDelta) <= Math.Abs(yDelta)) { moveVector = new Vector2(0, -1 * yDelta / Math.Abs(yDelta)); } else { moveVector = new Vector2(-1 * xDelta / Math.Abs(xDelta), 0); } } else { if (Math.Abs(xDelta) <= Math.Abs(yDelta)) { moveVector = new Vector2(-1 * xDelta / Math.Abs(xDelta), 0); } else { moveVector = new Vector2(0, -1 * yDelta / Math.Abs(yDelta)); } } if (Velocity.X > Math.Abs(xDelta)) Velocity.X = Math.Abs(xDelta); else Velocity.X = MAX_VELOCITY_X; if (Velocity.Y > Math.Abs(xDelta)) Velocity.Y = Math.Abs(xDelta); else Velocity.Y = MAX_VELOCITY_Y; Move(DirectionOperations.FromVector(moveVector), gameTime, room); }
/// <summary> /// Returns the target's direction if directly within one of /// the 8 Directions. Returns Direction.None otherwise. /// </summary> /// <param name="target"></param> /// <param name="room"></param> /// <returns></returns> internal Direction IsOrthogonalDiagonal(GameObject target, Room room) { float xDelta, yDelta; double theta; xDelta = BBox.Center.X - target.BBox.Center.X; yDelta = BBox.Center.Y - target.BBox.Center.Y; theta = Math.Atan2(yDelta, xDelta); return DirectionOperations.FromRadians(theta, SHOOTING_PRECISION_DIGITS); }
/// <summary> /// Keeps the given object within the boundaries of the room. /// </summary> /// <param name="obj">The object to keep in bounds.</param> public void KeepInBounds(GameObject obj) { // if the object went outside the boundaries of the room, collide it with a wall and push // it back in. Vector2 oldPosition = obj.Position; obj.Position = Vector2.Clamp(obj.Position, Vector2.Zero, new Vector2(GetWidthInPixels() - obj.BBox.Width - 1, GetHeightInPixels() - obj.BBox.Height - 1)); if (oldPosition != obj.Position) { // TODO: properly create a region of collision corresponding to the amount of the exit overlapped Vector2 change = new Vector2(Math.Abs(oldPosition.X - obj.Position.X), Math.Abs(oldPosition.Y - obj.Position.Y)); obj.Collide(new Tile(TileType.Wall), new BBox(oldPosition, (int)change.X, (int)change.Y)); } }
/// <summary> /// Returns distance in pixels to the specified GameObject. /// NOTE: May want to move to GameObject. /// </summary> /// <param name="target"></param> /// <returns></returns> internal Double DistanceToObject(GameObject target) { return Math.Sqrt( Math.Pow(BBox.Center.X - target.BBox.Center.X, 2) + Math.Pow(BBox.Center.Y - target.BBox.Center.Y, 2)); }
/// <summary> /// Get the number of columns that the given object spans over. /// </summary> /// <param name="obj">An object in the room.</param> /// <returns>The number of columns that the object spans over, starting at 0 if the object is /// confined to 1 tile.</returns> private int GetColSpan(GameObject obj) { return (int)(((obj.BBox.Y % TILESIZE) + obj.BBox.Height) / TILESIZE); }
/// <summary> /// Adds the given object to the current room of the world. /// </summary> /// <param name="obj">The object to be added to the current room.</param> public void Add(GameObject obj) { Add(obj, curRoom); }
/// <summary> /// Get the number of rows that the given object spans over. /// </summary> /// <param name="obj">An object in the room.</param> /// <returns>The number of rows that the object spans over, starting at 0 if the object is /// confined to 1 tile.</returns> private int GetRowSpan(GameObject obj) { return (int)(((obj.BBox.X % TILESIZE) + obj.BBox.Width) / TILESIZE); }
/// <summary> /// Gets the next start position of an object in a room, /// given its entering direction. /// </summary> /// <param name="obj">An object entering a new room.</param> /// <param name="direction">The direction the object is entering the room from.</param> /// <returns>The starting position of the object in the room.</returns> private Vector2 GetNextStartPosition(GameObject obj, Direction direction) { float newXPos = obj.Position.X, newYPos = obj.Position.Y; if (DirectionOperations.IsHorizontal(direction)) { // start it at the opposite end of the room newXPos = MathHelper.Distance(obj.Position.X, curRoom.GetWidthInPixels()); // pad the object away from entrance to prevent them from exiting immediately newXPos += (newXPos <= curRoom.GetWidthInPixels() / 2) ? ENTRANCE_PADDING : -ENTRANCE_PADDING; } if (DirectionOperations.IsVertical(direction)) { newYPos = MathHelper.Distance(obj.Position.Y, curRoom.GetHeightInPixels()); newYPos += (newYPos <= curRoom.GetHeightInPixels() / 2) ? ENTRANCE_PADDING : -ENTRANCE_PADDING; } return new Vector2(newXPos, newYPos); }
/// <summary> /// Check if the given object is at the edge of the room. /// </summary> /// <param name="obj">The object in the room to check.</param> /// <param name="direction">The edge of the room that the object is at, or /// Direction.None if the object is not at the edge of the room.</param> /// <returns>True if the object is at the edge of the room, false otherwise.</returns> private bool AtEdge(GameObject obj, out Direction direction) { // use the center of the object's bounding box as the telltale point of whether or not // the object is at the edge. Vector2 coords = GetTileCoordsByPixel(new Vector2(obj.BBox.Center.X, obj.BBox.Center.Y)); direction = Direction.None; // check diagonal edges first if (coords.X == 0 && coords.Y == 0) direction = Direction.NorthWest; else if (coords.X == Width - 1 && coords.Y == 0) direction = Direction.NorthEast; else if (coords.X == 0 && coords.Y == Height - 1) direction = Direction.SouthWest; else if (coords.X == Width - 1 && coords.Y == Height - 1) direction = Direction.SouthEast; // check the other edges else if (coords.X == 0) direction = Direction.West; else if (coords.X == Width - 1) direction = Direction.East; else if (coords.Y == 0) direction = Direction.North; else if (coords.Y == Height - 1) direction = Direction.South; return direction != Direction.None; }
/// <summary> /// Return whether or not a wall overlaps the given object. /// </summary> /// <param name="box">The bounding box that might be overlapping a wall.</param> /// <returns>True if the box overlaps a wall, false otherwise.</returns> private bool WallIntersects(GameObject obj) { // TODO: check every tile that the box overlaps, not just the corners. return WallAtPixel(obj.BBox.Left, obj.BBox.Top) || WallAtPixel(obj.BBox.Right, obj.BBox.Top) || WallAtPixel(obj.BBox.Left, obj.BBox.Bottom) || WallAtPixel(obj.BBox.Right, obj.BBox.Bottom); }
/// <summary> /// Keeps the given object within the boundaries of the room. /// </summary> /// <param name="obj">The object to keep in bounds.</param> public void KeepInBounds(GameObject obj) { obj.Position = Vector2.Clamp(obj.Position, Vector2.Zero, new Vector2(GetWidthInPixels() - obj.BBox.Width - 1, GetHeightInPixels() - obj.BBox.Height - 1)); }