/// <summary> /// Calculates the collision vector between 2 CollisionObjects as seen from refObj, given a certain collision direction. /// </summary> /// <param name="refObj">The object which collides with the other.</param> /// <param name="collObj">The object with which the first collides.</param> /// <param name="collisionDir">The directionality of the collision.</param> /// <returns>A vector representing the normal force collObj enacts on refObj.</returns> public static Vector2 CollisionForce(CollisionObject refObj, CollisionObject collObj, Vector2 collisionDir) { #region creation variables Vector2 collisionVector = Vector2.Zero; Rectangle refBox = refObj.GetCollisionBox(); Rectangle collBox = collObj.GetCollisionBox(); float smallestWidth; float smallestHeight; if (refBox.Width < collBox.Width) { smallestWidth = refBox.Width; } else { smallestWidth = collBox.Width; } if (refBox.Height < collBox.Height) { smallestHeight = refBox.Height; } else { smallestHeight = collBox.Height; } #endregion #region collision switch (collisionDir.ToString()) { #region vertical case "{X:0 Y:-1}": if (refObj.GetSpeedTotal().Y > 0) { collisionVector.Y -= refObj.GetSpeedTotal().Y *(1 + (collObj.GetBounciness() / 10) + Math.Abs(refBox.Bottom - collBox.Top) / smallestHeight); } break; case "{X:0 Y:1}": if (refObj.GetSpeedTotal().Y < 0) { collisionVector.Y -= refObj.GetSpeedTotal().Y *(1 + (collObj.GetBounciness() / 10) + Math.Abs(collBox.Bottom - refBox.Top) / smallestHeight); } break; #endregion #region horizontal case "{X:-1 Y:0}": if (refObj.GetSpeedTotal().X > 0 && (refBox.Center.Y + (refBox.Height * 0.9f) / 2 > collBox.Top || refBox.Center.Y - (refBox.Height * 0.9f) / 2 < collBox.Bottom)) { collisionVector.X -= refObj.GetSpeedTotal().X *(1 + (collObj.GetBounciness() / 10) + Math.Abs(collBox.Left - refBox.Right) / (smallestWidth)); } if (Globals.input.ActionsPressed().Contains(Input.Action.Right)) { collisionVector.X -= 0.1f; } break; case "{X:1 Y:0}": if (refObj.GetSpeedTotal().X < 0 && (refBox.Center.Y + (refBox.Height * 0.9f) / 2 > collBox.Top || refBox.Center.Y - (refBox.Height * 0.9f) / 2 < collBox.Bottom)) { collisionVector.X -= refObj.GetSpeedTotal().X *(1 + (collObj.GetBounciness() / 10) + Math.Abs(refBox.Left - collBox.Right) / (smallestWidth)); } if (Globals.input.ActionsPressed().Contains(Input.Action.Left)) { collisionVector.X += 0.1f; } break; #endregion #region diagonal case "{X:-1 Y:-1}": case "{X:-1 Y:1}": case "{X:1 Y:-1}": case "{X:1 Y:1}": Vector2 center = new Vector2(collBox.Center.X, collBox.Center.Y); collisionVector += DiagonalCollision(refObj, new Circle(center, Vector2.Distance(center, new Vector2(collBox.X, collBox.Y)))) * PhysicsConstants.metersPerPixel; break; #endregion } if (Math.Sign(collObj.GetSpeedTotal().X) != Math.Sign(refObj.GetSpeedTotal().X)) { collisionVector += collObj.GetSpeed() * refObj.CollisionImpactMultiplier(); } #endregion return(collisionVector); }