/// <summary> /// Creates an angle joint. /// </summary> /// <param name="world">The world.</param> /// <param name="bodyA">The first body.</param> /// <param name="bodyB">The second body.</param> /// <returns></returns> public static AngleJoint CreateAngleJoint(World world, Body bodyA, Body bodyB) { AngleJoint angleJoint = new AngleJoint(bodyA, bodyB); world.AddJoint(angleJoint); return angleJoint; }
public Spider(World world, PhysicsGameScreen screen, Vector2 position) { //Load bodies _circle = BodyFactory.CreateCircle(world, SpiderBodyRadius, 0.1f, position); _circle.BodyType = BodyType.Dynamic; //Left upper leg _leftUpper = BodyFactory.CreateRectangle(world, _upperLegSize.X, _upperLegSize.Y, 0.1f, _circle.Position - new Vector2(SpiderBodyRadius, 0f) - new Vector2(_upperLegSize.X / 2f, 0f)); _leftUpper.BodyType = BodyType.Dynamic; //Left lower leg _leftLower = BodyFactory.CreateRectangle(world, _lowerLegSize.X, _lowerLegSize.Y, 0.1f, _circle.Position - new Vector2(SpiderBodyRadius, 0f) - new Vector2(_upperLegSize.X, 0f) - new Vector2(_lowerLegSize.X / 2f, 0f)); _leftLower.BodyType = BodyType.Dynamic; //Right upper leg _rightUpper = BodyFactory.CreateRectangle(world, _upperLegSize.X, _upperLegSize.Y, 0.1f, _circle.Position + new Vector2(SpiderBodyRadius, 0f) + new Vector2(_upperLegSize.X / 2f, 0f)); _rightUpper.BodyType = BodyType.Dynamic; //Right lower leg _rightLower = BodyFactory.CreateRectangle(world, _lowerLegSize.X, _lowerLegSize.Y, 0.1f, _circle.Position + new Vector2(SpiderBodyRadius, 0f) + new Vector2(_upperLegSize.X, 0f) + new Vector2(_lowerLegSize.X / 2f, 0f)); _rightLower.BodyType = BodyType.Dynamic; //Create joints JointFactory.CreateRevoluteJoint(world, _circle, _leftUpper, new Vector2(_upperLegSize.X / 2f, 0f)); _leftShoulderAngleJoint = JointFactory.CreateAngleJoint(world, _circle, _leftUpper); _leftShoulderAngleJoint.MaxImpulse = 3f; JointFactory.CreateRevoluteJoint(world, _circle, _rightUpper, new Vector2(-_upperLegSize.X / 2f, 0f)); _rightShoulderAngleJoint = JointFactory.CreateAngleJoint(world, _circle, _rightUpper); _rightShoulderAngleJoint.MaxImpulse = 3f; JointFactory.CreateRevoluteJoint(world, _leftUpper, _leftLower, new Vector2(_lowerLegSize.X / 2f, 0f)); _leftKneeAngleJoint = JointFactory.CreateAngleJoint(world, _leftUpper, _leftLower); _leftKneeAngleJoint.MaxImpulse = 3f; JointFactory.CreateRevoluteJoint(world, _rightUpper, _rightLower, new Vector2(-_lowerLegSize.X / 2f, 0f)); _rightKneeAngleJoint = JointFactory.CreateAngleJoint(world, _rightUpper, _rightLower); _rightKneeAngleJoint.MaxImpulse = 3; _screen = screen; //GFX AssetCreator creator = _screen.ScreenManager.Assets; _torso = new Sprite(creator.CircleTexture(SpiderBodyRadius, MaterialType.Waves, Color.Gray, 1f)); _upperLeg = new Sprite(creator.TextureFromShape(_leftUpper.FixtureList[0].Shape, MaterialType.Blank, Color.DimGray, 1f)); _lowerLeg = new Sprite(creator.TextureFromShape(_leftLower.FixtureList[0].Shape, MaterialType.Blank, Color.DarkSlateGray, 1f)); }
public override void InitJoint () { joint = JointFactory.CreateAngleJoint(FSWorldComponent.PhysicsWorld, BodyA.PhysicsBody, BodyB.PhysicsBody); joint.BiasFactor = BiasFactor; joint.Softness = Softness; joint.CollideConnected = CollideConnected; base.InitJoint (); }
public SpringPhysicsObject(World world, PhysicsObject physObA, PhysicsObject physObB, Vector2 relativeJointPosition, float springSoftness, float springBiasFactor) : base(world, physObA, physObB, relativeJointPosition) { springJoint = JointFactory.CreateAngleJoint(world, physObA.fixture.Body, physObB.fixture.Body); springJoint.TargetAngle = 0; springJoint.Softness = springSoftness; springJoint.BiasFactor = springBiasFactor; }
public override Joint createJoint() { var joint = new AngleJoint( bodyA, bodyB ); joint.collideConnected = collideConnected; joint.maxImpulse = maxImpulse; joint.biasFactor = biasFactor; joint.softness = softness; return joint; }
public JumpySpider(World world, Vector2 position) { // Body _circle = BodyFactory.CreateCircle(world, SpiderBodyRadius, 0.1f, position); _circle.BodyType = BodyType.Dynamic; // Left upper leg _leftUpper = BodyFactory.CreateRectangle(world, _upperLegSize.X, _upperLegSize.Y, 0.1f, _circle.Position - new Vector2(SpiderBodyRadius, 0f) - new Vector2(_upperLegSize.X / 2f, 0f)); _leftUpper.BodyType = BodyType.Dynamic; // Left lower leg _leftLower = BodyFactory.CreateRectangle(world, _lowerLegSize.X, _lowerLegSize.Y, 0.1f, _circle.Position - new Vector2(SpiderBodyRadius, 0f) - new Vector2(_upperLegSize.X, 0f) - new Vector2(_lowerLegSize.X / 2f, 0f)); _leftLower.BodyType = BodyType.Dynamic; // Right upper leg _rightUpper = BodyFactory.CreateRectangle(world, _upperLegSize.X, _upperLegSize.Y, 0.1f, _circle.Position + new Vector2(SpiderBodyRadius, 0f) + new Vector2(_upperLegSize.X / 2f, 0f)); _rightUpper.BodyType = BodyType.Dynamic; // Right lower leg _rightLower = BodyFactory.CreateRectangle(world, _lowerLegSize.X, _lowerLegSize.Y, 0.1f, _circle.Position + new Vector2(SpiderBodyRadius, 0f) + new Vector2(_upperLegSize.X, 0f) + new Vector2(_lowerLegSize.X / 2f, 0f)); _rightLower.BodyType = BodyType.Dynamic; //Create joints JointFactory.CreateRevoluteJoint(world, _circle, _leftUpper, new Vector2(_upperLegSize.X / 2f, 0f)); _leftShoulderAngleJoint = JointFactory.CreateAngleJoint(world, _circle, _leftUpper); _leftShoulderAngleJoint.MaxImpulse = 3f; JointFactory.CreateRevoluteJoint(world, _circle, _rightUpper, new Vector2(-_upperLegSize.X / 2f, 0f)); _rightShoulderAngleJoint = JointFactory.CreateAngleJoint(world, _circle, _rightUpper); _rightShoulderAngleJoint.MaxImpulse = 3f; JointFactory.CreateRevoluteJoint(world, _leftUpper, _leftLower, new Vector2(_lowerLegSize.X / 2f, 0f)); _leftKneeAngleJoint = JointFactory.CreateAngleJoint(world, _leftUpper, _leftLower); _leftKneeAngleJoint.MaxImpulse = 3f; JointFactory.CreateRevoluteJoint(world, _rightUpper, _rightLower, new Vector2(-_lowerLegSize.X / 2f, 0f)); _rightKneeAngleJoint = JointFactory.CreateAngleJoint(world, _rightUpper, _rightLower); _rightKneeAngleJoint.MaxImpulse = 3; //GFX _torso = new Sprite(ContentWrapper.CircleTexture(SpiderBodyRadius, "Square", ContentWrapper.Grey, ContentWrapper.Gold, ContentWrapper.Black, 1f)); _upperLeg = new Sprite(ContentWrapper.TextureFromShape(_leftUpper.FixtureList[0].Shape, ContentWrapper.Grey, ContentWrapper.Black)); _lowerLeg = new Sprite(ContentWrapper.TextureFromShape(_leftLower.FixtureList[0].Shape, ContentWrapper.Gold, ContentWrapper.Black)); _flexed = false; _timer = 0f; _leftShoulderAngleJoint.TargetAngle = ShoulderRelaxed; _leftKneeAngleJoint.TargetAngle = KneeRelaxed; _rightShoulderAngleJoint.TargetAngle = -ShoulderRelaxed; _rightKneeAngleJoint.TargetAngle = -KneeRelaxed; }
private Vector2 _upperLegSize = new Vector2(3, 0.5f); //x=width, y=height #endregion Fields #region Constructors public Spider(World world, Vector2 position) { //Load bodies Body circle = BodyFactory.CreateCircle(world, SpiderBodyRadius, 0.1f, position); circle.BodyType = BodyType.Dynamic; //Left upper leg Body leftUpper = BodyFactory.CreateRectangle(world, _upperLegSize.X, _upperLegSize.Y, 0.1f, circle.Position - new Vector2(SpiderBodyRadius, 0) - new Vector2(_upperLegSize.X / 2, 0)); leftUpper.BodyType = BodyType.Dynamic; //Left lower leg Body leftLower = BodyFactory.CreateRectangle(world, _lowerLegSize.X, _lowerLegSize.Y, 0.1f, circle.Position - new Vector2(SpiderBodyRadius, 0) - new Vector2(_upperLegSize.X, 0) - new Vector2(_lowerLegSize.X / 2, 0)); leftLower.BodyType = BodyType.Dynamic; //Right upper leg Body rightUpper = BodyFactory.CreateRectangle(world, _upperLegSize.X, _upperLegSize.Y, 0.1f, circle.Position + new Vector2(SpiderBodyRadius, 0) + new Vector2(_upperLegSize.X / 2, 0)); rightUpper.BodyType = BodyType.Dynamic; //Right lower leg Body rightLower = BodyFactory.CreateRectangle(world, _lowerLegSize.X, _lowerLegSize.Y, 0.1f, circle.Position + new Vector2(SpiderBodyRadius, 0) + new Vector2(_upperLegSize.X, 0) + new Vector2(_lowerLegSize.X / 2, 0)); rightLower.BodyType = BodyType.Dynamic; //Create joints JointFactory.CreateRevoluteJoint(world, circle, leftUpper, new Vector2(SpiderBodyRadius, 0)); _leftShoulderAngleJoint = JointFactory.CreateAngleJoint(world, circle, leftUpper); _leftShoulderAngleJoint.MaxImpulse = 3; JointFactory.CreateRevoluteJoint(world, circle, rightUpper, new Vector2(-SpiderBodyRadius, 0)); _rightShoulderAngleJoint = JointFactory.CreateAngleJoint(world, circle, rightUpper); _rightShoulderAngleJoint.MaxImpulse = 3; JointFactory.CreateRevoluteJoint(world, leftUpper, leftLower, new Vector2(_upperLegSize.X / 2, 0)); _leftKneeAngleJoint = JointFactory.CreateAngleJoint(world, leftUpper, leftLower); _leftKneeAngleJoint.MaxImpulse = 3; JointFactory.CreateRevoluteJoint(world, rightUpper, rightLower, -new Vector2(_upperLegSize.X / 2, 0)); _rightKneeAngleJoint = JointFactory.CreateAngleJoint(world, rightUpper, rightLower); _rightKneeAngleJoint.MaxImpulse = 3; }
private AngleJointTest() { BodyFactory.CreateEdge(World, new Vector2(-40, 0), new Vector2(40, 0)); Body fA = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(-5, 4)); fA.BodyType = BodyType.Dynamic; Body fB = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(5, 4)); fB.BodyType = BodyType.Dynamic; AngleJoint joint = new AngleJoint(fA, fB); joint.TargetAngle = (float)Math.PI / 2; World.AddJoint(joint); //Keep a body at a fixed angle without a joint Body fC = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(10, 4)); fC.BodyType = BodyType.Dynamic; fC.Rotation = (float)(Math.PI / 3); fC.FixedRotation = true; // Or set the Inertia to float.MaxValue }
private AngleJointTest() { BodyFactory.CreateEdge(World, new Vector2(-40, 0), new Vector2(40, 0)); Body fA = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(-5, 4)); fA.BodyType = BodyType.Dynamic; Body fB = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(5, 4)); fB.BodyType = BodyType.Dynamic; AngleJoint joint = new AngleJoint(fA, fB); joint.TargetAngle = (float)Math.PI / 2; World.AddJoint(joint); Body fC = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(10, 4)); fC.BodyType = BodyType.Dynamic; FixedAngleJoint fixedJoint = new FixedAngleJoint(fC); fixedJoint.TargetAngle = (float)Math.PI / 3; World.AddJoint(fixedJoint); }
/// <summary> /// Sends the stick figure to its default pose /// </summary> public void Stand() { Crouching = false; upright.TargetAngle = 0.0f; walkStage = 0; leftHip.TargetAngle = 3 * MathHelper.PiOver4; leftKnee.TargetAngle = -5 * MathHelper.PiOver4; rightHip.TargetAngle = -3 * MathHelper.PiOver4; rightKnee.TargetAngle = -3 * MathHelper.PiOver4; leftLowerLeg.Friction = 0f; rightLowerLeg.Friction = 0f; AngleJoint[] checkThese = new AngleJoint[] { leftHip, leftKnee, rightHip, rightKnee }; if (JointsAreInPosition(checkThese)) { leftLowerLeg.Friction = 1f; rightLowerLeg.Friction = 1f; } }
/// <summary> /// Adds a Physics Joint to the simulation /// </summary> /// <param name="joint"></param> public void AddPhysicsJoint(PhysicsJoint joint) { string bodyOne = joint.BodyOne; string bodyTwo = joint.BodyTwo; short collisionGroup = Convert.ToInt16(joint.CollisionGroup); bool isAngleSpringEnabled = joint.AngleSpringEnabled; float springConstant = (float)joint.AngleSpringConstant; float angleLowerLimit = (float)joint.AngleLowerLimit; float angleUpperLimit = (float)joint.AngleUpperLimit; Point center = joint.GetCenter(); xna.Vector2 ptCollisionCenter = new xna.Vector2((float)center.X, (float)center.Y); if (!PhysicsObjects.ContainsKey(bodyOne)) throw new Exception("Cannot add joint for an invalid BodyOne value of '" + bodyOne + "'. If using Behaviors, did you forgot to add a PhysicsObjectBehavior?"); if (!PhysicsObjects.ContainsKey(bodyTwo)) throw new Exception("Cannot add joint for an invalid BodyTwo value of '" + bodyTwo + "'. If using Behaviors, did you forgot to add a PhysicsObjectBehavior?"); Body body1 = PhysicsObjects[bodyOne].BodyObject; Body body2 = PhysicsObjects[bodyTwo].BodyObject; xna.Vector2 ptCollisionCenterA = _boundaryHelper.ScreenToWorld(ptCollisionCenter); xna.Vector2 ptCollisionCenterB = _boundaryHelper.ScreenToWorld(ptCollisionCenter); // account for offset within body ptCollisionCenterA -= body1.Position; ptCollisionCenterB -= body2.Position; // DEMO: (5) Create Joints if (joint.IsWeldJoint) { WeldJoint weldJoint = new WeldJoint(body1, body2, ptCollisionCenterA, ptCollisionCenterB); Simulator.AddJoint(weldJoint); } else if (joint.IsDistanceJoint) { DistanceJoint distanceJoint = new DistanceJoint(body1, body2, ptCollisionCenterA, ptCollisionCenterB); Simulator.AddJoint(distanceJoint); } else { RevoluteJoint revoluteJoint = new RevoluteJoint(body1, body2, ptCollisionCenterA, ptCollisionCenterB); Simulator.AddJoint(revoluteJoint); if (isAngleSpringEnabled) { AngleJoint aj = new AngleJoint(body1, body2); aj.TargetAngle = 0; aj.Softness = springConstant; Simulator.AddJoint(aj); } if (angleUpperLimit != -1 && angleLowerLimit != -1) { float upperAngle = (float)PhysicsUtilities.DegreesToRadians(angleUpperLimit); float lowerAngle = (float)PhysicsUtilities.DegreesToRadians(angleLowerLimit); revoluteJoint.LimitEnabled = true; revoluteJoint.LowerLimit = lowerAngle; revoluteJoint.UpperLimit = upperAngle; } } if (collisionGroup > 0) { foreach (Fixture f in PhysicsObjects[bodyOne].BodyObject.FixtureList) { f.CollisionGroup = collisionGroup; } foreach (Fixture f in PhysicsObjects[bodyTwo].BodyObject.FixtureList) { f.CollisionGroup = collisionGroup; } } // get rid of the UI representation of the joint joint.Visibility = Visibility.Collapsed; }
private SerializationTest() { Body ground = BodyFactory.CreateEdge(World, new Vector2(-20, 0), new Vector2(20, 0)); //Friction and distance joint { Body bodyA = BodyFactory.CreateCircle(World, 1, 1.5f, new Vector2(10, 25)); bodyA.BodyType = BodyType.Dynamic; Body bodyB = BodyFactory.CreateRectangle(World, 1, 1, 1, new Vector2(-1, 25)); bodyB.BodyType = BodyType.Dynamic; FrictionJoint frictionJoint = JointFactory.CreateFrictionJoint(World, bodyB, ground, Vector2.Zero); frictionJoint.CollideConnected = true; frictionJoint.MaxForce = 100; JointFactory.CreateDistanceJoint(World, bodyA, bodyB); } //Wheel joint { Vertices vertices = new Vertices(6); vertices.Add(new Vector2(-1.5f, -0.5f)); vertices.Add(new Vector2(1.5f, -0.5f)); vertices.Add(new Vector2(1.5f, 0.0f)); vertices.Add(new Vector2(0.0f, 0.9f)); vertices.Add(new Vector2(-1.15f, 0.9f)); vertices.Add(new Vector2(-1.5f, 0.2f)); Body carBody = BodyFactory.CreatePolygon(World, vertices, 1, new Vector2(0, 1)); carBody.BodyType = BodyType.Dynamic; Body wheel1 = BodyFactory.CreateCircle(World, 0.4f, 1, new Vector2(-1.0f, 0.35f)); wheel1.BodyType = BodyType.Dynamic; wheel1.Friction = 0.9f; Body wheel2 = BodyFactory.CreateCircle(World, 0.4f, 1, new Vector2(1.0f, 0.4f)); wheel2.BodyType = BodyType.Dynamic; wheel2.Friction = 0.9f; Vector2 axis = new Vector2(0.0f, 1.0f); WheelJoint spring1 = JointFactory.CreateWheelJoint(World, carBody, wheel1, axis); spring1.MotorSpeed = 0.0f; spring1.MaxMotorTorque = 20.0f; spring1.MotorEnabled = true; spring1.Frequency = 4; spring1.DampingRatio = 0.7f; WheelJoint spring2 = JointFactory.CreateWheelJoint(World, carBody, wheel2, axis); spring2.MotorSpeed = 0.0f; spring2.MaxMotorTorque = 10.0f; spring2.MotorEnabled = false; spring2.Frequency = 4; spring2.DampingRatio = 0.7f; } //Prismatic joint { Body body = BodyFactory.CreateRectangle(World, 2, 2, 5, new Vector2(-10.0f, 10.0f)); body.BodyType = BodyType.Dynamic; body.Rotation = 0.5f * Settings.Pi; Vector2 axis = new Vector2(2.0f, 1.0f); axis.Normalize(); PrismaticJoint joint = JointFactory.CreatePrismaticJoint(World, ground, body, Vector2.Zero, axis); joint.MotorSpeed = 5.0f; joint.MaxMotorForce = 1000.0f; joint.MotorEnabled = true; joint.LowerLimit = -10.0f; joint.UpperLimit = 20.0f; joint.LimitEnabled = true; } // Pulley joint { Body body1 = BodyFactory.CreateRectangle(World, 2, 4, 5, new Vector2(-10.0f, 16.0f)); body1.BodyType = BodyType.Dynamic; Body body2 = BodyFactory.CreateRectangle(World, 2, 4, 5, new Vector2(10.0f, 16.0f)); body2.BodyType = BodyType.Dynamic; Vector2 anchor1 = new Vector2(-10.0f, 16.0f + 2.0f); Vector2 anchor2 = new Vector2(10.0f, 16.0f + 2.0f); Vector2 worldAnchor1 = new Vector2(-10.0f, 16.0f + 2.0f + 12.0f); Vector2 worldAnchor2 = new Vector2(10.0f, 16.0f + 2.0f + 12.0f); JointFactory.CreatePulleyJoint(World, body1, body2, anchor1, anchor2, worldAnchor1, worldAnchor2, 1.5f, true); } //Revolute joint { Body ball = BodyFactory.CreateCircle(World, 3.0f, 5.0f, new Vector2(5.0f, 30.0f)); ball.BodyType = BodyType.Dynamic; Body polygonBody = BodyFactory.CreateRectangle(World, 20, 0.4f, 2, new Vector2(10, 10)); polygonBody.BodyType = BodyType.Dynamic; polygonBody.IsBullet = true; RevoluteJoint joint = JointFactory.CreateRevoluteJoint(World, ground, polygonBody, new Vector2(10, 0)); joint.LowerLimit = -0.25f * Settings.Pi; joint.UpperLimit = 0.0f * Settings.Pi; joint.LimitEnabled = true; } //Weld joint { PolygonShape shape = new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.125f), 20); Body prevBody = ground; for (int i = 0; i < 10; ++i) { Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(-14.5f + 1.0f * i, 5.0f); body.CreateFixture(shape); Vector2 anchor = new Vector2(0.5f, 0); if (i == 0) anchor = new Vector2(-15f, 5); JointFactory.CreateWeldJoint(World, prevBody, body, anchor, new Vector2(-0.5f, 0)); prevBody = body; } } //Rope joint { LinkFactory.CreateChain(World, new Vector2(-10, 10), new Vector2(-20, 10), 0.1f, 0.5f, 10, 0.1f, true); } //Angle joint { Body fA = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(-5, 4)); fA.BodyType = BodyType.Dynamic; fA.Rotation = (float)(Math.PI / 3); Body fB = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(5, 4)); fB.BodyType = BodyType.Dynamic; AngleJoint joint = new AngleJoint(fA, fB); joint.TargetAngle = (float)Math.PI / 2; World.AddJoint(joint); } //Motor joint { Body body = BodyFactory.CreateRectangle(World, 4, 1, 2, new Vector2(0, 35)); body.BodyType = BodyType.Dynamic; body.Friction = 0.6f; MotorJoint motorJoint = JointFactory.CreateMotorJoint(World, ground, body); motorJoint.MaxForce = 1000.0f; motorJoint.MaxTorque = 1000.0f; motorJoint.LinearOffset = new Vector2(0, 35); motorJoint.AngularOffset = (float)(Math.PI / 3f); } }
/// <summary> /// Orients arms in necessary position /// </summary> private void UpdateArms() { // Update strength of arms based on health leftElbow.MaxImpulse = maxImpulse * health[leftLowerArm] * health[leftUpperArm]; leftShoulder.MaxImpulse = maxImpulse * health[torso] * health[leftUpperArm]; rightElbow.MaxImpulse = maxImpulse * health[rightLowerArm] * health[rightUpperArm]; rightShoulder.MaxImpulse = maxImpulse * health[torso] * health[rightUpperArm]; if (!Aiming && !throwing && !switchingHands) { // Rest arms at side if (weapon == null || weapon.Type == Weapon.WeaponType.Light || weapon.Type == Weapon.WeaponType.Explosive || weapon.Type == Weapon.WeaponType.Melee) { leftShoulder.TargetAngle = FindClosestAngle(3 * MathHelper.PiOver4, torso.Rotation, leftShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(-3 * MathHelper.PiOver4, torso.Rotation, rightShoulder.TargetAngle); leftElbow.TargetAngle = MathHelper.PiOver4; rightElbow.TargetAngle = -MathHelper.PiOver4; } else if (weapon.Type == Weapon.WeaponType.Medium || weapon.Type == Weapon.WeaponType.Heavy) { if (leftHanded) { leftShoulder.TargetAngle = FindClosestAngle(3 * MathHelper.PiOver4, torso.Rotation, leftShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(-3 * MathHelper.PiOver4, torso.Rotation, rightShoulder.TargetAngle); leftElbow.TargetAngle = MathHelper.PiOver2; rightElbow.TargetAngle = -MathHelper.PiOver4; } else { leftShoulder.TargetAngle = FindClosestAngle(3 * MathHelper.PiOver4, torso.Rotation, leftShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(-3 * MathHelper.PiOver4, torso.Rotation, rightShoulder.TargetAngle); leftElbow.TargetAngle = MathHelper.PiOver4; rightElbow.TargetAngle = -MathHelper.PiOver2; } } } else if (Aiming && !throwing) { // Aim weapon in direction float angle = -(float)Math.Atan2(aimVector.Y, aimVector.X); if (weapon == null || weapon.Type == Weapon.WeaponType.Light) { leftShoulder.TargetAngle = FindClosestAngle(angle - MathHelper.PiOver2, torso.Rotation, leftShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(angle - MathHelper.PiOver2, torso.Rotation, rightShoulder.TargetAngle); leftElbow.TargetAngle = 0f; rightElbow.TargetAngle = 0f; } else if (weapon.Type == Weapon.WeaponType.Medium || weapon.Type == Weapon.WeaponType.Heavy) { if (leftHanded) { leftShoulder.TargetAngle = FindClosestAngle(angle - MathHelper.PiOver2, torso.Rotation, leftShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(angle + (angle >= MathHelper.PiOver2 || angle <= -MathHelper.PiOver2 ? -MathHelper.PiOver4 : -3 * MathHelper.PiOver4), torso.Rotation, rightShoulder.TargetAngle); leftElbow.TargetAngle = 0f; rightElbow.TargetAngle = angle >= MathHelper.PiOver2 || angle <= -MathHelper.PiOver2 ? -MathHelper.PiOver2 : MathHelper.PiOver2; } else { leftShoulder.TargetAngle = FindClosestAngle(angle + (angle >= MathHelper.PiOver2 || angle <= -MathHelper.PiOver2 ? -MathHelper.PiOver4 : -3 * MathHelper.PiOver4), torso.Rotation, rightShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(angle - MathHelper.PiOver2, torso.Rotation, leftShoulder.TargetAngle); leftElbow.TargetAngle = angle >= MathHelper.PiOver2 || angle <= -MathHelper.PiOver2 ? -MathHelper.PiOver2 : MathHelper.PiOver2; rightElbow.TargetAngle = 0f; } } else if (weapon.Type == Weapon.WeaponType.Explosive || weapon.Type == Weapon.WeaponType.Melee) { if (leftHanded) { leftShoulder.TargetAngle = FindClosestAngle(angle + (angle >= MathHelper.PiOver2 || angle <= -MathHelper.PiOver2 ? MathHelper.Pi : 0), torso.Rotation, leftShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(angle - MathHelper.PiOver2, torso.Rotation, rightShoulder.TargetAngle); leftElbow.TargetAngle = 0f; rightElbow.TargetAngle = 0f; } else { leftShoulder.TargetAngle = FindClosestAngle(angle - MathHelper.PiOver2, torso.Rotation, rightShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(angle + (angle >= MathHelper.PiOver2 || angle <= -MathHelper.PiOver2 ? MathHelper.Pi : 0), torso.Rotation, leftShoulder.TargetAngle); leftElbow.TargetAngle = 0f; rightElbow.TargetAngle = 0f; } } Aiming = false; } else if (throwing) { // Throw weapon leftShoulder.TargetAngle = FindClosestAngle(-(float)Math.Atan2(aimVector.Y, aimVector.X) - MathHelper.PiOver2, torso.Rotation, leftShoulder.TargetAngle); rightShoulder.TargetAngle = FindClosestAngle(-(float)Math.Atan2(aimVector.Y, aimVector.X) - MathHelper.PiOver2, torso.Rotation, rightShoulder.TargetAngle); leftElbow.TargetAngle = 0f; rightElbow.TargetAngle = 0f; if (weapon != null) { if (world.JointList.Contains(weaponJoint)) world.RemoveJoint(weaponJoint); if (world.JointList.Contains(r_weaponJoint)) world.RemoveJoint(r_weaponJoint); weapon.BeingHeld = false; weapon.Body.LinearVelocity = aimVector / aimVector.Length() * 10f + this.torso.LinearVelocity; this.weapon = null; } AngleJoint[] joints = new AngleJoint[] { leftShoulder, leftElbow, rightShoulder, rightElbow }; if (JointsAreInPosition(joints)) throwing = false; } else if (switchingHands) { if (weapon != null) { if (leftHanded) { // If you don't have a right hand to switch to, cancel the action if (health[rightLowerArm] <= 0) switchingHands = false; else { // Move left hand to right position leftShoulder.TargetAngle = FindClosestAngle(0f, rightShoulder.TargetAngle, 0f); leftElbow.TargetAngle = rightElbow.TargetAngle; AngleJoint[] joints = new AngleJoint[] { leftShoulder, leftElbow }; if (JointsAreInPosition(joints) || (LeftHandPosition - RightHandPosition).Length() < 0.1f) { if (world.JointList.Contains(weaponJoint)) world.RemoveJoint(weaponJoint); if (world.JointList.Contains(r_weaponJoint)) world.RemoveJoint(r_weaponJoint); leftHanded = false; this.weapon.Position = RightHandPosition; r_weaponJoint = JointFactory.CreateRevoluteJoint(world, rightLowerArm, this.weapon.Body, Vector2.Zero); weaponJoint = JointFactory.CreateAngleJoint(world, rightLowerArm, this.weapon.Body); float angle = weapon.Body.Rotation - rightLowerArm.Rotation; weaponJoint.TargetAngle = (int)(angle / MathHelper.TwoPi) * MathHelper.TwoPi; weaponJoint.CollideConnected = false; weaponJoint.MaxImpulse = 100f; switchingHands = false; } } } else { // If you don't have a left hand to switch to, cancel the action if (health[leftLowerArm] <= 0) switchingHands = false; else { // Move right hand to left hand position rightShoulder.TargetAngle = FindClosestAngle(0f, leftShoulder.TargetAngle, 0f); rightElbow.TargetAngle = leftElbow.TargetAngle; AngleJoint[] joints = new AngleJoint[] { rightShoulder, rightElbow }; if (JointsAreInPosition(joints) || (LeftHandPosition - RightHandPosition).Length() < 0.1f) { if (world.JointList.Contains(weaponJoint)) world.RemoveJoint(weaponJoint); if (world.JointList.Contains(r_weaponJoint)) world.RemoveJoint(r_weaponJoint); leftHanded = true; this.weapon.Position = LeftHandPosition; r_weaponJoint = JointFactory.CreateRevoluteJoint(world, leftLowerArm, this.weapon.Body, Vector2.Zero); weaponJoint = JointFactory.CreateAngleJoint(world, leftLowerArm, this.weapon.Body); float angle = weapon.Body.Rotation - leftLowerArm.Rotation; weaponJoint.TargetAngle = (int)(angle / MathHelper.TwoPi) * MathHelper.TwoPi; weaponJoint.CollideConnected = false; weaponJoint.MaxImpulse = 100f; switchingHands = false; } } } } else switchingHands = false; } }
/// <summary> /// Checks if all the joints in a list are close to their target angle /// </summary> /// <param name="joints">The array of joints to check</param> /// <returns>True if the joints are at their target angles, false if not</returns> private bool JointsAreInPosition(AngleJoint[] joints) { foreach (AngleJoint j in joints) { if (Math.Abs(j.BodyB.Rotation - j.BodyA.Rotation - j.TargetAngle) > 0.20) return false; } return true; }
/// <summary> /// Connects the figure's body parts /// </summary> /// <param name="world">The physics world to add the joints to</param> protected void ConnectBody(World world) { upright = JointFactory.CreateAngleJoint(world, torso, gyro); upright.MaxImpulse = maxImpulse; upright.TargetAngle = 0.0f; upright.CollideConnected = false; r_neck = JointFactory.CreateRevoluteJoint(world, head, torso, -Vector2.UnitY * 20 * MainGame.PIXEL_TO_METER); neck = JointFactory.CreateAngleJoint(world, head, torso); neck.CollideConnected = false; neck.MaxImpulse = maxImpulse; r_leftShoulder = JointFactory.CreateRevoluteJoint(world, leftUpperArm, torso, -Vector2.UnitY * 15 * MainGame.PIXEL_TO_METER); leftShoulder = JointFactory.CreateAngleJoint(world, leftUpperArm, torso); leftShoulder.CollideConnected = false; leftShoulder.MaxImpulse = maxImpulse; r_rightShoulder = JointFactory.CreateRevoluteJoint(world, rightUpperArm, torso, -Vector2.UnitY * 15 * MainGame.PIXEL_TO_METER); rightShoulder = JointFactory.CreateAngleJoint(world, rightUpperArm, torso); rightShoulder.CollideConnected = false; rightShoulder.MaxImpulse = maxImpulse; r_leftElbow = JointFactory.CreateRevoluteJoint(world, leftLowerArm, leftUpperArm, -Vector2.UnitY * 7.5f * MainGame.PIXEL_TO_METER); leftElbow = JointFactory.CreateAngleJoint(world, leftLowerArm, leftUpperArm); leftElbow.CollideConnected = false; leftElbow.MaxImpulse = maxImpulse; r_rightElbow = JointFactory.CreateRevoluteJoint(world, rightLowerArm, rightUpperArm, -Vector2.UnitY * 7.5f * MainGame.PIXEL_TO_METER); rightElbow = JointFactory.CreateAngleJoint(world, rightLowerArm, rightUpperArm); rightElbow.CollideConnected = false; rightElbow.MaxImpulse = maxImpulse; r_leftHip = JointFactory.CreateRevoluteJoint(world, leftUpperLeg, torso, Vector2.UnitY * 15 * MainGame.PIXEL_TO_METER); leftHip = JointFactory.CreateAngleJoint(world, leftUpperLeg, torso); leftHip.CollideConnected = false; leftHip.MaxImpulse = maxImpulse; r_rightHip = JointFactory.CreateRevoluteJoint(world, rightUpperLeg, torso, Vector2.UnitY * 15 * MainGame.PIXEL_TO_METER); rightHip = JointFactory.CreateAngleJoint(world, rightUpperLeg, torso); rightHip.CollideConnected = false; rightHip.MaxImpulse = maxImpulse; r_leftKnee = JointFactory.CreateRevoluteJoint(world, leftLowerLeg, leftUpperLeg, -Vector2.UnitY * 7.5f * MainGame.PIXEL_TO_METER); leftKnee = JointFactory.CreateAngleJoint(world, leftUpperLeg, leftLowerLeg); leftKnee.CollideConnected = false; leftKnee.MaxImpulse = maxImpulse; r_rightKnee = JointFactory.CreateRevoluteJoint(world, rightLowerLeg, rightUpperLeg, -Vector2.UnitY * 7.5f * MainGame.PIXEL_TO_METER); rightKnee = JointFactory.CreateAngleJoint(world, rightUpperLeg, rightLowerLeg); rightKnee.CollideConnected = false; rightKnee.MaxImpulse = maxImpulse; }
public void Deserialize(World world, Stream stream) { world.Clear(); XMLFragmentElement root = XMLFragmentParser.LoadFromStream(stream); if (root.Name.ToLower() != "world") throw new Exception(); foreach (XMLFragmentElement main in root.Elements) { if (main.Name.ToLower() == "gravity") { world.Gravity = ReadVector(main); } } foreach (XMLFragmentElement shapeElement in root.Elements) { if (shapeElement.Name.ToLower() == "shapes") { foreach (XMLFragmentElement n in shapeElement.Elements) { if (n.Name.ToLower() != "shape") throw new Exception(); ShapeType type = (ShapeType)Enum.Parse(typeof(ShapeType), n.Attributes[0].Value, true); switch (type) { case ShapeType.Circle: { CircleShape shape = new CircleShape(); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "radius": shape.Radius = float.Parse(sn.Value); break; case "position": shape.Position = ReadVector(sn); break; default: throw new Exception(); } } _shapes.Add(shape); } break; case ShapeType.Polygon: { PolygonShape shape = new PolygonShape(); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "vertices": { List<Vector2> verts = new List<Vector2>(); foreach (XMLFragmentElement vert in sn.Elements) verts.Add(ReadVector(vert)); shape.Set(new Vertices(verts.ToArray())); } break; case "centroid": shape.MassData.Centroid = ReadVector(sn); break; } } _shapes.Add(shape); } break; case ShapeType.Edge: { EdgeShape shape = new EdgeShape(); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "hasvertex0": shape.HasVertex0 = bool.Parse(sn.Value); break; case "hasvertex3": shape.HasVertex0 = bool.Parse(sn.Value); break; case "vertex0": shape.Vertex0 = ReadVector(sn); break; case "vertex1": shape.Vertex1 = ReadVector(sn); break; case "vertex2": shape.Vertex2 = ReadVector(sn); break; case "vertex3": shape.Vertex3 = ReadVector(sn); break; default: throw new Exception(); } } _shapes.Add(shape); } break; } } } } foreach (XMLFragmentElement fixtureElement in root.Elements) { if (fixtureElement.Name.ToLower() == "fixtures") { foreach (XMLFragmentElement n in fixtureElement.Elements) { Fixture fixture = new Fixture(); if (n.Name.ToLower() != "fixture") throw new Exception(); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "shape": fixture.Shape = _shapes[int.Parse(sn.Value)]; break; case "density": fixture.Shape.Density = float.Parse(sn.Value); break; case "filterdata": foreach (XMLFragmentElement ssn in sn.Elements) { switch (ssn.Name.ToLower()) { case "categorybits": fixture._collisionCategories = (Category)int.Parse(ssn.Value); break; case "maskbits": fixture._collidesWith = (Category)int.Parse(ssn.Value); break; case "groupindex": fixture._collisionGroup = short.Parse(ssn.Value); break; } } break; case "friction": fixture.Friction = float.Parse(sn.Value); break; case "issensor": fixture.IsSensor = bool.Parse(sn.Value); break; case "restitution": fixture.Restitution = float.Parse(sn.Value); break; case "userdata": fixture.UserData = ReadSimpleType(sn, null, false); break; } } _fixtures.Add(fixture); } } } foreach (XMLFragmentElement bodyElement in root.Elements) { if (bodyElement.Name.ToLower() == "bodies") { foreach (XMLFragmentElement n in bodyElement.Elements) { Body body = new Body(world); if (n.Name.ToLower() != "body") throw new Exception(); body.BodyType = (BodyType)Enum.Parse(typeof(BodyType), n.Attributes[0].Value, true); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "active": if (bool.Parse(sn.Value)) body.Flags |= BodyFlags.Enabled; else body.Flags &= ~BodyFlags.Enabled; break; case "allowsleep": body.SleepingAllowed = bool.Parse(sn.Value); break; case "angle": { Vector2 position = body.Position; body.SetTransformIgnoreContacts(ref position, float.Parse(sn.Value)); } break; case "angulardamping": body.AngularDamping = float.Parse(sn.Value); break; case "angularvelocity": body.AngularVelocity = float.Parse(sn.Value); break; case "awake": body.Awake = bool.Parse(sn.Value); break; case "bullet": body.IsBullet = bool.Parse(sn.Value); break; case "fixedrotation": body.FixedRotation = bool.Parse(sn.Value); break; case "lineardamping": body.LinearDamping = float.Parse(sn.Value); break; case "linearvelocity": body.LinearVelocity = ReadVector(sn); break; case "position": { float rotation = body.Rotation; Vector2 position = ReadVector(sn); body.SetTransformIgnoreContacts(ref position, rotation); } break; case "userdata": body.UserData = ReadSimpleType(sn, null, false); break; case "fixtures": { foreach (XMLFragmentElement v in sn.Elements) { Fixture blueprint = _fixtures[int.Parse(v.Value)]; Fixture f = new Fixture(body, blueprint.Shape, blueprint.CollisionCategories); f.Restitution = blueprint.Restitution; f.UserData = blueprint.UserData; f.Friction = blueprint.Friction; f.CollidesWith = blueprint.CollidesWith; f.CollisionGroup = blueprint.CollisionGroup; } break; } } } _bodies.Add(body); } } } foreach (XMLFragmentElement jointElement in root.Elements) { if (jointElement.Name.ToLower() == "joints") { foreach (XMLFragmentElement n in jointElement.Elements) { Joint joint; if (n.Name.ToLower() != "joint") throw new Exception(); JointType type = (JointType)Enum.Parse(typeof(JointType), n.Attributes[0].Value, true); int bodyAIndex = -1, bodyBIndex = -1; bool collideConnected = false; object userData = null; foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "bodya": bodyAIndex = int.Parse(sn.Value); break; case "bodyb": bodyBIndex = int.Parse(sn.Value); break; case "collideconnected": collideConnected = bool.Parse(sn.Value); break; case "userdata": userData = ReadSimpleType(sn, null, false); break; } } Body bodyA = _bodies[bodyAIndex]; Body bodyB = _bodies[bodyBIndex]; switch (type) { case JointType.Distance: joint = new DistanceJoint(); break; case JointType.Friction: joint = new FrictionJoint(); break; case JointType.Line: joint = new LineJoint(); break; case JointType.Prismatic: joint = new PrismaticJoint(); break; case JointType.Pulley: joint = new PulleyJoint(); break; case JointType.Revolute: joint = new RevoluteJoint(); break; case JointType.Weld: joint = new WeldJoint(); break; case JointType.Rope: joint = new RopeJoint(); break; case JointType.Angle: joint = new AngleJoint(); break; case JointType.Slider: joint = new SliderJoint(); break; case JointType.Gear: throw new Exception("GearJoint is not supported."); default: throw new Exception("Invalid or unsupported joint."); } joint.CollideConnected = collideConnected; joint.UserData = userData; joint.BodyA = bodyA; joint.BodyB = bodyB; _joints.Add(joint); world.AddJoint(joint); foreach (XMLFragmentElement sn in n.Elements) { // check for specific nodes switch (type) { case JointType.Distance: { switch (sn.Name.ToLower()) { case "dampingratio": ((DistanceJoint)joint).DampingRatio = float.Parse(sn.Value); break; case "frequencyhz": ((DistanceJoint)joint).Frequency = float.Parse(sn.Value); break; case "length": ((DistanceJoint)joint).Length = float.Parse(sn.Value); break; case "localanchora": ((DistanceJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((DistanceJoint)joint).LocalAnchorB = ReadVector(sn); break; } } break; case JointType.Friction: { switch (sn.Name.ToLower()) { case "localanchora": ((FrictionJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((FrictionJoint)joint).LocalAnchorB = ReadVector(sn); break; case "maxforce": ((FrictionJoint)joint).MaxForce = float.Parse(sn.Value); break; case "maxtorque": ((FrictionJoint)joint).MaxTorque = float.Parse(sn.Value); break; } } break; case JointType.Line: { switch (sn.Name.ToLower()) { case "enablemotor": ((LineJoint)joint).MotorEnabled = bool.Parse(sn.Value); break; case "localanchora": ((LineJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((LineJoint)joint).LocalAnchorB = ReadVector(sn); break; case "motorspeed": ((LineJoint)joint).MotorSpeed = float.Parse(sn.Value); break; case "dampingratio": ((LineJoint)joint).DampingRatio = float.Parse(sn.Value); break; case "maxmotortorque": ((LineJoint)joint).MaxMotorTorque = float.Parse(sn.Value); break; case "frequencyhz": ((LineJoint)joint).Frequency = float.Parse(sn.Value); break; case "localxaxis": ((LineJoint)joint).LocalXAxis = ReadVector(sn); break; } } break; case JointType.Prismatic: { switch (sn.Name.ToLower()) { case "enablelimit": ((PrismaticJoint)joint).LimitEnabled = bool.Parse(sn.Value); break; case "enablemotor": ((PrismaticJoint)joint).MotorEnabled = bool.Parse(sn.Value); break; case "localanchora": ((PrismaticJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((PrismaticJoint)joint).LocalAnchorB = ReadVector(sn); break; case "local1axis1": ((PrismaticJoint)joint).LocalXAxis1 = ReadVector(sn); break; case "maxmotorforce": ((PrismaticJoint)joint).MaxMotorForce = float.Parse(sn.Value); break; case "motorspeed": ((PrismaticJoint)joint).MotorSpeed = float.Parse(sn.Value); break; case "lowertranslation": ((PrismaticJoint)joint).LowerLimit = float.Parse(sn.Value); break; case "uppertranslation": ((PrismaticJoint)joint).UpperLimit = float.Parse(sn.Value); break; case "referenceangle": ((PrismaticJoint)joint).ReferenceAngle = float.Parse(sn.Value); break; } } break; case JointType.Pulley: { switch (sn.Name.ToLower()) { case "groundanchora": ((PulleyJoint)joint).GroundAnchorA = ReadVector(sn); break; case "groundanchorb": ((PulleyJoint)joint).GroundAnchorB = ReadVector(sn); break; case "lengtha": ((PulleyJoint)joint).LengthA = float.Parse(sn.Value); break; case "lengthb": ((PulleyJoint)joint).LengthB = float.Parse(sn.Value); break; case "localanchora": ((PulleyJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((PulleyJoint)joint).LocalAnchorB = ReadVector(sn); break; case "maxlengtha": ((PulleyJoint)joint).MaxLengthA = float.Parse(sn.Value); break; case "maxlengthb": ((PulleyJoint)joint).MaxLengthB = float.Parse(sn.Value); break; case "ratio": ((PulleyJoint)joint).Ratio = float.Parse(sn.Value); break; } } break; case JointType.Revolute: { switch (sn.Name.ToLower()) { case "enablelimit": ((RevoluteJoint)joint).LimitEnabled = bool.Parse(sn.Value); break; case "enablemotor": ((RevoluteJoint)joint).MotorEnabled = bool.Parse(sn.Value); break; case "localanchora": ((RevoluteJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((RevoluteJoint)joint).LocalAnchorB = ReadVector(sn); break; case "maxmotortorque": ((RevoluteJoint)joint).MaxMotorTorque = float.Parse(sn.Value); break; case "motorspeed": ((RevoluteJoint)joint).MotorSpeed = float.Parse(sn.Value); break; case "lowerangle": ((RevoluteJoint)joint).LowerLimit = float.Parse(sn.Value); break; case "upperangle": ((RevoluteJoint)joint).UpperLimit = float.Parse(sn.Value); break; case "referenceangle": ((RevoluteJoint)joint).ReferenceAngle = float.Parse(sn.Value); break; } } break; case JointType.Weld: { switch (sn.Name.ToLower()) { case "localanchora": ((WeldJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((WeldJoint)joint).LocalAnchorB = ReadVector(sn); break; } } break; case JointType.Rope: { switch (sn.Name.ToLower()) { case "localanchora": ((RopeJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((RopeJoint)joint).LocalAnchorB = ReadVector(sn); break; case "maxlength": ((RopeJoint)joint).MaxLength = float.Parse(sn.Value); break; } } break; case JointType.Gear: throw new Exception("Gear joint is unsupported"); case JointType.Angle: { switch (sn.Name.ToLower()) { case "biasfactor": ((AngleJoint)joint).BiasFactor = float.Parse(sn.Value); break; case "maximpulse": ((AngleJoint)joint).MaxImpulse = float.Parse(sn.Value); break; case "softness": ((AngleJoint)joint).Softness = float.Parse(sn.Value); break; case "targetangle": ((AngleJoint)joint).TargetAngle = float.Parse(sn.Value); break; } } break; case JointType.Slider: { switch (sn.Name.ToLower()) { case "dampingratio": ((SliderJoint)joint).DampingRatio = float.Parse(sn.Value); break; case "frequencyhz": ((SliderJoint)joint).Frequency = float.Parse(sn.Value); break; case "maxlength": ((SliderJoint)joint).MaxLength = float.Parse(sn.Value); break; case "minlength": ((SliderJoint)joint).MinLength = float.Parse(sn.Value); break; case "localanchora": ((SliderJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((SliderJoint)joint).LocalAnchorB = ReadVector(sn); break; } } break; } } } } } }
/// <summary> /// Picks up the weapon /// </summary> /// <param name="w"></param> public void PickUpWeapon(Weapon w) { if (!w.BeingHeld && weapon == null && touchingWeapons.Contains(w)) { if (health[leftLowerArm] == 0 && health[rightLowerArm] == 0) return; this.weapon = w; this.weapon.PickUp(collisionCat); float angle; if (health[leftLowerArm] >= health[rightLowerArm]) { this.weapon.Position = LeftHandPosition; r_weaponJoint = JointFactory.CreateRevoluteJoint(world, leftLowerArm, this.weapon.Body, Vector2.Zero); weaponJoint = JointFactory.CreateAngleJoint(world, leftLowerArm, this.weapon.Body); leftHanded = true; angle = weapon.Body.Rotation - leftLowerArm.Rotation; } else { this.weapon.Position = RightHandPosition; r_weaponJoint = JointFactory.CreateRevoluteJoint(world, rightLowerArm, this.weapon.Body, Vector2.Zero); weaponJoint = JointFactory.CreateAngleJoint(world, rightLowerArm, this.weapon.Body); leftHanded = false; angle = weapon.Body.Rotation - rightLowerArm.Rotation; } weaponJoint.TargetAngle = (int)(angle / MathHelper.TwoPi) * MathHelper.TwoPi; weaponJoint.CollideConnected = false; weaponJoint.MaxImpulse = 100f; } }
/// <summary> /// Makes figure walk the the right (place in Update method) /// </summary> public void WalkRight() { upright.TargetAngle = -0.1f; if (torso.LinearVelocity.X < (onGround ? 4 : 3) * GetTotalLegStrength() && !(Crouching && onGround)) torso.ApplyForce(new Vector2(150, 0) * maxImpulse * health[torso] * health[head] * GetTotalLegStrength()); // Change limb dependency AngleJoint[] checkThese = new AngleJoint[] { leftHip, rightHip }; if (walkStage == 0) { leftHip.TargetAngle = (float)Math.PI - torso.Rotation; leftKnee.TargetAngle = -MathHelper.PiOver2 - torso.Rotation; rightHip.TargetAngle = -3 * MathHelper.PiOver4 - torso.Rotation; rightKnee.TargetAngle = -3 * MathHelper.PiOver4 - torso.Rotation; rightKnee.MaxImpulse = maxImpulse * 3 * health[rightLowerLeg] * health[rightUpperLeg]; leftLowerLeg.Friction = 0.0f; rightLowerLeg.Friction = 1000f; if (JointsAreInPosition(checkThese)) walkStage = 1; } else if (walkStage == 1) { leftHip.TargetAngle = 3 * MathHelper.PiOver2 - torso.Rotation; leftKnee.TargetAngle = -MathHelper.PiOver2 - torso.Rotation; rightHip.TargetAngle = -5 * MathHelper.PiOver4 - torso.Rotation; rightKnee.TargetAngle = -(float)Math.PI - torso.Rotation; rightKnee.MaxImpulse = maxImpulse * health[rightLowerLeg] * health[rightUpperLeg]; if (JointsAreInPosition(checkThese)) walkStage = 2; } else if (walkStage == 2) { leftHip.TargetAngle = 5 * MathHelper.PiOver4 - torso.Rotation; leftKnee.TargetAngle = -3 * MathHelper.PiOver4 - torso.Rotation; leftKnee.MaxImpulse = maxImpulse * 3 * health[leftLowerLeg] * health[leftUpperLeg]; rightHip.TargetAngle = -(float)Math.PI - torso.Rotation; rightKnee.TargetAngle = -MathHelper.PiOver2 - torso.Rotation; rightLowerLeg.Friction = 0.0f; leftLowerLeg.Friction = 1000f; if (JointsAreInPosition(checkThese)) walkStage = 3; } else if (walkStage == 3) { leftHip.TargetAngle = 3 * MathHelper.PiOver4 - torso.Rotation; leftKnee.TargetAngle = -(float)Math.PI - torso.Rotation; leftKnee.MaxImpulse = maxImpulse * health[leftLowerLeg] * health[leftUpperLeg]; rightHip.TargetAngle = -MathHelper.PiOver2 - torso.Rotation; rightKnee.TargetAngle = -MathHelper.PiOver2 - torso.Rotation; if (JointsAreInPosition(checkThese)) walkStage = 0; } }
private Vector2 _upperLegSize = new Vector2(3, 0.5f); //x=width, y=height public Spider(World world, Vector2 position) { DebugMaterial matHead = new DebugMaterial(MaterialType.Face) { Color = Color.ForestGreen, Scale = 2f }; DebugMaterial matBody = new DebugMaterial(MaterialType.Blank) { Color = Color.YellowGreen }; DebugMaterial matLeg = new DebugMaterial(MaterialType.Blank) { Color = Color.DarkGreen }; //Load bodies Fixture circle = FixtureFactory.CreateCircle(world, SpiderBodyRadius, 0.1f, position, matHead); circle.Body.BodyType = BodyType.Dynamic; //Left upper leg Fixture leftUpper = FixtureFactory.CreateRectangle(world, _upperLegSize.X, _upperLegSize.Y, 0.1f, circle.Body.Position - new Vector2(SpiderBodyRadius, 0) - new Vector2(_upperLegSize.X/2, 0), matBody); leftUpper.Body.BodyType = BodyType.Dynamic; //Left lower leg Fixture leftLower = FixtureFactory.CreateRectangle(world, _lowerLegSize.X, _lowerLegSize.Y, 0.1f, circle.Body.Position - new Vector2(SpiderBodyRadius, 0) - new Vector2(_upperLegSize.X, 0) - new Vector2(_lowerLegSize.X/2, 0), matLeg); leftLower.Body.BodyType = BodyType.Dynamic; //Right upper leg Fixture rightUpper = FixtureFactory.CreateRectangle(world, _upperLegSize.X, _upperLegSize.Y, 0.1f, circle.Body.Position + new Vector2(SpiderBodyRadius, 0) + new Vector2(_upperLegSize.X/2, 0), matBody); rightUpper.Body.BodyType = BodyType.Dynamic; //Right lower leg Fixture rightLower = FixtureFactory.CreateRectangle(world, _lowerLegSize.X, _lowerLegSize.Y, 0.1f, circle.Body.Position + new Vector2(SpiderBodyRadius, 0) + new Vector2(_upperLegSize.X, 0) + new Vector2(_lowerLegSize.X/2, 0), matLeg); rightLower.Body.BodyType = BodyType.Dynamic; //Create joints JointFactory.CreateRevoluteJoint(world, circle.Body, leftUpper.Body, new Vector2(SpiderBodyRadius, 0)); _leftShoulderAngleJoint = JointFactory.CreateAngleJoint(world, circle.Body, leftUpper.Body); _leftShoulderAngleJoint.MaxImpulse = 3; JointFactory.CreateRevoluteJoint(world, circle.Body, rightUpper.Body, new Vector2(-SpiderBodyRadius, 0)); _rightShoulderAngleJoint = JointFactory.CreateAngleJoint(world, circle.Body, rightUpper.Body); _rightShoulderAngleJoint.MaxImpulse = 3; JointFactory.CreateRevoluteJoint(world, leftUpper.Body, leftLower.Body, new Vector2(_upperLegSize.X/2, 0)); _leftKneeAngleJoint = JointFactory.CreateAngleJoint(world, leftUpper.Body, leftLower.Body); _leftKneeAngleJoint.MaxImpulse = 3; JointFactory.CreateRevoluteJoint(world, rightUpper.Body, rightLower.Body, -new Vector2(_upperLegSize.X/2, 0)); _rightKneeAngleJoint = JointFactory.CreateAngleJoint(world, rightUpper.Body, rightLower.Body); _rightKneeAngleJoint.MaxImpulse = 3; }