public virtual bool OnCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) { Vector2 normal = Vector2.Zero; Contact currentContact = contact; Vector2 nextNormal = Vector2.Zero; FixedArray2<Vector2> fx; // No idea what that is, but the function wants it // Iterate through the contacts, summing the normals do { Vector2 vec = Vector2.Zero; contact.GetWorldManifold(out vec, out fx); normal += vec; currentContact = currentContact.Next; } while (currentContact != null); if (normal.Y > Y && normal.X == 0) { Pressed = true; _pressing.Add(fixtureB); } return true; }
private void PreSolve(Contact contact, ref Manifold oldManifold) { if ((Flags & DebugViewFlags.ContactPoints) == DebugViewFlags.ContactPoints) { Manifold manifold = contact.Manifold; if (manifold.PointCount == 0) return; Fixture fixtureA = contact.FixtureA; FixedArray2<PointState> state1, state2; Collision.Collision.GetPointStates(out state1, out state2, ref oldManifold, ref manifold); FixedArray2<Vector2> points; Vector2 normal; contact.GetWorldManifold(out normal, out points); for (int i = 0; i < manifold.PointCount && _pointCount < MaxContactPoints; ++i) { if (fixtureA == null) _points[i] = new ContactPoint(); ContactPoint cp = _points[_pointCount]; cp.Position = points[i]; cp.Normal = normal; cp.State = state2[i]; _points[_pointCount] = cp; ++_pointCount; } } }
// Collision handlers public bool CollisionWithEnemy(Fixture f1, Fixture f2, Contact contact) { Vector2 normal; FixedArray2<Vector2> points; contact.GetWorldManifold(out normal, out points); foreach (IGameComponent comp in this.game.Components) { GameEnemy enemy = comp as GameEnemy; if (enemy != null) { if (enemy.getFixture() == f2) { if ((Math.Abs(normal.Y) > Math.Abs(normal.X)) && (normal.Y < 0)) // The contact is coming from above { enemy.Die(); // Uncomment this line if we decide to fix the timing so we dispose after the animation this.increaseScore(10); this.Jump(); break; } else { this.Die(); } break; } } } return true; }
private void SolveChangeDirection(Contact contact) { Vector2 normal; FixedArray2<Vector2> array; contact.GetWorldManifold(out normal, out array); if (Math.Abs(normal.X) < Comparator.EPS) return; Transform transform; phys_body.GetTransform(out transform); if (array[0].X < transform.p.X) rotation = 1; else rotation = -1; }
private bool OpenTrap(Fixture a, Fixture b, Contact c) { if (b.Body.UserData is Wall) { Vector2 normal; FarseerPhysics.Common.FixedArray2<Vector2> pointlist; c.GetWorldManifold(out normal, out pointlist); Vector2 position = pointlist[0]; // Create open trap body.UserData = null; } return c.IsTouching; }
bool OnCollision(Fixture platformFixture, Entity entity, Fixture entityFixture, Contact contact) { if (entityFixture.IsSensor) return false; bool result = false; if (!collided.Contains(entityFixture)) { Vector2 normal; FixedArray2<Vector2> points; contact.GetWorldManifold(out normal, out points); //check if contact points are moving into platform for (int i = 0; i < contact.Manifold.PointCount; i++) { var pointVelPlatform = platformFixture.Body.GetLinearVelocityFromWorldPoint(points[i]); var pointVelEntity = entity.Physics.GetLinearVelocityFromWorldPoint(points[i]); var relativeVel = platformFixture.Body.GetLocalVector(pointVelEntity - pointVelPlatform); if (relativeVel.Y > 1) //if moving down faster than 1 m/s, handle as before { result = true;//point is moving into platform, leave contact solid and exit break; } else if (relativeVel.Y > -1) { //if moving slower than 1 m/s //borderline case, moving only slightly out of platform var relativePoint = platformFixture.Body.GetLocalPoint(points[i]); float platformFaceY = 0.5f;//front of platform, from fixture definition :( if (relativePoint.Y > platformFaceY - 0.05) { result = true;//contact point is less than 5cm inside front face of platfrom break; } } } } collided.Add(entityFixture); return result; }
protected virtual bool onCollision(Fixture f1, Fixture f2, Contact contact) { Fixture obstacle = (f1 == PhysicsBody) ? f2 : f1; //if beneath the feet, treat it as ground WorldManifold manifold; contact.GetWorldManifold(out manifold); if (contact.IsTouching()) { if (isGround(manifold, obstacle)) { ground.Add(obstacle); groundNormal = manifold.Normal; groundVector = getGroundVector(); groundSlope = groundVector.Y / groundVector.X; //Console.Out.WriteLine("OnCollision called"); } } return true; }
private void PhysicsPostSolve(Fixture f1, Fixture f2, Contact contact) { Fixture self = null, other = null; Vector2 normal; FixedArray2<Vector2> points; contact.GetWorldManifold(out normal, out points); if (contact.FixtureA == _fsFixture) { self = contact.FixtureA; other = contact.FixtureB; } else if (contact.FixtureB == _fsFixture) { self = contact.FixtureB; other = contact.FixtureA; } // sticky behavior: null out all velocity normal to the surface of the wall, // apply some shitty fake friction to the velocity parallel to the surface of the wall. Vector2 normalComponent, parallelComponent; normalComponent = normal * Vector2.Dot(normal, other.Body.LinearVelocity); parallelComponent = other.Body.LinearVelocity - normalComponent; float velMultiplier = 1f - Stickiness * (1 / 100000f); Vector2 newVelocity; if (other.Body.LinearVelocity.Length() < 1e-10 || parallelComponent.Length() < 1e-10) { newVelocity = Vector2.Zero; } else if (other.Body.LinearVelocity.Y > 0) { newVelocity = parallelComponent * Math.Min(parallelComponent.Length(), UpwardSpeedLimit) / parallelComponent.Length(); } else { newVelocity = parallelComponent * velMultiplier; } other.Body.LinearVelocity = newVelocity; }
private void SolveContact(Contact contact) { Vector2 norm; FixedArray2<Vector2> array; contact.GetWorldManifold(out norm, out array); if (array[0].Y <= GetPosition().Y && array[1].Y <= GetPosition().Y) canUp = 2; }
public void PostSolve(Contact contact, ContactConstraint contactConstraint) { string levelUid = LevelSystem.currentLevelUid; List<int> characterEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.CharacterMovement); int entityAId = (int)contact.FixtureA.Body.UserData; int entityBId = (int)contact.FixtureB.Body.UserData; CharacterMovementComponent characterMovementComponent = null; FixedArray2<Vector2> points; Vector2 normal; characterMovementComponent = (_entityManager.getComponent(levelUid, entityAId, ComponentType.CharacterMovement) ?? _entityManager.getComponent(levelUid, entityBId, ComponentType.CharacterMovement)) as CharacterMovementComponent; if (characterMovementComponent != null) { if (contact.FixtureA == characterMovementComponent.feetFixture || contact.FixtureB == characterMovementComponent.feetFixture) { contact.GetWorldManifold(out normal, out points); characterMovementComponent.collisionNormals.Add(normal); //if (characterMovementComponent.allowJumpResetOnCollision) // characterMovementComponent.alreadyJumped = false; } } }
public bool BeginContact(Contact contact) { string levelUid = LevelSystem.currentLevelUid; List<int> levelGoalEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.RegionGoal); List<int> explosionEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Explosion); LevelSystem levelSystem = (LevelSystem)_systemManager.getSystem(SystemType.Level); ExplosionSystem explosionSystem = (ExplosionSystem)_systemManager.getSystem(SystemType.Explosion); int playerId = PlayerSystem.PLAYER_ID; // See if player is touching a level goal if (levelGoalEntities.Count > 0) { int entityA = (int)contact.FixtureA.Body.UserData; int entityB = (int)contact.FixtureB.Body.UserData; if (entityA == playerId) { if (levelGoalEntities.Contains(entityB)) levelSystem.completeRegionGoal(entityB); } else if (entityB == playerId) { if (levelGoalEntities.Contains(entityA)) levelSystem.completeRegionGoal(entityA); } } // Explosions if (explosionEntities.Count > 0) { int entityA = (int)contact.FixtureA.Body.UserData; int entityB = (int)contact.FixtureB.Body.UserData; IComponent component = null; ExplosionComponent explosionComponent = null; Fixture targetFixture = null; FixedArray2<Vector2> points; if (_entityManager.tryGetComponent(levelUid, entityA, ComponentType.Explosion, out component)) targetFixture = contact.FixtureB; else if (_entityManager.tryGetComponent(levelUid, entityB, ComponentType.Explosion, out component)) targetFixture = contact.FixtureA; if (targetFixture != null && component != null) { DestructibleGeometryComponent destructibleGeometryComponent = (DestructibleGeometryComponent)_entityManager.getComponent(levelUid, (int)targetFixture.Body.UserData, ComponentType.DestructibleGeometry); Vector2 contactNormal; Vector2 relative; Vector2 force; float distance; //contact.GetWorldManifold(out worldManifold); contact.GetWorldManifold(out contactNormal, out points); explosionComponent = (ExplosionComponent)component; relative = (targetFixture.Shape.Center + targetFixture.Body.Position) - explosionComponent.position; distance = Math.Max(relative.Length(), 0.1f); force = relative * (1 / distance) * explosionComponent.strength; if (destructibleGeometryComponent != null) { // Break fixture off from body explosionSystem.breakFixture(targetFixture, force, 180); return false; } else { // Apply generic explosion force targetFixture.Body.ApplyForce(force, points[0]); return false; } } } return true; }
public static bool dog_OnCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) { GameObject dog = (GameObject)fixtureA.Body.UserData; GameObject otherObject = (GameObject)fixtureB.Body.UserData; Vector2 normal; FixedArray2<Vector2> points; contact.GetWorldManifold(out normal, out points); Vector2 collidePoint = ConvertUnits.ToDisplayUnits(points[0]); dog.collisioncount++; if (otherObject.typeid == (int)GameObjectTypes.GROUND) { if (dog.collisioncount == 1) { SunManager.Instance.Mood = SunMood.MAD; AudioManager.Instance.SoundEffect("dog_oof").Play(0.5f, 0, 0); if (dog.sprite.PlayerNumber == 1) { ScoreKeeper.Instance.PlayerLeftScore -= ScoreKeeper.Missing; } if (dog.sprite.PlayerNumber == 2) { ScoreKeeper.Instance.PlayerRightScore -= ScoreKeeper.Missing; } SpriteHelper.Instance.TriggerAfter(delegate() { AudioManager.Instance.SoundEffect("cat_soclose").Play(0.5f, 0, 0); }, 1000); } //SpriteHelper.Instance.RemoveAfter(dog.id, 8000); if (dog.alive) { dog.alive = false; SpriteHelper.Instance.TriggerAfter(delegate() { if (dog.sprite != null) { Vector2 dogCenter = dog.sprite.Center; SpriteHelper.Instance.TriggerAnimation(GameObjectTypes.PUFF, dogCenter - new Vector2(128, 128), "spritesheet", 15); } SpriteHelper.Instance.TriggerAfter(delegate() { GameObjectFactory.Instance.Remove(dog.id); }, 100); }, 6000); return true; } } else if (otherObject.typeid == (int)GameObjectTypes.CAT) { if (dog.collisioncount == 1) { Instance.NewestCollision = dog.sprite.PlayerNumber; } } //something here giving 50 points else if (otherObject.typeid == (int)GameObjectTypes.DOG) { SpriteHelper.Instance.TriggerAfter(delegate() { if (otherObject.sprite != null) { Vector2 otherCenter = otherObject.sprite.Center; SpriteHelper.Instance.TriggerAnimation(GameObjectTypes.PUFF, otherCenter - new Vector2(128, 128), "spritesheet", 15); } SpriteHelper.Instance.TriggerAfter(delegate() { GameObjectFactory.Instance.Remove(otherObject.id); }, 100); }, 1000); if (dog.collisioncount == 1) { AudioManager.Instance.SoundEffect("dog_impact").Play(0.5f, 0, 0); } } else if (otherObject.typeid == (int)GameObjectTypes.WOOD1 || otherObject.typeid == (int)GameObjectTypes.WOOD2 || otherObject.typeid == (int)GameObjectTypes.WOOD3 || otherObject.typeid == (int)GameObjectTypes.WOOD4 ) { SunManager.Instance.Mood = SunMood.TOOTHYSMILE; //otherObject.collisiontime = System.Environment.TickCount; //otherObject.sprite.PlayerNumber = dog.sprite.PlayerNumber; if (dog.collisioncount == 1) { Instance.NewestCollision = dog.sprite.PlayerNumber; //Instance.SpreadVirus(); SpriteHelper.Instance.TriggerAnimation(GameObjectTypes.DUSTSPLODE, otherObject.sprite.Center - new Vector2(180, 180), "dustsplode", 15); SpriteHelper.Instance.TriggerAfter(delegate() { GameObjectFactory.Instance.Remove(otherObject.id); }, 100); AudioManager.Instance.SoundEffect("dog_impact").Play(); SpriteHelper.Instance.TriggerFadeUp(GameObjectTypes.SCOREPLUS50, collidePoint, "scoresheet"); if (Game1.ScreenConfiguration == 2) { if (Instance.NewestCollision == 1) { //ScoreKeeper.Instance.PlayerLeftScore += ScoreKeeper.HittingWood; Instance.client.SendMessage("action=sendpoints;playernumber=" + Instance.NewestCollision + ";score=" + 50); } if (Instance.NewestCollision == 2) { //ScoreKeeper.Instance.PlayerRightScore += ScoreKeeper.HittingWood; Instance.client.SendMessage("action=sendpoints;playernumber=" + Instance.NewestCollision + ";score=" + 50); } } return true; } if (dog.collisioncount < 2) { SpriteHelper.Instance.TriggerAnimation(GameObjectTypes.EXPLOSION1, collidePoint - new Vector2(175, 197), "explosion1", 15); //AudioManager.Instance.SoundEffect("dog_impact").Play(0.5f, 0, 0); } } else if (otherObject.typeid == (int)GameObjectTypes.PLANE) { if (dog.collisioncount == 1) { //PlaneManager.Instance.planeState = PlaneState.BOMB; PlaneManager.Instance.Bomb(dog.sprite.PlayerNumber); //do some bombing if (Game1.ScreenConfiguration == 2) { if (dog.sprite.PlayerNumber == 1) { //ScoreKeeper.Instance.PlayerLeftScore += ScoreKeeper.HittingPlane; Instance.client.SendMessage("action=sendpoints;playernumber=" + Instance.NewestCollision + ";score=" + 100); } if (dog.sprite.PlayerNumber == 2) { //ScoreKeeper.Instance.PlayerRightScore += ScoreKeeper.HittingPlane; Instance.client.SendMessage("action=sendpoints;playernumber=" + Instance.NewestCollision + ";score=" + 100); } } SpriteHelper.Instance.TriggerFadeUp(GameObjectTypes.SCOREPLUS100, collidePoint, "scoresheet"); AudioManager.Instance.SoundEffect("dog_bark").Play(0.5f, 0, 0); } } return true; }
/// <summary> /// Returns true if a contact should not be disabled due to portal clipping. /// </summary> private bool IsContactValid(Contact contact) { FixtureData[] fixtureData = new FixtureData[2]; fixtureData[0] = FixtureExt.GetData(contact.FixtureA); fixtureData[1] = FixtureExt.GetData(contact.FixtureB); BodyData[] bodyData = new BodyData[2]; bodyData[0] = BodyExt.GetData(contact.FixtureA.Body); bodyData[1] = BodyExt.GetData(contact.FixtureB.Body); Xna.Vector2 normal; FixedArray2<Xna.Vector2> vList; contact.GetWorldManifold(out normal, out vList); if (bodyData[0].IsChild || bodyData[1].IsChild) { if (bodyData[0].IsChild && bodyData[1].IsChild) { //return true; } int childIndex = bodyData[0].IsChild ? 0 : 1; int otherIndex = bodyData[0].IsChild ? 1 : 0; BodyData bodyDataChild = bodyData[childIndex]; BodyData bodyDataOther = bodyData[otherIndex]; FixtureData fixtureDataChild = fixtureData[childIndex]; FixtureData fixtureDataOther = fixtureData[otherIndex]; } //Contact is invalid if it is between two fixtures where one fixture is colliding with a portal on the other fixture. if (fixtureData[0].IsPortalParentless() && fixtureData[1].IsPortalParentless()) { for (int i = 0; i < fixtureData.Length; i++) { int iNext = (i + 1) % fixtureData.Length; var intersection = fixtureData[iNext].GetPortalChildren().Intersect(fixtureData[i].PortalCollisions); if (intersection.Count() > 0) { //Debug.Fail("Fixtures with portal collisions should be filtered."); return false; } } } //Contact is invalid if it is too close to a portal. foreach (IPortal p in Scene.GetPortalList()) { if (!Portal.IsValid(p)) { continue; } FixturePortal portal = p as FixturePortal; if (portal != null) { //Don't consider this portal if its fixtures are part of the contact. if (fixtureData[0].PartOfPortal(portal) || fixtureData[1].PartOfPortal(portal)) { continue; } LineF line = new LineF(Portal.GetWorldVerts(portal)); double[] vDist = new double[] { MathExt.PointLineDistance(vList[0], line, true), MathExt.PointLineDistance(vList[1], line, true) }; //Only consider contacts that are between the fixture this portal is parented too and some other fixture. if (contact.FixtureA == FixtureExt.GetFixtureAttached(portal) || contact.FixtureB == FixtureExt.GetFixtureAttached(portal)) { if (contact.Manifold.PointCount == 1) { if (vDist[0] < FixturePortal.CollisionMargin) { return false; } } else if (vDist[0] < FixturePortal.CollisionMargin && vDist[1] < FixturePortal.CollisionMargin) { return false; } } } } //Contact is invalid if it is on the opposite side of a colliding portal. for (int i = 0; i < fixtureData.Length; i++) { int iNext = (i + 1) % fixtureData.Length; foreach (IPortal portal in fixtureData[i].PortalCollisions) { LineF line = new LineF(Portal.GetWorldVerts(portal)); FixturePortal cast = portal as FixturePortal; if (cast != null) { if (fixtureData[i].PartOfPortal(cast) || fixtureData[iNext].PartOfPortal(cast)) { continue; } } //Contact is invalid if it is on the opposite side of the portal from its body origin. //Xna.Vector2 pos = BodyExt.GetData(fixtureData[i].Fixture.Body).PreviousPosition; Vector2 pos = BodyExt.GetLocalOrigin(fixtureData[i].Fixture.Body); bool oppositeSides0 = line.GetSideOf(vList[0]) != line.GetSideOf(pos); Debug.Assert(contact.Manifold.PointCount > 0); if (contact.Manifold.PointCount == 1) { if (oppositeSides0) { return false; } } else //else if (line.GetSideOf((vList[0] + vList[1])/2) != line.GetSideOf(pos)) { bool oppositeSides1 = line.GetSideOf(vList[1]) != line.GetSideOf(pos); /*if (oppositeSides0 && oppositeSides1) { return false; } if (oppositeSides0) { contact.Manifold.Points[0] = contact.Manifold.Points[1]; } contact.Manifold.PointCount = 1; return true;*/ if (!oppositeSides0 && !oppositeSides1) { continue; } if (!fixtureData[iNext].PortalCollisions.Contains(portal) || !(oppositeSides0 || oppositeSides1)) { return false; } } } } return true; }
private void AfterLowerShapeCollision(Fixture fA, Fixture fB, Contact contact) { var v = new Vector2(); var fa = new FixedArray2<Vector2>(); contact.GetWorldManifold(out v, out fa); v = fa[0]; _groundContactPoint = v; if (v.Y > Body.Position.Y + 1.1f) IsTouchingGround = true; contact.Enabled = true; }
public void OnAfterCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) { Vector2 vec = Vector2.Zero; FixedArray2<Vector2> fx; contact.GetWorldManifold(out vec, out fx); for (int i = 0; i < contact.Manifold.PointCount; i++) { fx[i].Normalize(); } }
/// <summary> /// コリジョン発生イベント ハンドラー /// </summary> /// <param name="fixtureA">フィクスチャーA (自分)</param> /// <param name="fixtureB">フィクスチャーB (衝突相手)</param> /// <param name="contact">コンタクト情報</param> /// <returns></returns> private bool CollisionEnterEventHandler(Fixture fixtureA, Fixture fixtureB, Contact contact) { var phy = Physics2D.GetInstance (); var a = fixtureA.UserData as PhysicsBody; var b = fixtureB.UserData as PhysicsBody; if (a.body == null || b.body == null) { // メモ: // Bodyを Dispose してもただちに無効化されるわけではなく、 // 同ステップではイベント ハンドラーも含めてまだ有効。 // ここでチェックしてお帰りいただく必要がある。 return false; } if (((a.CollisionMask & b.GroupID) == 0) || ((b.CollisionMask & a.GroupID) == 0)) { return false; } XnaVector2 normal; // A --> B FixedArray2<XnaVector2> points; contact.GetWorldManifold (out normal, out points); var count = contact.Manifold.PointCount; if (count == 0 && contact.IsTouching ()) { // センサー(トリガー)モードの時、 // count=0 かつ Manifold は未定義 var cp = new ContactPoint (b, new Vector3 (0, 0, 0), new Vector3 (0, 0, 0)); foreach (var comp in Node.Components) { comp.OnCollisionEnter (cp); } } else if (count == 1) { var p = new Vector3 (points[0].X * phy.PPM, points[0].Y * phy.PPM, 0); var n = new Vector3 (normal.X, normal.Y, 0); var cp = new ContactPoint (b, p, n); foreach (var comp in Node.Components) { comp.OnCollisionEnter (cp); } } else if (count == 2) { var p = new Vector3 ((points[0].X + points[1].X) / 2.0f * phy.PPM, (points[0].Y + points[1].Y) / 2.0f * phy.PPM, 0); var n = new Vector3 (normal.X, normal.Y, 0); var cp = new ContactPoint (b, p, n); foreach (var comp in Node.Components) { comp.OnCollisionEnter (cp); } } return true; }
public bool OnCollision(Fixture fix1, Fixture fix2, Contact contact) { if (fix2.UserData is Bullet && !((Bullet)fix2.UserData).Player && _invincibility <= 0) { SharedHealth.CurrentHealth -= fix2.Body.LinearVelocity.Length(); ((Bullet)fix2.UserData).Dispose(); _invincibility = 1500; } if (fix2.UserData is Spike) { if (((Spike)fix2.UserData).MainFixture.Body.BodyType == BodyType.Static) { ((Spike)fix2.UserData).MainFixture.Body.BodyType = BodyType.Dynamic; } } if (fix2.UserData is PickupSpecial) { PickupSpecial pickup = (PickupSpecial)fix2.UserData; if (pickup.PlayerIndex == PlayerIndex || pickup.PlayerIndex == PlayerIndex.Three) { switch (pickup.GameSwitch) { default: GameSave.CurrentGameSwitches |= pickup.GameSwitch; pickup.Dead = true; break; } } } if (fix2.UserData is Enemy && ((Enemy)fix2.UserData).TouchDamage > 0 && _invincibility <= 0) { _sharedHealth.CurrentHealth -= ((Enemy)fix2.UserData).TouchDamage; _invincibility = 1500; } if (fix2.UserData is Pickup) { Pickup pickup = (Pickup)fix2.UserData; if (pickup.PlayerIndex == PlayerIndex || pickup.PlayerIndex == PlayerIndex.Three) { switch (pickup.Collectable) { case Collectable.HEALTH: SharedHealth.CurrentHealth += 25; pickup.Dead = true; break; case Collectable.FULLHEALTH: SharedHealth.CurrentHealth = SharedHealth.MaxHealth; pickup.Dead = true; break; default: Collectables |= pickup.Collectable; pickup.Dead = true; break; } } } //if ((Collectables & Collectable.GRAB) != Collectable.GRAB) // _jumpPower = 0; if (_body.Body.LinearVelocity.Length() > 20) { Health -= _body.Body.LinearVelocity.Length() / 2.0; _invincibility = 1500; _bounceSound.Play(0.5f, 0, 0); } if (fix2.UserData is IPickable && _gamePadState.Buttons.LeftShoulder == ButtonState.Pressed && _heldObject == null && (Collectables & Collectable.GRAB) == Collectable.GRAB) { _heldObject = (IPickable)fix2.UserData; } //else if (fix2.UserData is IClibmableThing) //{ // ClimbableThings.Add(fix2); //} else if (fix2.UserData is IPassableBottom) { if (_fixtures[0].Body.LinearVelocity.Y > 0 || _fixtures[1].Body.Position.Y - 0.3 < fix2.Body.Position.Y) return false; } else if (!fix2.IsSensor) { // Check if the player is standing on a surface at less than pi/4 radians from the horizontal // First calculate the overall normal Vector2 normal = Vector2.Zero; Contact currentContact = contact; Vector2 nextNormal = Vector2.Zero; FixedArray2<Vector2> fx; // No idea what that is, but the function wants it lol // Iterate through the contacts, summing the normals do { Vector2 vec = Vector2.Zero; contact.GetWorldManifold(out vec, out fx); normal += vec; currentContact = currentContact.Next; } while (currentContact != null); double normalAngle = Math.Atan2(normal.X, normal.Y); if (Math.Abs(normalAngle) <= MathHelper.PiOver4) { _moveState = MoveState.GROUND; } else if (Math.Abs(normalAngle) < MathHelper.Pi) { _moveState = MoveState.SLIDING; } } return true; }
bool BeginContact(Contact contact) { if (contact.FixtureA.Body.UserData == null || contact.FixtureB.Body.UserData == null) return true; if (contact.FixtureA.Body.UserData is BipedBodyDescriptor || contact.FixtureB.Body.UserData is BipedBodyDescriptor) { var bipedBody = (contact.FixtureA.Body.UserData is BipedBodyDescriptor) ? contact.FixtureA.Body : contact.FixtureB.Body; var biped = (BipedBodyDescriptor)bipedBody.UserData; var other = (bipedBody == contact.FixtureB.Body) ? contact.FixtureA.Body : contact.FixtureB.Body; Vector2 wmNormal; FixedArray2<Vector2> wmPoints; contact.GetWorldManifold(out wmNormal, out wmPoints); switch (biped.FixtureIndex) { case BipedFixtureIndex.LFoot: if (biped.Biped.OwnedPlayer.StickingLegs && biped.Biped.OwnedPlayer.Welds[0] == null && biped.Biped.OwnedPlayer.WeldDefs[0] == false) { var jd = biped.Biped.OwnedPlayer.Welds[0] = EasyRevoluteJoint(biped.Biped.Bodies[(int)biped.FixtureIndex], other, wmPoints[0]); jd.LowerLimit = -0.5f * (float)Math.PI; // -90 degrees jd.UpperLimit = 0.25f * (float)Math.PI; // 45 degrees jd.LimitEnabled = true; jd.CollideConnected = true; biped.Biped.OwnedPlayer.WeldDefs[0] = true; } break; case BipedFixtureIndex.RFoot: if (biped.Biped.OwnedPlayer.StickingLegs && biped.Biped.OwnedPlayer.Welds[1] == null && biped.Biped.OwnedPlayer.WeldDefs[1] == false) { var jd = biped.Biped.OwnedPlayer.Welds[1] = EasyRevoluteJoint(biped.Biped.Bodies[(int)biped.FixtureIndex], other, wmPoints[0]); jd.LowerLimit = -0.5f * (float)Math.PI; // -90 degrees jd.UpperLimit = 0.25f * (float)Math.PI; // 45 degrees jd.LimitEnabled = true; jd.CollideConnected = true; biped.Biped.OwnedPlayer.WeldDefs[1] = true; } break; case BipedFixtureIndex.LHand: if (biped.Biped.OwnedPlayer.StickingHands && biped.Biped.OwnedPlayer.Welds[2] == null && biped.Biped.OwnedPlayer.WeldDefs[2] == false) { var jd = biped.Biped.OwnedPlayer.Welds[2] = EasyRevoluteJoint(biped.Biped.Bodies[(int)biped.FixtureIndex], other, wmPoints[0]); jd.LowerLimit = -0.5f * (float)Math.PI; // -90 degrees jd.UpperLimit = 0.25f * (float)Math.PI; // 45 degrees jd.LimitEnabled = true; jd.CollideConnected = true; biped.Biped.OwnedPlayer.WeldDefs[2] = true; } break; case BipedFixtureIndex.RHand: if (biped.Biped.OwnedPlayer.StickingHands && biped.Biped.OwnedPlayer.Welds[3] == null && biped.Biped.OwnedPlayer.WeldDefs[3] == false) { var jd = biped.Biped.OwnedPlayer.Welds[3] = EasyRevoluteJoint(biped.Biped.Bodies[(int)biped.FixtureIndex], other, wmPoints[0]); jd.LowerLimit = -0.5f * (float)Math.PI; // -90 degrees jd.UpperLimit = 0.25f * (float)Math.PI; // 45 degrees jd.LimitEnabled = true; jd.CollideConnected = true; biped.Biped.OwnedPlayer.WeldDefs[3] = true; } break; } } return true; }
public bool turtleSpinCollision(Fixture f1, Fixture f2, Contact contact) { Console.WriteLine(f2.Body.UserData); if (f1.UserData != null && f2.UserData != null) { Vector2 normal = Vector2.Zero; FixedArray2<Vector2> points; contact.GetWorldManifold(out normal, out points); char id = (char)f1.UserData; AnimatedSprite Coll; if (id == 'o') Coll = new AnimatedSprite(orange_coll_sprite, 2, 3, 4); else if (id == 'r') Coll = new AnimatedSprite(red_coll_sprite, 2, 3, 4); else if (id == 'b') Coll = new AnimatedSprite(blue_coll_sprite, 2, 3, 4); else if (id == 'p') Coll = new AnimatedSprite(purple_coll_sprite, 2, 3, 4); else Coll = new AnimatedSprite(orange_coll_sprite, 2, 3, 4); Coll.playOnce = true; Coll.position = ConvertUnits.ToDisplayUnits(points[0]); Coll.normal = ConvertUnits.ToDisplayUnits(f1.Body.Position) - Coll.position; spriteList.Add(Coll); } return true; }
public bool OnCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) { if (fixtureA.Body == mBody) { mColor = Color.Red; } Vector2 vec = Vector2.Zero; FixedArray2<Vector2> fx; contact.GetWorldManifold(out vec, out fx); for (int i = 0; i < contact.Manifold.PointCount; i++) { fx[i].Normalize(); //particleEffect.Trigger(new Vector2(fx[i].X * 64, fx[i].Y * 64)); } return true; // return true to actually do the collision }
public bool OnCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) { //if (fixtureA.Body == mBody) //{ // mColor = Color.Red; //} Vector2 vec = Vector2.Zero; FixedArray2<Vector2> fx; contact.GetWorldManifold(out vec, out fx); for (int i = 0; i < contact.Manifold.PointCount; i++) { fx[i].Normalize(); Vector2 point = new Vector2(fx[i].X, fx[i].Y); //TODO I dont like how we have to set the camera in this GameObject this.mParticleEffect.Trigger(PhysicsGameScreen.mCamera.ConvertWorldToScreen(point)); } return true; // return true to actually do the collision }
private bool MyOnCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) { FixedArray2<Vector2> worldPoints; Vector2 normal; contact.GetWorldManifold(out normal, out worldPoints); collisionPoint = ConvertUnits.ToDisplayUnits(worldPoints[0]); drawSpark = true; Random randomSound = new Random(); effect[randomSound.Next(3)].Play(); return true; }
private void AfterUpperShapeCollision(Fixture fA, Fixture fB, Contact contact) { var v = new Vector2(); var fa = new FixedArray2<Vector2>(); contact.GetWorldManifold(out v, out fa); v = fa[0]; if (v.X < Body.Position.X - 0.5f) IsTouchingLeftWall = true; else if (v.X > Body.Position.X + 0.5f) IsTouchingRightWall = true; contact.Enabled = true; }
bool OnCollidedWith(Fixture f, WorldGeometry2 wg, Fixture wF, Contact info) { Vector2 norm; FarseerPhysics.Common.FixedArray2<Vector2> pts; info.GetWorldManifold(out norm, out pts); norm.Normalize(); if (!collided.Any(x => x.Item1 == wF)) collided.Add(Tuple.Create(wF, norm)); Physics.IgnoreGravity = true; return info.Enabled; }
private void PreSolveListener(Contact contact, ref Manifold oldManifold) { if (contact.IsTouching) { Debug.Assert(contact.Manifold.PointCount > 0); /* Sometimes a body will tunnel through a portal fixture. * The circumstances aren't well understood but checking if the contact normal * is facing from fixtureB to fixtureA (it should always face from A to B * according to the Box2D documentation) and then reversing the normal if it is * helps prevent tunneling from occuring.*/ if (!FixtureExt.GetData(contact.FixtureA).IsPortalParentless() || !FixtureExt.GetData(contact.FixtureB).IsPortalParentless()) { Xna.Vector2 normal; FixedArray2<Xna.Vector2> vList; contact.GetWorldManifold(out normal, out vList); Vector2 center0 = FixtureExt.GetCenterWorld(contact.FixtureA); Vector2 center1 = FixtureExt.GetCenterWorld(contact.FixtureB); if (Math.Abs(MathExt.AngleDiff(center1 - center0, (Vector2)normal)) > Math.PI / 2) { contact.Manifold.LocalNormal *= -1; } } if (!IsContactValid(contact)) { contact.Enabled = false; //return; } else { Actor actor0 = BodyExt.GetData(contact.FixtureA.Body).Actor; Actor actor1 = BodyExt.GetData(contact.FixtureB.Body).Actor; actor0.CallOnCollision(actor1, true); actor1.CallOnCollision(actor0, false); } #region Debug if (DebugMode) { FixtureData[] userData = new FixtureData[2]; userData[0] = FixtureExt.GetData(contact.FixtureA); userData[1] = FixtureExt.GetData(contact.FixtureB); Xna.Vector2 normal; FixedArray2<Xna.Vector2> vList; contact.GetWorldManifold(out normal, out vList); if (contact.Manifold.PointCount == 2) { Model line = ModelFactory.CreateLines( new LineF[] { new LineF(vList[0], vList[1]) }); if (contact.Enabled) { line.SetColor(new Vector3(1, 1, 0.2f)); } else { line.SetColor(new Vector3(0.5f, 0.5f, 0)); } line.Transform.Position += new Vector3(0, 0, 5); DebugEntity.AddModel(line); } for (int i = 0; i < 2; i++) { float scale = 0.8f; Vector3 pos = new Vector3(vList[i].X, vList[i].Y, 5); //Ignore contact points that are exactly on the origin. These are almost certainly null values. if (pos.X == 0 && pos.Y == 0) { continue; } Vector2 arrowNormal = (Vector2)normal * 0.2f * scale; if (i == 0) { arrowNormal *= -1; } Model arrow = ModelFactory.CreateArrow(pos, arrowNormal, 0.02f * scale, 0.05f * scale, 0.03f * scale); DebugEntity.AddModel(arrow); Model model = ModelFactory.CreateCube(); model.Transform.Scale = new Vector3(0.08f, 0.08f, 0.08f) * scale; DebugEntity.AddModel(model); if (contact.Enabled) { model.SetColor(new Vector3(1, 1, 0.2f)); arrow.SetColor(new Vector3(1, 1, 0.2f)); } else { model.SetColor(new Vector3(0.5f, 0.5f, 0)); arrow.SetColor(new Vector3(0.5f, 0.5f, 0)); } if (userData[0].IsPortalParentless() && userData[1].IsPortalParentless()) { arrow.SetColor(new Vector3(0.7f, 0.5f, 0.2f)); } model.Transform.Position = pos; if (!userData[i].IsPortalParentless()) { IList<Vector2> vertices = Vector2Ext.ToOtk(((PolygonShape)userData[i].Fixture.Shape).Vertices); Model fixtureModel = ModelFactory.CreatePolygon(vertices); fixtureModel.SetColor(new Vector3(0, 1, 1)); fixtureModel.Transform = userData[i].Actor.GetTransform().Get3D(); fixtureModel.Transform.Position += new Vector3(0, 0, 5); fixtureModel.Transform.Scale = Vector3.One; DebugEntity.AddModel(fixtureModel); } } } #endregion } }
private void SolveCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) { if (IsDestroyByTouching) { Destroyed = true; return; } Vector2 normal; FixedArray2<Vector2> array; contact.GetWorldManifold(out normal, out array); if (Math.Abs(normal.Y) > 0.8) Destroyed = true; else if (DestroyPlayer) MarioGame.GameOver = false; }
public static bool cat_OnCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) { GameObject cat = (GameObject)fixtureA.Body.UserData; GameObject otherObject = (GameObject)fixtureB.Body.UserData; cat.collisioncount++; Vector2 normal; FixedArray2<Vector2> points; contact.GetWorldManifold(out normal, out points); Vector2 collidePoint = ConvertUnits.ToDisplayUnits(points[0]); if (otherObject.typeid == (int)GameObjectTypes.DOG) { //cat.sprite.HitPoints -= (int)otherObject.sprite.PhysicsBody.LinearVelocity.Length(); cat.sprite.HitPoints = 0; AudioManager.Instance.SoundEffect("cat1").Play(); } if (otherObject.typeid == (int)GameObjectTypes.WOOD1 || otherObject.typeid == (int)GameObjectTypes.WOOD2 || otherObject.typeid == (int)GameObjectTypes.WOOD3 || otherObject.typeid == (int)GameObjectTypes.WOOD4) { if (otherObject.sprite.PhysicsBody.LinearVelocity.Length() > 2) { cat.sprite.HitPoints = 0; AudioManager.Instance.SoundEffect("cat_moan").Play(); } //dont know what that is /*else { if (otherObject.sprite.PlayerNumber == 1) { ScoreKeeper.Instance.PlayerLeftScore += ScoreKeeper.HittingWood; SpriteHelper.Instance.TriggerFadeUp(GameObjectTypes.SCOREPLUS50, collidePoint, "scoresheet"); } else if (otherObject.sprite.PlayerNumber == 2) { ScoreKeeper.Instance.PlayerRightScore += ScoreKeeper.HittingWood; SpriteHelper.Instance.TriggerFadeUp(GameObjectTypes.SCOREPLUS50, collidePoint, "scoresheet"); } otherObject.sprite.PlayerNumber = 0; }*/ } //might have to do negatives if (cat.sprite.PhysicsBody.LinearVelocity.X >= 5 || cat.sprite.PhysicsBody.LinearVelocity.Y >= 5) { cat.sprite.HitPoints = 0; AudioManager.Instance.SoundEffect("cat_aaagh").Play(); } if (cat.sprite.HitPoints <= 0) { //if cat dies, points awarded to person to last hit tower if (Game1.ScreenConfiguration == 2) { if (Instance.NewestCollision == 1 && !cat.sprite.AlreadyGavePoints) { //ScoreKeeper.Instance.PlayerLeftScore += ScoreKeeper.HittingCat; SpriteHelper.Instance.TriggerFadeUp(GameObjectTypes.SCOREPLUS250, collidePoint, "scoresheet"); cat.sprite.AlreadyGavePoints = true; Instance.client.SendMessage("action=sendpoints;playernumber=" + Instance.NewestCollision + ";score=" + 250); } if (Instance.NewestCollision == 2 && !cat.sprite.AlreadyGavePoints) { //ScoreKeeper.Instance.PlayerRightScore += ScoreKeeper.HittingCat; SpriteHelper.Instance.TriggerFadeUp(GameObjectTypes.SCOREPLUS250, collidePoint, "scoresheet"); cat.sprite.AlreadyGavePoints = true; Instance.client.SendMessage("action=sendpoints;playernumber=" + Instance.NewestCollision + ";score=" + 250); } } Vector2 catCenter = cat.sprite.Center; SpriteHelper.Instance.TriggerAfter(delegate() { SpriteHelper.Instance.TriggerAnimation(GameObjectTypes.CATSPLODE, catCenter - new Vector2(32, 32), "catsplode", 15); SpriteHelper.Instance.TriggerAfter(delegate() { GameObjectFactory.Instance.Remove(cat.id); }, 100); }, 100); //AudioManager.Instance.SoundEffect("dog_oof").Play(); } return true; }
public ColliderContact(Contact contact) { this.colliderA = contact.FixtureA.Body.UserData; this.colliderB = contact.FixtureB.Body.UserData; involvesATrigger = colliderA.isTrigger || colliderB.isTrigger; // Creates collisions Microsoft.Xna.Framework.Vector2 normal; FarseerPhysics.Common.FixedArray2<Microsoft.Xna.Framework.Vector2> points; contact.GetWorldManifold(out normal, out points); collisionBToA = new Collision() { collider = colliderB, relativeVelocity = ((colliderA.rigidbody != null) ? colliderA.rigidbody.velocity : Vector3.zero) - ((colliderB.rigidbody != null) ? colliderB.rigidbody.velocity : Vector3.zero), contacts = new ContactPoint[contact.Manifold.PointCount] }; collisionAToB = new Collision() { collider = colliderA, relativeVelocity = ((colliderB.rigidbody != null) ? colliderB.rigidbody.velocity : Vector3.zero) - ((colliderA.rigidbody != null) ? colliderA.rigidbody.velocity : Vector3.zero), contacts = new ContactPoint[contact.Manifold.PointCount] }; for (int j = 0; j < collisionBToA.contacts.Length; j++) { collisionBToA.contacts[j].thisCollider = colliderB; collisionBToA.contacts[j].otherCollider = colliderA; collisionBToA.contacts[j].point = VectorConverter.Convert(points[j], colliderB.to2dMode); collisionBToA.contacts[j].normal = VectorConverter.Convert(-normal, colliderB.to2dMode); collisionAToB.contacts[j].thisCollider = colliderA; collisionAToB.contacts[j].otherCollider = colliderB; collisionAToB.contacts[j].point = VectorConverter.Convert(points[j], colliderA.to2dMode); collisionAToB.contacts[j].normal = VectorConverter.Convert(normal, colliderA.to2dMode); } }
private bool OpenTrap(Fixture a, Fixture b, Contact c) { if (b.Body.UserData is Wall) { if (!Open) { Vector2 normal; FarseerPhysics.Common.FixedArray2<Vector2> pointlist; c.GetWorldManifold(out normal, out pointlist); Vector2 position = pointlist[0]; Open = true; if (world.BodyList.Contains(body)) world.RemoveBody(body); body = BodyFactory.CreateRectangle(world, 100 * MainGame.PIXEL_TO_METER, 16 * MainGame.PIXEL_TO_METER, 1f); body.BodyType = BodyType.Static; body.Position = position + normal / normal.Length() * 10 * MainGame.PIXEL_TO_METER; body.Rotation = (float)Math.Atan2(normal.Y, normal.X) + MathHelper.PiOver2; body.CollisionCategories = collisionCat; body.UserData = this; } } else if (b.Body.UserData is Trap) { if (!Open && ((Trap)b.Body.UserData).Open) { body.UserData = null; ((Trap)b.Body.UserData).Explode(); } } else if (b.Body.UserData is Stick_Figures.StickFigure) { if (Open) Explode(); } return c.IsTouching; }
protected override bool OnCollisionEventHandler(Fixture fixtureA, Fixture fixtureB, Contact contact) { Vector2 normal; FixedArray2<Vector2> points; contact.GetWorldManifold(out normal, out points); if (contact.IsTouching && normal.Y < -.5f) { ground = fixtureB; grounded = true; } return true; }