/// <summary> /// Smart collision detection allowing for pixel-perfect collisions. /// </summary> /// <param name="obj">Object to test against</param> /// <returns></returns> public override bool IsOverlappedWith(InteractableObject obj) { var box1 = GetBoundingBox(true); var box2 = obj.GetBoundingBox(true); var isect = Rectangle.Intersect(box1, box2); if (isect.IsEmpty) return false; var gameObject = obj as GameObject; // Check whether both objects are GameObjects and are neither rotated nor scaled if (CollisionDetectionMode == CollisionDetectionMode.Fast || gameObject == null || !Scale.IsAlmost(1) || !obj.Scale.IsAlmost(1) || ScaleVector.HasValue || obj.ScaleVector.HasValue || (!Angle.IsAlmostNull() && CollisionDetectionMode != CollisionDetectionMode.Round) || (!gameObject.Angle.IsAlmostNull() && gameObject.CollisionDetectionMode != CollisionDetectionMode.Round) ) return true; // Convert it from screen coordinates to texture coordinates Rectangle textureRect1 = isect, textureRect2 = isect; textureRect1.X -= box1.X; textureRect1.Y -= box1.Y; textureRect2.X -= box2.X; textureRect2.Y -= box2.Y; var colorData1 = GetCurrentAnimation().GetTextureRegion(textureRect1); var colorData2 = gameObject.GetCurrentAnimation().GetTextureRegion(textureRect2); // If both pixels in the same location are non-transparent // HACK: only 50% of the pixels are checked for the sake of speed for (var idx = 0; idx < colorData1.Length; idx += 2) if (colorData1[idx].A != 0 && colorData2[idx].A != 0) return true; return false; }
/// <summary> /// Check whether an object collides with another object. /// Collision is rectangle based and non-rotatable. /// </summary> /// <param name="obj">Object to test collision to.</param> public virtual bool IsOverlappedWith(InteractableObject obj) { return GetBoundingBox(true).Intersects(obj.GetBoundingBox(true)); }