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; }
protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info) { TrapComponent trapComponent = trapObject.Components.FindComponent<TrapComponent>(); trapComponent.Activate(); ourObject.CollisionsEnabled = false; 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(); }
protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info) { ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>(); if (actor == null) return; actor.Kill(Owner as T2DSceneObject); }
protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info) { ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>(); if (actor == null) return; if (_confirmDamage(ourObject, theirObject, actor)) actor.TakeDamage(_damage, ourObject); }
protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info) { PlayerActorComponent player = theirObject.Components.FindComponent<PlayerActorComponent>(); if (player == null) return; else player.SwitchToFallDeath(); base._onEnter(ourObject, theirObject, info); }
protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info) { BairneActorComponent actor = theirObject.Components.FindComponent<BairneActorComponent>(); if (actor != null) { actor.OnLeft = onLeft; actor.ReachedBound = true; actor.HorizontalStop(); } else ;//log error }
/// <summary> /// The routine run when the player collides with the object. /// </summary> /// <param name="ourObject">The trigger object.</param> /// <param name="theirObject">The player that collided with the trigger.</param> /// <param name="info">Some sort of info...</param> protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info) { if (!flipped) { switchedOn = !switchedOn; if (behaviors != null) foreach (ISwitchBehavior behavior in behaviors) behavior.Execute(ourObject, switchedOn); flipped = true; } }
///<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 override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info) { base._onEnter(ourObject, theirObject, info); ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>(); if (actor == null || ourObject == null) return; if (_confirmPickup(ourObject, theirObject, actor)) { ourObject.Visible = false; ourObject.CollisionsEnabled = false; if (actor.Controller != null) (actor.Controller as ActorController).ActorCollectedItem(actor, this); if (ourObject.IsRegistered) TorqueObjectDatabase.Instance.Unregister(ourObject); ourObject = 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 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); } } }
/// <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> /// Produces an explosion at the point of impact. /// </summary> /// <param name="info">Information about the collision point.</param> /// <param name="sparks"> /// Should the explosion includes sparks (tank collision) or not /// (barrier collision). /// </param> public void Explode(T2DCollisionInfo info, bool sparks) { if (sparks) { // Trigger the tank sparks T2DParticleEffect sparksEffect = (TorqueObjectDatabase.Instance.FindObject<T2DParticleEffect>( "SparkEffect")).Clone() as T2DParticleEffect; if (sparksEffect != null) { sparksEffect.Position = info.Position; sparksEffect.Rotation = T2DVectorUtil.AngleFromVector(info.Normal); sparksEffect.Size = new Vector2(10.0f, 10.0f); Owner.Manager.Register(sparksEffect); } MindcraftersComponentsLibrary.SoundBank.PlayCue("explodeTank"); } else { // Trigger smoke T2DParticleEffect smokeEffect = (TorqueObjectDatabase.Instance.FindObject<T2DParticleEffect>( "SmokeEffect")).Clone() as T2DParticleEffect; if (smokeEffect != null) { smokeEffect.Position = info.Position; // For non-tank hit ie: barriers, we do a little // calculation so that glancing blows look like they carry // the momentum of the shell while more direct shots // reflect back towards the direction the shell came from. Vector2 I = SceneObject.Physics.Velocity; I.Normalize(); Vector2 R = I - (Vector2.Dot(2.0f * I, info.Normal) * info.Normal); float dot = Vector2.Dot(info.Normal, -I); smokeEffect.Rotation = T2DVectorUtil.AngleFromVector(dot * -I + (1.0f - dot) * R); smokeEffect.Size = new Vector2(10.0f, 10.0f); Owner.Manager.Register(smokeEffect); } MindcraftersComponentsLibrary.SoundBank.PlayCue("explodeBarrier"); } // Stop the projectile's playing sound on the parent object. // It is stored there to allow the sound to quickly fade rather // than just cut off when the projectile object is unregistered. MainGunComponent mgc = _parentObj.Components.FindComponent<MainGunComponent>(); if (mgc != null) { mgc.StopProjectileSound(_projectileSoundRef); } // Clean up the projectile. if (DestroyOnCollision) Owner.MarkForDelete = true; }
/// <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; }
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 _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); } }
/// <summary> /// Derived classes should add collision points to 'list' using this method, which guarantees that duplicates are not added and that the list is proprly /// reset when earlier collisions are detected. /// </summary> protected void _AddCollisionPoint(ref float dt, float collisionTime, Vector2 pos, Vector2 norm, Vector2 penetration, T2DSceneObject obj, int matidx, List<T2DCollisionInfo> list) { float MIN_COINCIDENT_TIME = 0.0005f; if (collisionTime < 0.0f) collisionTime = 0.0f; if (collisionTime < dt + MIN_COINCIDENT_TIME) { if (collisionTime < dt - MIN_COINCIDENT_TIME) { // prior collision, restart list and decrease dt list.Clear(); dt = collisionTime; } // add collision to list T2DCollisionInfo info = new T2DCollisionInfo(); info.Position = pos; info.Normal = norm; info.Penetration = penetration; info.SceneObject = obj; info.MaterialIndex = matidx; list.Add(info); // save some debug info _keepCollision = 1000; // 1000 frames _lastCollisionPoint = pos; _lastCollisionNormal = norm; } }
/// <summary> /// Called from an actor possessed by this controller each time it collides with a wall or ceiling. /// (as defined on a per-actor basis by the ActorComponent's _maxSurfaceNormalY field). /// </summary> /// <param name="actor">The possessed ActorComponent that hit a wall.</param> /// <param name="info">The collision info for the collision that lead to this callback.</param> /// <param name="dot">Dot product of the velocity and the normal.</param> public virtual void ActorHitWall(ActorComponent actor, T2DCollisionInfo info, float dot) { }
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); }
/// <summary> /// The _onEnter callback that's called whenever an obejct collides with this trigger. /// </summary> /// <param name="ourObject">The owner of this trigger component.</param> /// <param name="theirObject">The object that collided with this trigger.</param> /// <param name="info">The collision info generated for the collision.</param> protected virtual void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info) { }
/// <summary> /// Performs a specialized collision check against the specified object using our ground check collision polyon. /// </summary> /// <param name="obj">The object to check collision against.</param> /// <returns>A list of collisions that occured with the object.</returns> private void _testGroundPolyMove(T2DSceneObject obj) { // clear the Actor's ground collision list for the new check _groundCollisionList.Clear(); // grab their collision component T2DCollisionComponent theirCollider = obj.Collision; // if it doesnt have a collision component we don't care about it if (theirCollider == null) return; // always check based on a full tick float elapsed = 0.03f; // vars for moving poly - poly check float collisionTime = 0.0f; Vector2 collisionNormal = Vector2.Zero; Vector2 collisionPoint = Vector2.Zero; Vector2 collisionPenetration = Vector2.Zero; // use a position shifted up by the height of the ground check poly // (the poly itself is based below the actor, so this actually puts the bottom of it at the bottom of the actor's poly) Vector2 ourPos = new Vector2(_actor.Position.X, _actor.Position.Y - (_groundCheckYThreshold * 4)); // use a velocity that will allow the poly to pass from it's current position // to a position exactly below where the actor's feet will be // (divide by threshold elapsed here to get the full distance in one tick) Vector2 ourVel = new Vector2(_actor.Physics.VelocityX, Math.Abs(_actor.Physics.VelocityY) + ((_groundCheckYThreshold * 4) / elapsed)); // iterate the object's images for (int i = 0; i < obj.Collision.Images.Count; i++) { // grab this collision image T2DPolyImage theirImage = obj.Collision.Images[i] as T2DPolyImage; // if this isn't a poly image, skip it // (when new image types arise, add an if structure here) if (theirImage == null) continue; // call the intersect function to do the math for us bool collisionTest = Collision2D.IntersectMovingPolyPoly( elapsed, _GroundPolyImage.CollisionPoly, theirImage.CollisionPoly, ourPos, theirImage.SceneObject.Position, _GroundPolyImage.SceneObject.Rotation, theirImage.SceneObject.Rotation, ourVel, Vector2.Zero, ref collisionPoint, ref collisionNormal, ref collisionPenetration, ref collisionTime); // if the collision test came back positive... if (collisionTest) { // skip platforms if the collision surface isn't facing 'upwards' at all if (collisionNormal.Y >= 0) continue; // create a new collision info structure and add it to the list so we can return it T2DCollisionInfo newInfo = new T2DCollisionInfo(); newInfo.Normal = collisionNormal; newInfo.Penetration = collisionPenetration; newInfo.Position = collisionPoint + (collisionPenetration / 2); _groundCollisionList.Add(newInfo); } } }
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; }
/// <summary> /// Resolve world limit collision. Typically called by T2DPhysicsComponent. /// </summary> /// <param name="info">Current collision information.</param> public void ResolveWorldLimitCollision(T2DCollisionInfo info) { T2DResolveCollisionDelegate resolve = WorldLimitResolveCollision; T2DOnCollisionDelegate onCollision = OnWorldLimit; T2DCollisionMaterial physicsMaterial = T2DPhysicsComponent.DefaultCollisionMaterial; if (SceneObject.Collision != null && SceneObject.Collision.CollisionMaterial != null) physicsMaterial = SceneObject.Collision.CollisionMaterial; // on collision, on resolve... if (onCollision != null) onCollision(SceneObject, null, info, ref resolve, ref physicsMaterial); Assert.Fatal(physicsMaterial != null, "OnWorldLimitCollision nulled out physics material"); if (resolve != null) resolve(SceneObject, null, ref info, physicsMaterial, false); }
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; } }
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; } }