Ejemplo n.º 1
0
        void CreateScene()
        {
            scene = new Scene();
            scene.CreateComponent <Octree>();
            scene.CreateComponent <DebugRenderer>();
            // Create camera node
            CameraNode = scene.CreateChild("Camera");
            // Set camera's position
            CameraNode.Position = (new Vector3(0.0f, 0.0f, -10.0f));

            Camera camera = CameraNode.CreateComponent <Camera>();

            camera.Orthographic = true;

            var graphics = Graphics;

            camera.OrthoSize = (float)graphics.Height * PixelSize;
            camera.Zoom      = 1.2f * Math.Min((float)graphics.Width / 1280.0f, (float)graphics.Height / 800.0f);        // Set zoom according to user's resolution to ensure full visibility (initial zoom (1.2) is set for full visibility at 1280x800 resolution)

            // Create 2D physics world component
            scene.CreateComponent <PhysicsWorld2D>();

            var      cache      = ResourceCache;
            Sprite2D boxSprite  = cache.GetSprite2D("Urho2D/Box.png");
            Sprite2D ballSprite = cache.GetSprite2D("Urho2D/Ball.png");

            // Create ground.
            Node groundNode = scene.CreateChild("Ground");

            groundNode.Position = (new Vector3(0.0f, -3.0f, 0.0f));
            groundNode.Scale    = new Vector3(200.0f, 1.0f, 0.0f);

            // Create 2D rigid body for gound
            /*RigidBody2D groundBody = */
            groundNode.CreateComponent <RigidBody2D>();

            StaticSprite2D groundSprite = groundNode.CreateComponent <StaticSprite2D>();

            groundSprite.Sprite = boxSprite;

            // Create box collider for ground
            CollisionBox2D groundShape = groundNode.CreateComponent <CollisionBox2D>();

            // Set box size
            groundShape.Size = new Vector2(0.32f, 0.32f);
            // Set friction
            groundShape.Friction = 0.5f;

            for (uint i = 0; i < NumObjects; ++i)
            {
                Node node = scene.CreateChild("RigidBody");
                node.Position = (new Vector3(NextRandom(-0.1f, 0.1f), 5.0f + i * 0.4f, 0.0f));

                // Create rigid body
                RigidBody2D body = node.CreateComponent <RigidBody2D>();
                body.BodyType = BodyType2D.Dynamic;
                StaticSprite2D staticSprite = node.CreateComponent <StaticSprite2D>();

                if (i % 2 == 0)
                {
                    staticSprite.Sprite = boxSprite;

                    // Create box
                    CollisionBox2D box = node.CreateComponent <CollisionBox2D>();
                    // Set size
                    box.Size = new Vector2(0.32f, 0.32f);
                    // Set density
                    box.Density = 1.0f;
                    // Set friction
                    box.Friction = 0.5f;
                    // Set restitution
                    box.Restitution = 0.1f;
                }
                else
                {
                    staticSprite.Sprite = ballSprite;

                    // Create circle
                    CollisionCircle2D circle = node.CreateComponent <CollisionCircle2D>();
                    // Set radius
                    circle.Radius = 0.16f;
                    // Set density
                    circle.Density = 1.0f;
                    // Set friction.
                    circle.Friction = 0.5f;
                    // Set restitution
                    circle.Restitution = 0.1f;
                }
            }
        }
