/// <summary> /// Calculate the colission on a per pixel level /// Looks at both pixel colors. If they are not transparent (the alpha channel is not 0), /// then there is a collision. /// </summary> /// <param name="e1">Entity 1</param> /// <param name="e2">Entity 2</param> /// <returns></returns> private bool PerPixelCollision(AnimatedEntity e1, AnimatedEntity e2) { var at = e1.Animation.Transformations; var afw = e1.Animation.FrameWidth; var afh = e1.Animation.FrameHeight; var acd = e1.Animation.ColorData; var bt = e2.Animation.Transformations; var bfw = e2.Animation.FrameWidth; var bfh = e2.Animation.FrameHeight; var bcd = e2.Animation.ColorData; /// Get Color data of each Texture Color[] bitsA = new Color[afw * afh]; Color[] bitsB = new Color[bfw * bfh]; /// Calculate the intersecting rectangle int x1 = Math.Max(e1.Bounds.X, e2.Bounds.X); int x2 = Math.Min(e1.Bounds.X + e1.Bounds.Width, e2.Bounds.X + e2.Bounds.Width); int y1 = Math.Max(e1.Bounds.Y, e2.Bounds.Y); int y2 = Math.Min(e1.Bounds.Y + e1.Bounds.Height, e2.Bounds.Y + e2.Bounds.Height); /// For each single pixel in the intersecting rectangle for (int y = y1; y < y2; ++y) { for (int x = x1; x < x2; ++x) { /// Get the color from each texture Color a = bitsA[(x - e1.Bounds.X) + (y - e1.Bounds.Y) * afw]; Color b = bitsB[(x - e2.Bounds.X) + (y - e2.Bounds.Y) * bfw]; /// If both colors are not transparent (the alpha channel is not 0), then there is a collision if (a.A != 0 && b.A != 0) { return true; } } } /// If no collision occurred by now, we're clear. return false; }
/// <summary> /// Handle a touch event with another entity. /// This occurs when two entities collide /// </summary> /// <param name="other">The other entity that has been collided with</param> public virtual void Touch(AnimatedEntity other) { }
/// <summary> /// Handle collisions /// </summary> /// <param name="other">The other entity that collided with the asteroid.</param> public override void Touch(AnimatedEntity other) { /// Check to see if the player got hit. if (other is Player) { var player = other as Player; if (!player.UnderProtection) { player.Kill(); } } base.Touch(other); }
/// <summary> /// Check if this entity has collided with another entity /// </summary> /// <param name="other"></param> /// <returns></returns> public bool CheckCollision(AnimatedEntity other) { var distance = Math.Abs(Vector2.Distance(this.CenterPosition, other.CenterPosition)); var inThisRadius = distance < this.Radius; var inOtherRadius = distance < other.Radius; if (inThisRadius || inOtherRadius) { return true; } else { return false; } }
/// <summary> /// Handle collisions with other entities /// </summary> /// <param name="other">The entity that the bullet is colliding with.</param> public override void Touch(AnimatedEntity other) { if (other is Asteroid) { var asteroid = other as Asteroid; asteroid.Health = 0; asteroid.Killer = this; Kill(); } else if (other is EnemyShip) { var enemyShip = other as EnemyShip; enemyShip.Kill(this); Kill(); } base.Touch(other); }