public override void CollideWithObject(GameObject obj, Room room, BBox collision) { if (obj is Player && obj.Color == Color && !Symbolizing) { if (this != room.CorrectPortal) { Unlocked = true; room.Failed = true; room.Finish(); } else { if (type != RoomType.Acceptance) { curSymAnimation = animations.Find((set) => set.IsCalled(SYM + "1")); Symbolizing = true; } else { Unlocked = true; } } } base.CollideWithObject(obj, room, collision); }
public override void CollideWithObject(GameObject obj, Room room, BBox collision) { base.CollideWithObject(obj, room, collision); // ink blobs should smash into each other, but avoid awkward behavior with ink blobs // coming out of the same generator if (obj is InkBlob && !(obj is WaterBlob) && (obj.Color != Color)) room.Add(new InkBlob(Position, Vector2.Lerp(Velocity, obj.Velocity, 0.5f), Color.Combine(obj.Color), Vector2.Lerp(Size, obj.Size, 0.5f), shouldBounce)); room.Remove(this); }
public override void Update(Room room, GameTime gameTime) { if (curAnimation.IsCalled("Appear") && curAnimation.IsDonePlaying()) ChangeAnimation("Main"); else if (curAnimation.IsCalled("Main") && curAnimation.IsDonePlaying()) ChangeAnimation("Disappear"); else if (curAnimation.IsCalled("Disappear") && curAnimation.IsDonePlaying()) room.Remove(this); Move(room, Vector2.Zero); if (direction.X < 0) box = new BBox((int)(Position.X - SIZE_Y / 8 + 40), (int)(Position.Y - SIZE_X / 2), (int)SIZE_Y - 40, (int)SIZE_X); if (direction.X > 0) { box = new BBox((int)(Position.X - 50), (int)Position.Y, (int)SIZE_Y - 140, (int)SIZE_X); } base.Update(room, gameTime); }
public static BBox SmallerOf(BBox box1, BBox box2) { return box1.Area < box2.Area ? box1 : box2; }
public BBox Intersect(BBox other) { Rectangle intersection = Rectangle.Intersect(box, other.Rectangle); if (intersection != Rectangle.Empty) return new BBox(intersection); return null; }
/// <summary> /// Initializes a new instance of the <see cref="GameObject" /> class. /// </summary> /// <param name="position">The position.</param> /// <param name="initialVelocity">The initial velocity.</param> /// <param name="maxSpeed">The max speed.</param> /// <param name="acceleration">The acceleration.</param> /// <param name="deceleration">The deceleration.</param> /// <param name="color">The color.</param> /// <param name="colorable"> /// if set to <c>true</c> [colorable]. /// </param> /// <param name="size">The size.</param> /// <param name="animations">The animations.</param> /// <param name="startAnimationName">Start name of the animation.</param> /// <param name="rotation">The rotation.</param> public GameObject(Vector2 position, Vector2 initialVelocity, Vector2 maxSpeed, Vector2 acceleration, Vector2 deceleration, Color color, bool colorable, Vector2 size, List<AnimationSet> animations, String startAnimationName, float rotation) { this.position = position; velocity = initialVelocity; this.maxSpeed = maxSpeed; this.acceleration = acceleration; this.deceleration = deceleration; this.color = color; this.colorable = colorable; Debug.Assert(size.X >= 0 && size.Y >= 0, "Invalid object size."); this.size = size; this.animations = animations; curAnimation = GetAnimationByName(startAnimationName); Debug.Assert(curAnimation != null, "Couldn't find the starting animation."); this.rotation = rotation; box = new BBox((int)(Position.X + BBOX_OFFSET_X*Size.X), (int)(Position.Y + BBOX_OFFSET_Y*Size.Y), (int)((1 - 2 * BBOX_OFFSET_X)*Size.X), (int)((1-2*BBOX_OFFSET_Y)*Size.Y)); }
/// <summary> /// Returns whether or not the given object is colliding with this object. /// </summary> /// <param name="obj">The object to check.</param> /// <param name="collisionRegion">The region of collision. Empty if no collision occurred.</param> /// <returns>True if the objects are colliding, false otherwise.</returns> public virtual bool IsColliding(GameObject obj, out BBox collisionRegion) { float collisionForgiveness = (this is Spout || obj is Spout) ? SPOUT_CFF : COLLISION_FORGIVENESS_FACTOR; collisionRegion = box.Intersect(obj.box); // only do forgiveness on the smaller box, a small enough box might not even be allowed // to collide on the larger box if we don't care BBox smallerBox = BBox.SmallerOf(box, obj.box); // because boxes are cruel, and not very true to the shape of the objects, only return true // if the area of collision is larger than we're willing to forgive. return collisionRegion != null && !collisionRegion.IsEmpty() && collisionRegion.Area >= smallerBox.Area * collisionForgiveness; }
public virtual void CollideWithObject(GameObject obj, Room room, BBox collision) { }
/// <summary> /// Updates the room. /// </summary> /// <param name="gameTime">The game time.</param> public virtual void Update(GameTime gameTime) { if (ShouldPlayMusic) { ResourceManager.PlaySong(GameEngine.GetTypeName(Type)); ShouldPlayMusic = false; } // Add and remove any buffered objects. AddAllBuffered(); RemoveAllBuffered(); background.Update(gameTime); if (player == null) { Fail(); } if (!Failed) { // Update all objects in the room. if (portals.Find((portal) => portal.Symbolizing) == null) player.Update(this, gameTime); foreach (Portal portal in portals) { portal.Update(this, gameTime); if (portal.Unlocked) Finish(); } foreach (InkGenerator generator in generators) generator.Update(this, gameTime); foreach (WaveGenerator generator in waveGenerators) generator.Update(this, gameTime); foreach (SpoutGenerator generator in spoutGenerators) generator.Update(this, gameTime); foreach (InkBlob blob in blobs) blob.Update(this, gameTime); foreach (Wave wave in waves) wave.Update(this, gameTime); foreach (Spout spout in spouts) spout.Update(this, gameTime); // handle any collisions with the player BBox collision; foreach (Portal portal in portals) if (portal.IsColliding(player, out collision)) { player.CollideWithObject(portal, this, collision); portal.CollideWithObject(player, this, collision); } foreach (InkGenerator generator in generators) { if (generator.IsColliding(player, out collision)) { player.CollideWithObject(generator, this, collision); generator.CollideWithObject(player, this, collision); } } foreach (InkBlob blob in blobs) { if (blob.IsColliding(player, out collision)) { player.CollideWithObject(blob, this, collision); blob.CollideWithObject(player, this, collision); } } foreach (Spike spike in spikes) { if (spike.IsColliding(player, out collision)) { player.CollideWithObject(spike, this, collision); spike.CollideWithObject(player, this, collision); } } collision = new BBox(0, 0, 0, 0); foreach (Wave wave in waves) { if (player.IsColliding(wave, out collision)) { player.CollideWithObject(wave, this, collision); wave.CollideWithObject(player, this, collision); } } foreach (Spout spout in spouts) if (spout.ShouldDamage && player.IsColliding(spout, out collision)) { player.CollideWithObject(spout, this, collision); spout.CollideWithObject(player, this, collision); } // check to see if we entered a new section of the room Section newSection = GetDeepestSection(player); if (GetDeepestSection(player) != curSection) ChangeSection(newSection); // now that we've handled all those objects, update the camera to track whatever it wants to track camera.Update(this, gameTime); inkMap.Update(); miniMap.Update(this, gameTime); toolbar.Update(gameTime); if (toolbar.IsSelected(NAVIGATION)) { miniMapIsVisible = !miniMapIsVisible; GameEngine.ShouldShowMinimap = miniMapIsVisible; } if (toolbar.IsSelected(UNDO)) { player.Die(this); } } }
public override void CollideWithObject(GameObject obj, Room room, BBox collision) { if (!dying && obj.IsCollidable) { // water is special, kills player if (obj is WaterBlob || (obj is Wave && obj.Color == Color.LightBlue) || (obj is Spout && obj.Color == Color.LightBlue && ShouldSpoutCollide(obj))) Die(room); else if (obj is InkBlob || obj is Wave || obj is Spout && ShouldSpoutCollide(obj)) { if (obj.Color == Color.Black) color = Color.Black; else color = color.Combine(obj.Color); } if (obj is Portal) if (color == obj.Color) { if (room.Portals.Count > 1 && obj != room.CorrectPortal) room.Failed = true; //room.Finish(); } if (obj as Spike != null) { // only punish the player if they're moving towards the spikes, too unforgiving otherwise if ((obj.Color == Color.White || obj.Color != Color) && (obj.Facing == Direction.Left && Velocity.X >= 0 || obj.Facing == Direction.Right && Velocity.X <= 0 || obj.Facing == Direction.Up && Velocity.Y >= 0 || obj.Facing == Direction.Down && Velocity.Y <= 0) && collision.Area >= box.Area / 7) //&& Math.Max(MathHelper.Distance(Box.Center.X, obj.Box.Center.X), // MathHelper.Distance(Box.Center.Y, obj.Box.Center.Y)) < 20f) Die(room); } } base.CollideWithObject(obj, room, collision); }