Ejemplo n.º 2
0
        public VehicleCreator(Scene scene, Urho.Resources.ResourceCache cache, ScreenInfoRatio screenInfo, Vector2 initPositionHeight)
        {
            _screenInfo             = screenInfo;
            _vehicleVerticalOffset += initPositionHeight.Y;

            // Load vehicle info
            _vehicleModel = VehicleManager.Instance.SelectedVehicleModel;

            var l = _vehicleModel.BodyPosition.Left;
            var t = _vehicleModel.BodyPosition.Top;
            var r = _vehicleModel.BodyPosition.Right;
            var b = _vehicleModel.BodyPosition.Bottom;

            // Get vehicle texture from coordinates
            var sprite = new Sprite2D {
                Texture   = cache.GetTexture2D("Textures/Garage/vehicles_body.png"),
                Rectangle = new IntRect(l, t, r, b)
            };

            // Create vehicle main body reference
            Node box = scene.CreateChild("Box");

            StaticSprite2D boxSprite = box.CreateComponent <StaticSprite2D>();

            boxSprite.Sprite = sprite;

            _mainBody                = box.CreateComponent <RigidBody2D>();
            _mainBody.BodyType       = BodyType2D.Dynamic;
            _mainBody.LinearDamping  = 0.2f;
            _mainBody.AngularDamping = 0.2f;
            _mainBody.Bullet         = true;
            _mainBody.Mass           = 1.0f;
            //_mainBody.SetMassCenter(new Vector2(-2.1f * _screenInfo.XScreenRatio, -0.1f * _screenInfo.YScreenRatio));

            /****************************************/
            /* Outer body for collision - null mass */
            /****************************************/
            float startVX       = -1.2f + _vehicleModel.BalanceBodyOffset[0];
            float startVY       = -0.55f + _vehicleModel.BalanceBodyOffset[1];
            float driverXOffset = 1.0f + _vehicleModel.BalanceBodyOffset[2];

            VehicleObjectPosition = new Vector3(-0.7f * _screenInfo.XScreenRatio, _vehicleVerticalOffset + _vehicleModel.BalanceBodyOffset[1], 3.0f);
            // MAIN BODY BOUNDS
            CollisionChain2D bodyBounds = box.CreateComponent <CollisionChain2D>();

            bodyBounds.VertexCount = 9;
            bodyBounds.SetVertex(0, new Vector2(startVX, startVY)); // BOTTOM LEFT
            bodyBounds.SetVertex(1, new Vector2(startVX, startVY + 0.1f));
            bodyBounds.SetVertex(2, new Vector2(startVX + driverXOffset, startVY + 0.1f));
            bodyBounds.SetVertex(3, new Vector2(startVX + driverXOffset, startVY + 0.2f));
            bodyBounds.SetVertex(4, new Vector2(startVX + driverXOffset + 0.3f, startVY + 0.2f));
            bodyBounds.SetVertex(5, new Vector2(startVX + driverXOffset + 0.3f, startVY + 0.1f));
            bodyBounds.SetVertex(6, new Vector2(startVX + driverXOffset + 0.8f, startVY + 0.1f));
            bodyBounds.SetVertex(7, new Vector2(startVX + driverXOffset + 0.8f, startVY)); // BOTTOM RIGHT
            bodyBounds.SetVertex(8, new Vector2(startVX, startVY));                        // BOTTOM LEFT
            bodyBounds.Friction    = 1.0f;
            bodyBounds.Restitution = 0.0f;

            // BACK BODY BOUND
            CollisionChain2D backBounds = box.CreateComponent <CollisionChain2D>();

            backBounds.VertexCount = 4;
            backBounds.SetVertex(0, new Vector2(startVX, startVY + 0.1f));
            backBounds.SetVertex(1, new Vector2(startVX, startVY + 0.15f));
            backBounds.SetVertex(2, new Vector2(startVX + 0.02f, startVY + 0.15f));
            backBounds.SetVertex(3, new Vector2(startVX + 0.02f, startVY + 0.1f));
            backBounds.SetVertex(4, new Vector2(startVX, startVY + 0.1f));

            backBounds.Friction    = 1.0f;
            backBounds.Restitution = 0.0f;

            // Main body for constraints and mass
            // Create box shape
            CollisionBox2D shape = box.CreateComponent <CollisionBox2D>();

            // Set size
            shape.Size        = new Vector2(0.32f, 0.32f);
            shape.Density     = 8.0f;  // Set shape density (kilograms per meter squared)
            shape.Friction    = 0.8f;  // Set friction
            shape.Restitution = 0.0f;  // Set restitution (no bounce)

            // Update center of collision body - moves center of mass
            shape.SetCenter(-0.2f, -0.65f);

            // Create a vehicle from a compound of 2 ConstraintWheel2Ds
            var car = box;

            //car.Scale = new Vector3(1.5f * _screenInfo.XScreenRatio, 1.5f * _screenInfo.YScreenRatio, 0.0f);

            // DEFINES POSITION OF SPRITE AND MAIN BODY MASS
            car.Position = new Vector3(0.0f * _screenInfo.XScreenRatio, _vehicleVerticalOffset * _screenInfo.YScreenRatio, 1.0f);

            /*****************/
            /* DEFINE WHEELS */
            /*****************/

            var wheelSprites = new List <Sprite2D>();

            foreach (var w in _vehicleModel.WheelsPosition)
            {
                wheelSprites.Add(new Sprite2D {
                    Texture   = cache.GetTexture2D("Textures/Garage/vehicles_wheels.png"),
                    Rectangle = new IntRect(w.Left, w.Top, w.Right, w.Bottom)
                });
            }
            // Create a ball (will be cloned later)
            Node           ball1WheelNode = scene.CreateChild("Wheel");
            StaticSprite2D ballSprite     = ball1WheelNode.CreateComponent <StaticSprite2D>();

            ballSprite.Sprite    = wheelSprites[0];
            ball1WheelNode.Scale = new Vector3(_vehicleModel.WheelsSize[0], _vehicleModel.WheelsSize[0], 1.0f);

            RigidBody2D ballBody = ball1WheelNode.CreateComponent <RigidBody2D>();

            ballBody.BodyType       = BodyType2D.Dynamic;
            ballBody.LinearDamping  = 0.1f;
            ballBody.AngularDamping = 0.1f;
            ballBody.Bullet         = true;
            ballBody.Mass           = 2.0f;

            // WHEEL COLLISION
            CollisionCircle2D ballShape = ball1WheelNode.CreateComponent <CollisionCircle2D>(); // Create circle shape

            ballShape.Radius      = 0.14f;                                                      // * _vehicleModel.WheelsSize[0]; // Set radius
            ballShape.Density     = 2.0f;                                                       // Set shape density (kilograms per meter squared)
            ballShape.Friction    = (_vehicleModel.Wheel / 2) / 10.0f;                          // Set friction: 1.0 = max friction
            ballShape.Restitution = (20 - _vehicleModel.Suspensions) / 2 / 10.0f;               // Set restitution: make it bounce: 0.0 = no bounce

            // CLONE AND POSITION WHEELS

            for (var i = 0; i < _vehicleModel.WheelsBodyPosition.Count; i++)
            {
                if (i == 0)
                {
                    float x1 = _vehicleModel.WheelsBodyPosition[i].X % _vehicleImgPos;
                    float y1 = _vehicleModel.WheelsBodyPosition[i].Y % _vehicleImgPos;
                    x1 = x1 >= _vehicleImgPos / 2 ? (x1 - _vehicleImgPos / 2) * Application.PixelSize : -(_vehicleImgPos / 2 - x1) * Application.PixelSize;
                    y1 = (_vehicleImgPos / 2 - y1) * Application.PixelSize;

                    // WHEEL POSITION - NEEDS TO BE SET RELATIVE TO MAIN BODY
                    ball1WheelNode.Position = new Vector3(x1, y1 + (_vehicleVerticalOffset - 0.05f) * _screenInfo.YScreenRatio, 1.0f);

                    // SET BACK WHEEL CONSTRAINT COMPONENTS
                    var constraintWheel = car.CreateComponent <ConstraintWheel2D>();
                    constraintWheel.OtherBody      = ball1WheelNode.GetComponent <RigidBody2D>();
                    constraintWheel.Anchor         = ball1WheelNode.Position2D;
                    constraintWheel.Axis           = new Vector2(0.0f, 1.0f);
                    constraintWheel.MaxMotorTorque = 150.0f;
                    constraintWheel.FrequencyHz    = 15.0f;
                    constraintWheel.DampingRatio   = 10.0f;
                    constraintWheel.MotorSpeed     = 0.0f;
                    _wheelsConstraints.Add(constraintWheel);
                }
                else
                {
                    Node           newWheelNode  = ball1WheelNode.Clone(CreateMode.Replicated);
                    StaticSprite2D newBallSprite = newWheelNode.CreateComponent <StaticSprite2D>();
                    newBallSprite.Sprite = wheelSprites.Count > i ? wheelSprites[i] : wheelSprites.Last();

                    float x2 = _vehicleModel.WheelsBodyPosition[i].X % _vehicleImgPos;
                    float y2 = _vehicleModel.WheelsBodyPosition[i].Y % _vehicleImgPos;
                    x2 = x2 >= _vehicleImgPos / 2 ? (x2 - _vehicleImgPos / 2) * Application.PixelSize : -(_vehicleImgPos / 2 - x2) * Application.PixelSize;
                    y2 = (_vehicleImgPos / 2 - y2) * Application.PixelSize;

                    // Update collision shape
                    CollisionCircle2D collisionShape = newWheelNode.GetComponent <CollisionCircle2D>(); // Create circle shape
                    collisionShape.Radius = 0.14f;                                                      // * _vehicleModel.WheelsSize[i];
                    // WHEEL POSITION - NEEDS TO BE SET RELATIVE TO MAIN BODY
                    newWheelNode.Scale    = new Vector3(_vehicleModel.WheelsSize[i], _vehicleModel.WheelsSize[i], 1.0f);
                    newWheelNode.Position = new Vector3(x2, y2 + (_vehicleVerticalOffset - 0.05f) * _screenInfo.YScreenRatio, 1.0f);

                    // SET FRONT WHEEL CONSTRAINT COMPONENTS
                    var constraintWheel = car.CreateComponent <ConstraintWheel2D>();
                    constraintWheel.OtherBody      = newWheelNode.GetComponent <RigidBody2D>();
                    constraintWheel.Anchor         = newWheelNode.Position2D;
                    constraintWheel.Axis           = new Vector2(0.0f, 1.0f);
                    constraintWheel.MaxMotorTorque = 150.0f;
                    constraintWheel.FrequencyHz    = 15.0f;
                    constraintWheel.DampingRatio   = 10.0f;
                    constraintWheel.MotorSpeed     = 0.0f;
                    _wheelsConstraints.Add(constraintWheel);
                }
            }
        }
        void CreateScene()
        {
            scene = new Scene();
            scene.CreateComponent <Octree>();
            scene.CreateComponent <DebugRenderer>();
            PhysicsWorld2D physicsWorld = scene.CreateComponent <PhysicsWorld2D>(); // Create 2D physics world component

            physicsWorld.DrawJoint = true;                                          // Display the joints (Note that DrawDebugGeometry() must be set to true to acually draw the joints)
            drawDebug = true;                                                       // Set DrawDebugGeometry() to true

            // Create camera
            CameraNode = scene.CreateChild("Camera");
            // Set camera's position
            CameraNode.Position = (new Vector3(0.0f, 0.0f, 0.0f)); // Note that Z setting is discarded; use camera.zoom instead (see MoveCamera() below for example)

            camera = CameraNode.CreateComponent <Camera>();
            camera.Orthographic = true;

            var graphics = Graphics;

            camera.OrthoSize = (float)graphics.Height * PixelSize;
            camera.Zoom      = 1.2f * Math.Min((float)graphics.Width / 1280.0f, (float)graphics.Height / 800.0f); // Set zoom according to user's resolution to ensure full visibility (initial zoom (1.2) is set for full visibility at 1280x800 resolution)

            // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen
            Viewport viewport = new Viewport(Context, scene, camera, null);
            Renderer renderer = Renderer;

            renderer.SetViewport(0, viewport);

            Zone zone = renderer.DefaultZone;

            zone.FogColor = (new Color(0.1f, 0.1f, 0.1f)); // Set background color for the scene

            // Create 4x3 grid
            for (uint i = 0; i < 5; ++i)
            {
                Node        edgeNode = scene.CreateChild("VerticalEdge");
                RigidBody2D edgeBody = edgeNode.CreateComponent <RigidBody2D>();
                if (dummyBody == null)
                {
                    dummyBody = edgeBody; // Mark first edge as dummy body (used by mouse pick)
                }
                CollisionEdge2D edgeShape = edgeNode.CreateComponent <CollisionEdge2D>();
                edgeShape.SetVertices(new Vector2(i * 2.5f - 5.0f, -3.0f), new Vector2(i * 2.5f - 5.0f, 3.0f));
                edgeShape.Friction = 0.5f; // Set friction
            }

            for (uint j = 0; j < 4; ++j)
            {
                Node edgeNode = scene.CreateChild("HorizontalEdge");
                /*RigidBody2D edgeBody = */
                edgeNode.CreateComponent <RigidBody2D>();
                CollisionEdge2D edgeShape = edgeNode.CreateComponent <CollisionEdge2D>();
                edgeShape.SetVertices(new Vector2(-5.0f, j * 2.0f - 3.0f), new Vector2(5.0f, j * 2.0f - 3.0f));
                edgeShape.Friction = 0.5f; // Set friction
            }

            var cache = ResourceCache;

            // Create a box (will be cloned later)
            Node box = scene.CreateChild("Box");

            box.Position = (new Vector3(0.8f, -2.0f, 0.0f));
            StaticSprite2D boxSprite = box.CreateComponent <StaticSprite2D>();

            boxSprite.Sprite = cache.GetSprite2D("Urho2D/Box.png");
            RigidBody2D boxBody = box.CreateComponent <RigidBody2D>();

            boxBody.BodyType       = BodyType2D.Dynamic;
            boxBody.LinearDamping  = 0.0f;
            boxBody.AngularDamping = 0.0f;
            CollisionBox2D shape = box.CreateComponent <CollisionBox2D>(); // Create box shape

            shape.Size        = new Vector2(0.32f, 0.32f);                 // Set size
            shape.Density     = 1.0f;                                      // Set shape density (kilograms per meter squared)
            shape.Friction    = 0.5f;                                      // Set friction
            shape.Restitution = 0.1f;                                      // Set restitution (slight bounce)

            // Create a ball (will be cloned later)
            Node ball = scene.CreateChild("Ball");

            ball.Position = (new Vector3(1.8f, -2.0f, 0.0f));
            StaticSprite2D ballSprite = ball.CreateComponent <StaticSprite2D>();

            ballSprite.Sprite = cache.GetSprite2D("Urho2D/Ball.png");
            RigidBody2D ballBody = ball.CreateComponent <RigidBody2D>();

            ballBody.BodyType       = BodyType2D.Dynamic;
            ballBody.LinearDamping  = 0.0f;
            ballBody.AngularDamping = 0.0f;
            CollisionCircle2D ballShape = ball.CreateComponent <CollisionCircle2D>(); // Create circle shape

            ballShape.Radius      = 0.16f;                                            // Set radius
            ballShape.Density     = 1.0f;                                             // Set shape density (kilograms per meter squared)
            ballShape.Friction    = 0.5f;                                             // Set friction
            ballShape.Restitution = 0.6f;                                             // Set restitution: make it bounce

            // Create a polygon
            Node polygon = scene.CreateChild("Polygon");

            polygon.Position = (new Vector3(1.6f, -2.0f, 0.0f));
            polygon.SetScale(0.7f);
            StaticSprite2D polygonSprite = polygon.CreateComponent <StaticSprite2D>();

            polygonSprite.Sprite = cache.GetSprite2D("Urho2D/Aster.png");
            RigidBody2D polygonBody = polygon.CreateComponent <RigidBody2D>();

            polygonBody.BodyType = BodyType2D.Dynamic;
            CollisionPolygon2D polygonShape = polygon.CreateComponent <CollisionPolygon2D>();

            polygonShape.VertexCount = 6; // Set number of vertices (mandatory when using SetVertex())
            polygonShape.SetVertex(0, new Vector2(-0.8f, -0.3f));
            polygonShape.SetVertex(1, new Vector2(0.5f, -0.8f));
            polygonShape.SetVertex(2, new Vector2(0.8f, -0.3f));
            polygonShape.SetVertex(3, new Vector2(0.8f, 0.5f));
            polygonShape.SetVertex(4, new Vector2(0.5f, 0.9f));
            polygonShape.SetVertex(5, new Vector2(-0.5f, 0.7f));
            polygonShape.Density     = 1.0f; // Set shape density (kilograms per meter squared)
            polygonShape.Friction    = 0.3f; // Set friction
            polygonShape.Restitution = 0.0f; // Set restitution (no bounce)

            // Create a ConstraintDistance2D
            CreateFlag("ConstraintDistance2D", -4.97f, 3.0f); // Display Text3D flag
            Node        boxDistanceNode  = box.Clone(CreateMode.Replicated);
            Node        ballDistanceNode = ball.Clone(CreateMode.Replicated);
            RigidBody2D ballDistanceBody = ballDistanceNode.GetComponent <RigidBody2D>();

            boxDistanceNode.Position  = (new Vector3(-4.5f, 2.0f, 0.0f));
            ballDistanceNode.Position = (new Vector3(-3.0f, 2.0f, 0.0f));

            ConstraintDistance2D constraintDistance = boxDistanceNode.CreateComponent <ConstraintDistance2D>(); // Apply ConstraintDistance2D to box

            constraintDistance.OtherBody       = ballDistanceBody;                                              // Constrain ball to box
            constraintDistance.OwnerBodyAnchor = boxDistanceNode.Position2D;
            constraintDistance.OtherBodyAnchor = ballDistanceNode.Position2D;
            // Make the constraint soft (comment to make it rigid, which is its basic behavior)
            constraintDistance.FrequencyHz  = 4.0f;
            constraintDistance.DampingRatio = 0.5f;

            // Create a ConstraintFriction2D ********** Not functional. From Box2d samples it seems that 2 anchors are required, Urho2D only provides 1, needs investigation ***********
            CreateFlag("ConstraintFriction2D", 0.03f, 1.0f); // Display Text3D flag
            Node boxFrictionNode  = box.Clone(CreateMode.Replicated);
            Node ballFrictionNode = ball.Clone(CreateMode.Replicated);

            boxFrictionNode.Position  = (new Vector3(0.5f, 0.0f, 0.0f));
            ballFrictionNode.Position = (new Vector3(1.5f, 0.0f, 0.0f));

            ConstraintFriction2D constraintFriction = boxFrictionNode.CreateComponent <ConstraintFriction2D>(); // Apply ConstraintDistance2D to box

            constraintFriction.OtherBody = ballFrictionNode.GetComponent <RigidBody2D>();                       // Constraint ball to box

            // Create a ConstraintGear2D
            CreateFlag("ConstraintGear2D", -4.97f, -1.0f);                // Display Text3D flag
            Node        baseNode = box.Clone(CreateMode.Replicated);
            RigidBody2D tempBody = baseNode.GetComponent <RigidBody2D>(); // Get body to make it static

            tempBody.BodyType = BodyType2D.Static;
            baseNode.Position = (new Vector3(-3.7f, -2.5f, 0.0f));
            Node ball1Node = ball.Clone(CreateMode.Replicated);

            ball1Node.Position = (new Vector3(-4.5f, -2.0f, 0.0f));
            RigidBody2D ball1Body = ball1Node.GetComponent <RigidBody2D>();
            Node        ball2Node = ball.Clone(CreateMode.Replicated);

            ball2Node.Position = (new Vector3(-3.0f, -2.0f, 0.0f));
            RigidBody2D ball2Body = ball2Node.GetComponent <RigidBody2D>();

            ConstraintRevolute2D gear1 = baseNode.CreateComponent <ConstraintRevolute2D>(); // Apply constraint to baseBox

            gear1.OtherBody = ball1Body;                                                    // Constrain ball1 to baseBox
            gear1.Anchor    = ball1Node.Position2D;
            ConstraintRevolute2D gear2 = baseNode.CreateComponent <ConstraintRevolute2D>(); // Apply constraint to baseBox

            gear2.OtherBody = ball2Body;                                                    // Constrain ball2 to baseBox
            gear2.Anchor    = ball2Node.Position2D;

            ConstraintGear2D constraintGear = ball1Node.CreateComponent <ConstraintGear2D>(); // Apply constraint to ball1

            constraintGear.OtherBody       = ball2Body;                                       // Constrain ball2 to ball1
            constraintGear.OwnerConstraint = gear1;
            constraintGear.OtherConstraint = gear2;
            constraintGear.Ratio           = 1.0f;

            ball1Body.ApplyAngularImpulse(0.015f, true); // Animate

            // Create a vehicle from a compound of 2 ConstraintWheel2Ds
            CreateFlag("ConstraintWheel2Ds compound", -2.45f, -1.0f); // Display Text3D flag
            Node car = box.Clone(CreateMode.Replicated);

            car.Scale    = new Vector3(4.0f, 1.0f, 0.0f);
            car.Position = (new Vector3(-1.2f, -2.3f, 0.0f));
            StaticSprite2D tempSprite = car.GetComponent <StaticSprite2D>(); // Get car Sprite in order to draw it on top

            tempSprite.OrderInLayer = 0;                                     // Draw car on top of the wheels (set to -1 to draw below)
            Node ball1WheelNode = ball.Clone(CreateMode.Replicated);

            ball1WheelNode.Position = (new Vector3(-1.6f, -2.5f, 0.0f));
            Node ball2WheelNode = ball.Clone(CreateMode.Replicated);

            ball2WheelNode.Position = (new Vector3(-0.8f, -2.5f, 0.0f));

            ConstraintWheel2D wheel1 = car.CreateComponent <ConstraintWheel2D>();

            wheel1.OtherBody      = ball1WheelNode.GetComponent <RigidBody2D>();
            wheel1.Anchor         = ball1WheelNode.Position2D;
            wheel1.Axis           = new Vector2(0.0f, 1.0f);
            wheel1.MaxMotorTorque = 20.0f;
            wheel1.FrequencyHz    = 4.0f;
            wheel1.DampingRatio   = 0.4f;

            ConstraintWheel2D wheel2 = car.CreateComponent <ConstraintWheel2D>();

            wheel2.OtherBody      = ball2WheelNode.GetComponent <RigidBody2D>();
            wheel2.Anchor         = ball2WheelNode.Position2D;
            wheel2.Axis           = new Vector2(0.0f, 1.0f);
            wheel2.MaxMotorTorque = 10.0f;
            wheel2.FrequencyHz    = 4.0f;
            wheel2.DampingRatio   = 0.4f;

            // ConstraintMotor2D
            CreateFlag("ConstraintMotor2D", 2.53f, -1.0f); // Display Text3D flag
            Node boxMotorNode = box.Clone(CreateMode.Replicated);

            tempBody          = boxMotorNode.GetComponent <RigidBody2D>(); // Get body to make it static
            tempBody.BodyType = BodyType2D.Static;
            Node ballMotorNode = ball.Clone(CreateMode.Replicated);

            boxMotorNode.Position  = (new Vector3(3.8f, -2.1f, 0.0f));
            ballMotorNode.Position = (new Vector3(3.8f, -1.5f, 0.0f));

            ConstraintMotor2D constraintMotor = boxMotorNode.CreateComponent <ConstraintMotor2D>();

            constraintMotor.OtherBody        = ballMotorNode.GetComponent <RigidBody2D>(); // Constrain ball to box
            constraintMotor.LinearOffset     = new Vector2(0.0f, 0.8f);                    // Set ballNode position relative to boxNode position = (0,0)
            constraintMotor.AngularOffset    = 0.1f;
            constraintMotor.MaxForce         = 5.0f;
            constraintMotor.MaxTorque        = 10.0f;
            constraintMotor.CorrectionFactor = 1.0f;
            constraintMotor.CollideConnected = true; // doesn't work

            // ConstraintMouse2D is demonstrated in HandleMouseButtonDown() function. It is used to "grasp" the sprites with the mouse.
            CreateFlag("ConstraintMouse2D", 0.03f, -1.0f); // Display Text3D flag

            // Create a ConstraintPrismatic2D
            CreateFlag("ConstraintPrismatic2D", 2.53f, 3.0f); // Display Text3D flag
            Node boxPrismaticNode = box.Clone(CreateMode.Replicated);

            tempBody          = boxPrismaticNode.GetComponent <RigidBody2D>(); // Get body to make it static
            tempBody.BodyType = BodyType2D.Static;
            Node ballPrismaticNode = ball.Clone(CreateMode.Replicated);

            boxPrismaticNode.Position  = new Vector3(3.3f, 2.5f, 0.0f);
            ballPrismaticNode.Position = new Vector3(4.3f, 2.0f, 0.0f);

            ConstraintPrismatic2D constraintPrismatic = boxPrismaticNode.CreateComponent <ConstraintPrismatic2D>();

            constraintPrismatic.OtherBody        = ballPrismaticNode.GetComponent <RigidBody2D>(); // Constrain ball to box
            constraintPrismatic.Axis             = new Vector2(1.0f, 1.0f);                        // Slide from [0,0] to [1,1]
            constraintPrismatic.Anchor           = new Vector2(4.0f, 2.0f);
            constraintPrismatic.LowerTranslation = -1.0f;
            constraintPrismatic.UpperTranslation = 0.5f;
            constraintPrismatic.EnableLimit      = true;
            constraintPrismatic.MaxMotorForce    = 1.0f;
            constraintPrismatic.MotorSpeed       = 0.0f;

            // ConstraintPulley2D
            CreateFlag("ConstraintPulley2D", 0.03f, 3.0f); // Display Text3D flag
            Node boxPulleyNode  = box.Clone(CreateMode.Replicated);
            Node ballPulleyNode = ball.Clone(CreateMode.Replicated);

            boxPulleyNode.Position  = (new Vector3(0.5f, 2.0f, 0.0f));
            ballPulleyNode.Position = (new Vector3(2.0f, 2.0f, 0.0f));

            ConstraintPulley2D constraintPulley = boxPulleyNode.CreateComponent <ConstraintPulley2D>(); // Apply constraint to box

            constraintPulley.OtherBody             = ballPulleyNode.GetComponent <RigidBody2D>();       // Constrain ball to box
            constraintPulley.OwnerBodyAnchor       = boxPulleyNode.Position2D;
            constraintPulley.OtherBodyAnchor       = ballPulleyNode.Position2D;
            constraintPulley.OwnerBodyGroundAnchor = boxPulleyNode.Position2D + new Vector2(0.0f, 1.0f);
            constraintPulley.OtherBodyGroundAnchor = ballPulleyNode.Position2D + new Vector2(0.0f, 1.0f);
            constraintPulley.Ratio = 1.0f; // Weight ratio between ownerBody and otherBody

            // Create a ConstraintRevolute2D
            CreateFlag("ConstraintRevolute2D", -2.45f, 3.0f); // Display Text3D flag
            Node boxRevoluteNode = box.Clone(CreateMode.Replicated);

            tempBody          = boxRevoluteNode.GetComponent <RigidBody2D>(); // Get body to make it static
            tempBody.BodyType = BodyType2D.Static;
            Node ballRevoluteNode = ball.Clone(CreateMode.Replicated);

            boxRevoluteNode.Position  = (new Vector3(-2.0f, 1.5f, 0.0f));
            ballRevoluteNode.Position = (new Vector3(-1.0f, 2.0f, 0.0f));

            ConstraintRevolute2D constraintRevolute = boxRevoluteNode.CreateComponent <ConstraintRevolute2D>(); // Apply constraint to box

            constraintRevolute.OtherBody      = ballRevoluteNode.GetComponent <RigidBody2D>();                  // Constrain ball to box
            constraintRevolute.Anchor         = new Vector2(-1.0f, 1.5f);
            constraintRevolute.LowerAngle     = -1.0f;                                                          // In radians
            constraintRevolute.UpperAngle     = 0.5f;                                                           // In radians
            constraintRevolute.EnableLimit    = true;
            constraintRevolute.MaxMotorTorque = 10.0f;
            constraintRevolute.MotorSpeed     = 0.0f;
            constraintRevolute.EnableMotor    = true;

            // Create a ConstraintRope2D
            CreateFlag("ConstraintRope2D", -4.97f, 1.0f); // Display Text3D flag
            Node boxRopeNode = box.Clone(CreateMode.Replicated);

            tempBody          = boxRopeNode.GetComponent <RigidBody2D>();
            tempBody.BodyType = BodyType2D.Static;
            Node ballRopeNode = ball.Clone(CreateMode.Replicated);

            boxRopeNode.Position  = (new Vector3(-3.7f, 0.7f, 0.0f));
            ballRopeNode.Position = (new Vector3(-4.5f, 0.0f, 0.0f));

            ConstraintRope2D constraintRope = boxRopeNode.CreateComponent <ConstraintRope2D>();

            constraintRope.OtherBody        = ballRopeNode.GetComponent <RigidBody2D>(); // Constrain ball to box
            constraintRope.OwnerBodyAnchor  = new Vector2(0.0f, -0.5f);                  // Offset from box (OwnerBody) : the rope is rigid from OwnerBody center to this ownerBodyAnchor
            constraintRope.MaxLength        = 0.9f;                                      // Rope length
            constraintRope.CollideConnected = true;

            // Create a ConstraintWeld2D
            CreateFlag("ConstraintWeld2D", -2.45f, 1.0f); // Display Text3D flag
            Node boxWeldNode  = box.Clone(CreateMode.Replicated);
            Node ballWeldNode = ball.Clone(CreateMode.Replicated);

            boxWeldNode.Position  = (new Vector3(-0.5f, 0.0f, 0.0f));
            ballWeldNode.Position = (new Vector3(-2.0f, 0.0f, 0.0f));

            ConstraintWeld2D constraintWeld = boxWeldNode.CreateComponent <ConstraintWeld2D>();

            constraintWeld.OtherBody    = ballWeldNode.GetComponent <RigidBody2D>(); // Constrain ball to box
            constraintWeld.Anchor       = boxWeldNode.Position2D;
            constraintWeld.FrequencyHz  = 4.0f;
            constraintWeld.DampingRatio = 0.5f;

            // Create a ConstraintWheel2D
            CreateFlag("ConstraintWheel2D", 2.53f, 1.0f); // Display Text3D flag
            Node boxWheelNode  = box.Clone(CreateMode.Replicated);
            Node ballWheelNode = ball.Clone(CreateMode.Replicated);

            boxWheelNode.Position  = (new Vector3(3.8f, 0.0f, 0.0f));
            ballWheelNode.Position = (new Vector3(3.8f, 0.9f, 0.0f));

            ConstraintWheel2D constraintWheel = boxWheelNode.CreateComponent <ConstraintWheel2D>();

            constraintWheel.OtherBody        = ballWheelNode.GetComponent <RigidBody2D>(); // Constrain ball to box
            constraintWheel.Anchor           = ballWheelNode.Position2D;
            constraintWheel.Axis             = new Vector2(0.0f, 1.0f);
            constraintWheel.EnableMotor      = true;
            constraintWheel.MaxMotorTorque   = 1.0f;
            constraintWheel.MotorSpeed       = 0.0f;
            constraintWheel.FrequencyHz      = 4.0f;
            constraintWheel.DampingRatio     = 0.5f;
            constraintWheel.CollideConnected = true; // doesn't work
        }