//TODO: Comment better /// <summary> /// Moves the body on the path. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="time">The time.</param> /// <param name="strength">The strength.</param> /// <param name="timeStep">The time step.</param> public static void MoveBodyOnPath(Path path, Body body, float time, float strength, float timeStep, bool if_type2 = true) { Vector2 destination = path.GetPosition(time); Vector2 positionDelta = body.Position - destination; if ( positionDelta.Length() != 0 ) positionDelta.Normalize(); // Added for game Vector2 velocity = (positionDelta / timeStep) * strength; Vector2 vel = Math.Min(8,body.LinearVelocity.Length()+3) * -velocity * body.Mass; if (if_type2 && vel.Length() > 1) { float velocity_magnitude_X = Math.Abs(body.LinearVelocity.X); float velocity_magnitude_Y = Math.Abs(body.LinearVelocity.Y); float force_magnitude_X = Math.Abs(vel.X); float force_magnitude_Y = Math.Abs(vel.Y); bool horiz = force_magnitude_X > 2; bool vert = force_magnitude_Y > 2; bool high_vert_low_horiz = (velocity_magnitude_X < velocity_magnitude_Y - 10); bool high_horiz_low_vert = velocity_magnitude_X > velocity_magnitude_Y + 10; if ((horiz) && high_vert_low_horiz) { vel.X *= 2f; vel.Y /= 2f; //body.LinearVelocity = new Vector2(body.LinearVelocity.X,body.LinearVelocity.Y/1.5f); } if (vert && high_horiz_low_vert) { vel.Y *= 2f; vel.X /= 2f; // body.LinearVelocity = new Vector2(body.LinearVelocity.X/1.5f, body.LinearVelocity.Y); } if (Math.Sign(vel.Y) != Math.Sign(body.LinearVelocity.Y)) { vel.Y *= 3; } if (Math.Sign(vel.X) != Math.Sign(body.LinearVelocity.X)) { vel.X *= 3; } body.ApplyForce(vel); } else if(path.GetLength()>0.5f) { body.LinearVelocity = -velocity; } }
private void AddBallAndChain(Body body) { // The chain will be divided into several segments along the following path var chainPath = new Path(); chainPath.Add(ConvertUnits.ToSimUnits(332, 332)); chainPath.Add(ConvertUnits.ToSimUnits(332, 452)); // Creates the shape for the chain segments var chainLinkShape = new PolygonShape(PolygonTools.CreateRectangle(ConvertUnits.ToSimUnits(1), ConvertUnits.ToSimUnits(2)), 0.5f); // Creates the bodies for the chain segments _chainBodies = PathManager.EvenlyDistributeShapesAlongPath(World, chainPath, new[] {chainLinkShape}, BodyType.Dynamic, 30); // Connects the chain segments for (var i = 0; i < _chainBodies.Count - 1; i++) { var joint = new RevoluteJoint(_chainBodies[i], _chainBodies[i + 1], Vector2.Zero, Vector2.Zero); World.AddJoint(joint); } // Connects the start of the chain to the ufo var chainStartJoint = new RevoluteJoint(body, _chainBodies.First(), ConvertUnits.ToSimUnits(0, 25), Vector2.Zero); World.AddJoint(chainStartJoint); // Creates the ball at the end of the chain _chainEndBall = BodyFactory.CreateCircle(World, ConvertUnits.ToSimUnits(10), 3f, bodyType: BodyType.Dynamic); _chainEndBall.Position = ConvertUnits.ToSimUnits(332, 452); _chainEndBall.OnCollision += ChainBallOnCollision; // Adds the ball to the chain var chainEndJoint = new RevoluteJoint(_chainBodies.Last(), _chainEndBall, Vector2.Zero, Vector2.Zero); World.AddJoint(chainEndJoint); // Adds a rope join that ensures that the chain won't stretch var ropeJoint = new RopeJoint(body, _chainEndBall, ConvertUnits.ToSimUnits(0, 25), Vector2.Zero) { MaxLength = chainPath.GetLength() }; World.AddJoint(ropeJoint); }