Exemple #1
0
        private void ClimbOverObstacles()
        {
            if (Collider.FarseerBody.ContactList == null || Math.Abs(movement.X) < 0.01f)
            {
                return;
            }

            //check if the collider is touching a suitable obstacle to climb over
            Vector2?handle = null;

            FarseerPhysics.Dynamics.Contacts.ContactEdge ce = Collider.FarseerBody.ContactList;
            while (ce != null && ce.Contact != null)
            {
                if (ce.Contact.Enabled && ce.Contact.IsTouching && ce.Contact.FixtureA.CollisionCategories.HasFlag(Physics.CollisionWall))
                {
                    Vector2 contactNormal;
                    FarseerPhysics.Common.FixedArray2 <Vector2> contactPos;
                    ce.Contact.GetWorldManifold(out contactNormal, out contactPos);

                    //only climb if moving towards the obstacle
                    if (Math.Sign(contactPos[0].X - Collider.SimPosition.X) == Math.Sign(movement.X) &&
                        (handle == null || contactPos[0].Y > ((Vector2)handle).Y))
                    {
                        handle = contactPos[0];
                    }
                }

                ce = ce.Next;
            }

            if (handle == null)
            {
                return;
            }

            float colliderBottomY = GetColliderBottom().Y;

            //the contact point should be higher than the bottom of the collider
            if (((Vector2)handle).Y < colliderBottomY + 0.01f ||
                ((Vector2)handle).Y > Collider.SimPosition.Y)
            {
                return;
            }

            //find the height of the floor below the torso
            //(if moving towards towards an obstacle that's low enough to climb over, the torso should be above it)
            float obstacleY = GetFloorY(GetLimb(LimbType.Torso));

            if (obstacleY > colliderBottomY)
            {
                //higher vertical velocity for taller obstacles
                Collider.LinearVelocity += Vector2.UnitY * (((Vector2)handle).Y - colliderBottomY + 0.01f) * 50;
                onGround = true;
            }
        }
        /// <summary>
        /// wakes any contacting bodies. Useful when creating a fixture or changing something that won't trigger the bodies to wake themselves
        /// such as Circle.center.
        /// </summary>
        protected void WakeAnyContactingBodies()
        {
            Body body = this.GetComponent <FSRigidBody>().Body;

            FarseerPhysics.Dynamics.Contacts.ContactEdge contactEdge = body.ContactList;
            while (contactEdge != null)
            {
                FarseerPhysics.Dynamics.Contacts.Contact contact = contactEdge.Contact;
                if (contact.FixtureA == _fixture || contact.FixtureB == _fixture)
                {
                    contact.FixtureA.Body.IsAwake = true;
                    contact.FixtureB.Body.IsAwake = true;
                }

                contactEdge = contactEdge.Next;
            }
        }
        public FSCollisionShape SetRestitution(float restitution)
        {
            _fixtureDef.Restitution = restitution;
            if (_fixture != null)
            {
                _fixture.Restitution = restitution;

                Body body = this.GetComponent <FSRigidBody>().Body;
                FarseerPhysics.Dynamics.Contacts.ContactEdge contactEdge = body.ContactList;
                while (contactEdge != null)
                {
                    FarseerPhysics.Dynamics.Contacts.Contact contact = contactEdge.Contact;
                    if (contact.FixtureA == _fixture || contact.FixtureB == _fixture)
                    {
                        contact.ResetRestitution();
                    }

                    contactEdge = contactEdge.Next;
                }
            }

            return(this);
        }