public static void ResolveCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial material, bool handleBoth) { theirObject.Physics.Velocity = Vector2.Zero; ourObject.Physics.Velocity = Vector2.Zero; ourObject.MarkForDelete = true; }
public static void EtherealCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial material, bool handleBoth) { // Start player's flashing animation to indicate she was hit. PlayerActorComponent actor = theirObject.Components.FindComponent<PlayerActorComponent>(); if (actor != null && !actor.IsInvincible) actor.ApplyDamageEffects(); }
///<summary> ///Callback for when the microbe collides with another object. ///</summary> ///<param name="ourObject">The microbe.</param> ///<param name="theirObject">The other object.</param> ///<param name="info">Information about the collision point.</param> ///<param name="resolve">Not used.</param> ///<param name="physicsMaterial"> ///The physics properties of the objects. ///</param> public void OnCollision( T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { if (!ourObject.MarkForDelete && theirObject.TestObjectType(_collidesWith)) { //handle microbe collision with another microbe if (theirObject.TestObjectType( TorqueObjectDatabase.Instance.GetObjectType("microbe"))) { T2DPhysicsComponent.BounceCollision.Invoke( ourObject, theirObject, ref info, physicsMaterial, false); //T2DPhysicsComponent.ClampCollision.Invoke( //ourObject, theirObject, ref info, physicsMaterial, false); //T2DPhysicsComponent.KillCollision.Invoke( //ourObject, theirObject, ref info, physicsMaterial, false); //T2DPhysicsComponent.RigidCollision.Invoke( //ourObject, theirObject, ref info, physicsMaterial, false); //T2DPhysicsComponent.StickyCollision.Invoke( //ourObject, theirObject, ref info, physicsMaterial, false); } else if (theirObject.TestObjectType( TorqueObjectDatabase.Instance.GetObjectType("projectile"))) { //T2DPhysicsComponent.BounceCollision.Invoke( // ourObject, theirObject, ref info, physicsMaterial, false); //T2DPhysicsComponent.ClampCollision.Invoke( //ourObject, theirObject, ref info, physicsMaterial, false); T2DPhysicsComponent.KillCollision.Invoke( ourObject, theirObject, ref info, physicsMaterial, false); //T2DPhysicsComponent.RigidCollision.Invoke( //ourObject, theirObject, ref info, physicsMaterial, false); //T2DPhysicsComponent.StickyCollision.Invoke( //ourObject, theirObject, ref info, physicsMaterial, false); } //TODO: add handling for other object types } }
/// <summary> /// T2DOnCollision delegate to handle damage between the melee scene object and enemies /// </summary> /// <param name="myObject">The melee scene object mounted on the player</param> /// <param name="theirObject">The enemy scene object</param> /// <param name="info">Collision information</param> /// <param name="resolve">How the collision will be resolved</param> /// <param name="physicsMaterial">The type of material that would affect the physics</param> public static void MeleeCollision(T2DSceneObject myObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { int damage = myObject.Components.FindComponent<AttackCollisionComponent>().Damage; if (theirObject.TestObjectType(PlatformerData.PlayerObjectType)) { PlayerActorComponent actor = theirObject.Components.FindComponent<PlayerActorComponent>(); // Deal damage to the enemy if (actor != null) actor.TakeDamage(damage, myObject, true, true); } myObject.MarkForDelete = true; }
public static void ProjCollision(T2DSceneObject projectile, T2DSceneObject targetObject, T2DCollisionInfo into, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial material) { int damage = projectile.Components.FindComponent<ProjectileComponent>().Damage; if (targetObject.TestObjectType(PlatformerData.ActorObjectType)) { PlayerActorComponent actor = targetObject.Components.FindComponent<PlayerActorComponent>(); // Deal damage to the enemy if (actor != null) actor.TakeDamage(damage, projectile, true, true); } projectile.CollisionsEnabled = false; projectile.MarkForDelete = true; }
/// <summary> /// T2DOnCollision delegate to handle damage between the kushling and the player /// </summary> /// <param name="myObject">The kushling</param> /// <param name="theirObject">The collided object.</param> /// <param name="info">Collision information</param> /// <param name="resolve">How the collision will be resolved</param> /// <param name="physicsMaterial">The type of material that would affect the physics</param> public static void KushCollision(T2DSceneObject myObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { int damage = myObject.Components.FindComponent<KushlingActorComponent>().Damage; if (theirObject.TestObjectType(PlatformerData.ActorObjectType)) { PlayerActorComponent actor = theirObject.Components.FindComponent<PlayerActorComponent>(); // Deal damage to the enemy if (actor != null && !actor.IsInvincible) actor.TakeDamage(damage, myObject, true, true); } else if (theirObject.TestObjectType(PlatformerData.EnemyObjectType)) { resolve = T2DPhysicsComponent.ClampCollision; } else resolve = null; }
protected static void _resolveBounce(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth) { if (ourObject.Physics != null) { // are we already bouncing away? float dot = Vector2.Dot(ourObject.Physics.Velocity, info.Normal); if (dot < 0.0f) ourObject.Physics.Velocity = ourObject.Physics.Velocity - (1.0f + physicsMaterial.Restitution) * dot * info.Normal; } if (handleBoth && theirObject.Physics != null) { // are they already bouncing away? float dot = Vector2.Dot(theirObject.Physics.Velocity, -info.Normal); if (dot < 0.0f) theirObject.Physics.Velocity = theirObject.Physics.Velocity + (1.0f + physicsMaterial.Restitution) * dot * info.Normal; } }
/// <summary> /// Callback for when the projectile collides with another object. /// </summary> /// <param name="ourObject">The projectile.</param> /// <param name="theirObject">The other object.</param> /// <param name="info">Information about the collision point.</param> /// <param name="resolve">Not used.</param> /// <param name="physicsMaterial">The physics properties of the objects.</param> public void OnCollision( T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { if (!ourObject.MarkForDelete && theirObject.TestObjectType(_collidesWith)) { // If we hit a player object then activate its game pad vibration T2DStaticSprite psprite = theirObject as T2DStaticSprite; if (psprite != null) { GamepadVibrationComponent vib = psprite.Components.FindComponent<GamepadVibrationComponent>(); if (vib != null) { vib.SetLowSpeedVibration(0.1f, 0.8f); } } if (theirObject.TestObjectType(TorqueObjectDatabase.Instance.GetObjectType("tank"))) { Explode(info, true); } else { Explode(info, false); } } }
/// <summary> /// T2DOnCollision delegate to handle damage between the melee scene object and enemies /// </summary> /// <param name="myObject">The melee scene object mounted on the player</param> /// <param name="theirObject">The enemy scene object</param> /// <param name="info">Collision information</param> /// <param name="resolve">How the collision will be resolved</param> /// <param name="physicsMaterial">The type of material that would affect the physics</param> public static void MeleeCollision(T2DSceneObject myObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>(); int damage = myObject.Components.FindComponent<AttackCollisionComponent>().Damage; // Deal damage to the enemy if(actor != null) actor.TakeDamage(damage, myObject, true, true); myObject.MarkForDelete = true; }
private static void PlayerCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { if (theirObject is T2DAnimatedSprite) { var player = (T2DAnimatedSprite) TorqueObjectDatabase.Instance.FindObject<T2DSceneObject>("Player1"); var aiPlayer = (T2DAnimatedSprite) TorqueObjectDatabase.Instance.FindObject<T2DSceneObject>("Player2"); if (player.AnimationData.Name.Contains("SpecialMove")) { Game.Instance.AiHealth -= 2.5; } else if (aiPlayer.AnimationData.Name.Contains("SpecialMove")) { Game.Instance.PlayerHealth -= 2.5; } } }
protected static void _resolveRigid(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth) { Assert.Fatal(ourObject.Physics != null, "Cannot use rigid collision response without physics component"); Assert.Fatal((theirObject != null && theirObject.Physics != null) || !handleBoth, "Cannot use rigid collision response without physics component"); //------------------------------------------------------------------------------------------------------ // Fetch information. //------------------------------------------------------------------------------------------------------ // collision normal Vector2 normal = -info.Normal; // Positions Vector2 srcPosition = ourObject.Position; Vector2 dstPosition = theirObject != null ? theirObject.Position : Vector2.Zero; // Velocities Vector2 srcVelocity = ourObject.Physics.Velocity; Vector2 dstVelocity = Vector2.Zero; // Angular Velocities. float srcAngularVelocity = MathHelper.ToRadians(-ourObject.Physics.AngularVelocity); float dstAngularVelocity = 0.0f; // Friction/Restitution. float friction = physicsMaterial.Friction; float restitution = physicsMaterial.Restitution; // Inverse Masses. float srcInverseMass = ourObject.Physics.InverseMass; float dstInverseMass = 0.0f; // Inverse Inertial Moments. float srcInverseInertialMoment = ourObject.Physics.InverseRotationalInertia; float dstInverseInertialMoment = 0.0f; if (theirObject != null && theirObject.Physics != null) { dstVelocity = theirObject.Physics.Velocity; dstAngularVelocity = MathHelper.ToRadians(-theirObject.Physics.AngularVelocity); dstInverseMass = theirObject.Physics.InverseMass; dstInverseInertialMoment = theirObject.Physics.InverseRotationalInertia; } //------------------------------------------------------------------------------------------------------ // Contact info. //------------------------------------------------------------------------------------------------------ // Contact Velocity. Vector2 srcContactDelta = info.Position - srcPosition; Vector2 dstContactDelta = info.Position - dstPosition; Vector2 srcContactDeltaPerp = new Vector2(-srcContactDelta.Y, srcContactDelta.X); Vector2 dstContactDeltaPerp = new Vector2(-dstContactDelta.Y, dstContactDelta.X); Vector2 srcVP = srcVelocity - srcAngularVelocity * srcContactDeltaPerp; Vector2 dstVP = dstVelocity - dstAngularVelocity * dstContactDeltaPerp; //------------------------------------------------------------------------------------------------------ // Calculate Impact Velocity. //------------------------------------------------------------------------------------------------------ Vector2 deltaImpactVelocity = dstVP - srcVP; float deltaVelocityDot = Vector2.Dot(deltaImpactVelocity, normal); // Are we seperated? if (deltaVelocityDot > 0.0f) // Yes, so no interaction! return; // Normalise velocity. Vector2 Vn = deltaVelocityDot * normal; Vector2 Vt = deltaImpactVelocity - Vn; float vt = Vt.Length(); Vector2 VtDir = Vt; if (vt > 0.0f) VtDir *= 1.0f / vt; //------------------------------------------------------------------------------------------------------ // Calculate Impulse ( Dynamic-Friction and Restitution ) //------------------------------------------------------------------------------------------------------ // Break Impulse Function Down a little... float srcRN = Collision2D.PerpDot(srcContactDelta, normal); float dstRN = Collision2D.PerpDot(dstContactDelta, normal); float t0 = srcRN * srcRN * srcInverseInertialMoment; float t1 = dstRN * dstRN * dstInverseInertialMoment; float denom = srcInverseMass + dstInverseMass + t0 + t1; // handle two non-rotating, non-moving objects colliding (two platforms?) float jn = Math.Abs(denom) > Epsilon.Value ? deltaVelocityDot / denom : 0.0f; // Calculate Impulse (include restitution/dynamic friction). Vector2 impulseForce = ((-(1.0f + restitution) * jn) * normal) + ((friction * jn) * VtDir); //------------------------------------------------------------------------------------------------------ // Changes in Momentum ( Linear and Angular ). //------------------------------------------------------------------------------------------------------ // Calculate Linear Acceleration. Vector2 srcLinearDelta = -impulseForce * srcInverseMass; Vector2 dstLinearDelta = impulseForce * dstInverseMass; // Calculate Angular Acceleration. float srcAngularDelta = Collision2D.PerpDot(srcContactDelta, impulseForce) * srcInverseInertialMoment; float dstAngularDelta = -Collision2D.PerpDot(dstContactDelta, impulseForce) * dstInverseInertialMoment; //------------------------------------------------------------------------------------------------------ // Finally, apply acceleration. //------------------------------------------------------------------------------------------------------ ourObject.Physics.Velocity += srcLinearDelta; ourObject.Physics.AngularVelocity -= MathHelper.ToDegrees(srcAngularDelta); if (handleBoth) { theirObject.Physics.Velocity += dstLinearDelta; theirObject.Physics.AngularVelocity -= MathHelper.ToDegrees(dstAngularDelta); } }
public virtual void OnCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { // call our custom collision resolve // (this is almost exactly the same as clamp, but takes *both* objects' velocity into account) if (theirObject.TestObjectType(PlatformerData.PlatformObjectType)) resolve = ResolveActorCollision; else resolve = null; // if we hit a ladder, enable it if (theirObject.TestObjectType(PlatformerData.LadderObjectType)) { // find the ladder component LadderComponent ladder = theirObject.Components.FindComponent<LadderComponent>(); // enable it if (ladder != null) ladder.Enabled = true; } }
public void OnCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { // call our local trigger OnEnter method _onEnter(ourObject, theirObject, info); }
public override void Dispose() { _IsDisposed = true; if (_collisionImages != null) _collisionImages.Clear(); _collisionImages = null; if (_collisionMaterial != null) _collisionMaterial.Dispose(); _collisionMaterial = null; _onCollision = null; _ResetRefs(); _resolveCollisionDelegate = null; _testEarlyOut = null; base.Dispose(); }
///<summary> ///Callback for when the tank collides with another object. ///</summary> ///<param name="ourObject">The tank.</param> ///<param name="theirObject">The other object.</param> ///<param name="info">Information about the collision point.</param> ///<param name="resolve">Not used.</param> ///<param name="physicsMaterial"> ///The physics properties of the objects. ///</param> public void OnCollision( T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { if (ourObject.MarkForDelete || !theirObject.TestObjectType(_collidesWith)) return; //Set up gamepad vibration if this is a player object //also set up maxVelocity GamepadVibrationComponent vib = ourObject.Components.FindComponent<GamepadVibrationComponent>(); TankMovementComponent mac = ourObject.Components.FindComponent<TankMovementComponent>(); float maxSpeed = 0.1f; //avoid possible divide by zero below if (null != mac) { maxSpeed = mac.MaxForwardSpeed; } //Calculate Impact Velocity. Vector2 deltaImpactVelocity = _CalculateImpactVelocity(ourObject, theirObject, info); float impact = deltaImpactVelocity.Length(); float vibration = MathHelper.Clamp((impact / (maxSpeed * 2.0f)), 0.0f, 1.0f); //Perform sound (on all objects) and vibration (players only) if (vibration < 0.3) { //High speed vibration for the small collisions if (vib != null) { vib.SetHighSpeedVibration(0.2f, (vibration / 0.3f) * 0.8f); } if (vibration >= 0.1 && TorqueEngineComponent.Instance.TorqueTime >= _nextSoftSoundPlayTime) { Program.SoundBank.PlayCue("softCollision"); _nextSoftSoundPlayTime = TorqueEngineComponent.Instance.TorqueTime + SOUND_TIME_STEP + TorqueUtil.GetFastRandomFloat(SOUND_TIME_STEP_VARIANCE); } } else { //Low speed vibration for the big collisions if (vib != null) { vib.SetLowSpeedVibration( 0.2f, ((vibration - 0.3f) / 0.7f) * 0.9f + 0.1f); } if (TorqueEngineComponent.Instance.TorqueTime >= _nextHardSoundPlayTime) { Program.SoundBank.PlayCue("hardCollision"); _nextHardSoundPlayTime = TorqueEngineComponent.Instance.TorqueTime + SOUND_TIME_STEP + TorqueUtil.GetFastRandomFloat(SOUND_TIME_STEP_VARIANCE); } } }
protected static void _resolveClamp(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth) { if (ourObject.Physics != null) { float dot = Vector2.Dot(ourObject.Physics.Velocity, info.Normal); if (dot < 0.0f) ourObject.Physics.Velocity = ourObject.Physics.Velocity - dot * info.Normal; } if (handleBoth && theirObject.Physics != null) { float dot = Vector2.Dot(theirObject.Physics.Velocity, -info.Normal); if (dot < 0.0f) theirObject.Physics.Velocity = theirObject.Physics.Velocity + dot * info.Normal; } }
protected static void _resolveKill(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth) { ourObject.MarkForDelete = true; if (handleBoth) theirObject.MarkForDelete = true; }
public virtual void ResolveActorCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth) { // this is a custom collision response mode for actors // make sure this method is being used on an Actor if (!ourObject.TestObjectType(PlatformerData.ActorObjectType)) return; // make sure it's the right actor ActorComponent actor = ourObject.Components.FindComponent<ActorComponent>(); if (actor == null) return; // check for a physics component if (_actor.Physics == null) return; // get their object's velocity Vector2 theirVel = Vector2.Zero; if (theirObject.Physics != null) theirVel = theirObject.Physics.Velocity; // check if it's a ground surface bool groundSurface = info.Normal.Y <= _maxGroundNormalY; // get the actor's velocity modified velocity by the destination object's velocity Vector2 vel = _actor.Physics.Velocity - theirVel; //get the dot product float dot = Vector2.Dot(vel, info.Normal); // if we're currently on the ground, do magical stuff if (_onGround && !groundSurface) { // don't let the clamp push us off the ground or into the ground! // accomplish this by clamping the collision normal against the ground normal float groundDot = Vector2.Dot(info.Normal, _groundSurfaceNormal); // remove any portion of the ground surface normal from the collision normal info.Normal -= groundDot * _groundSurfaceNormal; // cancel move speed (this isn't a ground surface that we hit) _moveSpeed.X = 0; } // return if we're moving away from the surface if (dot >= 0.0f) return; // if object was not a ground surface... if (!groundSurface) { // notify the controller that we hit a wall if (Controller as ActorController != null) (Controller as ActorController).ActorHitWall(this, info, dot); // forfeit all inherited velocity // (we ran into something, just get rid of it!) _inheritedVelocity = Vector2.Zero; } else { // if we actually overlapped with a platform, correct by a small amount (1/10 of a unit) // (the purpose of _groundYBuffer is to avoid constant collisions from scraping across the ground. // if we are colliding with the ground regularly, _groundYBuffer is too low. this error correction // is intended to solve potential problems when prolonged penetration occurs.) _platformError += info.Normal * 0.1f; } // clamp our actial velocity anyway _actor.Physics.Velocity -= dot * info.Normal; // if we're not on the ground, just dump our velocity into our move speed // and let the actor's physics clamp it if (!_onGround) _moveSpeed.X = _actor.Physics.Velocity.X; }
protected static void _resolveSticky(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth) { if (ourObject.Physics != null) { ourObject.Physics.Velocity = new Vector2(0, 0); ourObject.Physics.AngularVelocity = 0; } if (handleBoth && theirObject.Physics != null) { theirObject.Physics.Velocity = new Vector2(0, 0); theirObject.Physics.AngularVelocity = 0; } }
/// <summary> /// T2DOnCollision delegate to handle damage between the melee scene object and enemies /// </summary> /// <param name="myObject">The melee scene object mounted on the player</param> /// <param name="theirObject">The enemy scene object</param> /// <param name="info">Collision information</param> /// <param name="resolve">How the collision will be resolved</param> /// <param name="physicsMaterial">The type of material that would affect the physics</param> public static void MeleeCollision(T2DSceneObject myObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial) { //theirObject.Collision.Images[0]. int damage = myObject.Components.FindComponent<AttackCollisionComponent>().Damage; if(theirObject.TestObjectType(PlatformerData.ActorObjectType)) { EnemyActorComponent actor = theirObject.Components.FindComponent<EnemyActorComponent>(); // Deal damage to the enemy if (actor != null) actor.TakeDamage(damage, theirObject); } else { WeakSpotComponent weakSpot = theirObject.Components.FindComponent<WeakSpotComponent>(); if(weakSpot != null) weakSpot.TakeDamage(damage, true); } myObject.MarkForDelete = true; }