Beispiel #1
0
    void rotate_body_to(FarseerPhysics.Dynamics.Body body, float desiredAngle)
    {
        float DEGTORAD      = Mathf.PI / 180f;
        float bodyAngle     = body.Rotation;
        float nextAngle     = bodyAngle + body.AngularVelocity * Time.deltaTime;
        float totalRotation = desiredAngle - nextAngle;

        while (totalRotation < -180 * DEGTORAD)
        {
            totalRotation += 360 * DEGTORAD;
        }
        while (totalRotation > 180 * DEGTORAD)
        {
            totalRotation -= 360 * DEGTORAD;
        }
        float desiredAngularVelocity = totalRotation * 60;
        float impulse = body.Inertia * desiredAngularVelocity;        // disregard time factor

        body.ApplyAngularImpulse(impulse / 5f);
    }
Beispiel #2
0
        public override void LoadContent()
        {
            base.LoadContent();

            World.Gravity = new Vector2(0f, 10f);

            HasCursor = false;
            EnableCameraControl = true;
            HasVirtualStick = true;

            _hzFront = 8.5f;
            _hzBack = 5.0f;
            _zeta = 0.85f;
            _maxSpeed = 50.0f;

#if WINDOWS_PHONE
            _scale = 2f / 3f;
#else
            _scale = 1f;
#endif

            // terrain
            _ground = new Body(World);
            {
                Vertices terrain = new Vertices();
                terrain.Add(new Vector2(-20f, -5f));
                terrain.Add(new Vector2(-20f, 0f));
                terrain.Add(new Vector2(20f, 0f));
                terrain.Add(new Vector2(25f, -0.25f));
                terrain.Add(new Vector2(30f, -1f));
                terrain.Add(new Vector2(35f, -4f));
                terrain.Add(new Vector2(40f, 0f));
                terrain.Add(new Vector2(45f, 0f));
                terrain.Add(new Vector2(50f, 1f));
                terrain.Add(new Vector2(55f, 2f));
                terrain.Add(new Vector2(60f, 2f));
                terrain.Add(new Vector2(65f, 1.25f));
                terrain.Add(new Vector2(70f, 0f));
                terrain.Add(new Vector2(75f, -0.3f));
                terrain.Add(new Vector2(80f, -1.5f));
                terrain.Add(new Vector2(85f, -3.5f));
                terrain.Add(new Vector2(90f, 0f));
                terrain.Add(new Vector2(95f, 0.5f));
                terrain.Add(new Vector2(100f, 1f));
                terrain.Add(new Vector2(105f, 2f));
                terrain.Add(new Vector2(110f, 2.5f));
                terrain.Add(new Vector2(115f, 1.3f));
                terrain.Add(new Vector2(120f, 0f));
                terrain.Add(new Vector2(160f, 0f));
                terrain.Add(new Vector2(159f, 10f));
                terrain.Add(new Vector2(201f, 10f));
                terrain.Add(new Vector2(200f, 0f));
                terrain.Add(new Vector2(240f, 0f));
                terrain.Add(new Vector2(250f, -5f));
                terrain.Add(new Vector2(250f, 10f));
                terrain.Add(new Vector2(270f, 10f));
                terrain.Add(new Vector2(270f, 0));
                terrain.Add(new Vector2(310f, 0));
                terrain.Add(new Vector2(310f, -5));

                for (int i = 0; i < terrain.Count - 1; ++i)
                {
                    FixtureFactory.AttachEdge(terrain[i], terrain[i + 1], _ground);
                }

                _ground.Friction = 0.6f;
            }

            // teeter board
            {
                _board = new Body(World);
                _board.BodyType = BodyType.Dynamic;
                _board.Position = new Vector2(140.0f, -1.0f);

                PolygonShape box = new PolygonShape(1f);
                box.SetAsBox(10.0f, 0.25f);
                _teeter =
                    new Sprite(ScreenManager.Assets.TextureFromShape(box, MaterialType.Pavement, Color.LightGray, 1.2f));

                _board.CreateFixture(box);

                RevoluteJoint teeterAxis = JointFactory.CreateRevoluteJoint(_ground, _board, Vector2.Zero);
                teeterAxis.LowerLimit = -8.0f * Settings.Pi / 180.0f;
                teeterAxis.UpperLimit = 8.0f * Settings.Pi / 180.0f;
                teeterAxis.LimitEnabled = true;
                World.AddJoint(teeterAxis);

                _board.ApplyAngularImpulse(-100.0f);
            }

            // bridge
            {
                _bridgeSegments = new List<Body>();

                const int segmentCount = 20;
                PolygonShape shape = new PolygonShape(1f);
                shape.SetAsBox(1.0f, 0.125f);
                _bridge =
                    new Sprite(ScreenManager.Assets.TextureFromShape(shape, MaterialType.Dots, Color.SandyBrown, 1f));

                Body prevBody = _ground;
                for (int i = 0; i < segmentCount; ++i)
                {
                    Body body = new Body(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(161f + 2f * i, 0.125f);
                    Fixture fix = body.CreateFixture(shape);
                    fix.Friction = 0.6f;
                    JointFactory.CreateRevoluteJoint(World, prevBody, body, -Vector2.UnitX);

                    prevBody = body;
                    _bridgeSegments.Add(body);
                }
                JointFactory.CreateRevoluteJoint(World, _ground, prevBody, Vector2.UnitX);
            }

            // boxes
            {
                _boxes = new List<Body>();
                PolygonShape box = new PolygonShape(1f);
                box.SetAsBox(0.5f, 0.5f);
                _box =
                    new Sprite(ScreenManager.Assets.TextureFromShape(box, MaterialType.Squares, Color.SaddleBrown, 2f));

                Body body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(220f, -0.5f);
                body.CreateFixture(box);
                _boxes.Add(body);

                body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(220f, -1.5f);
                body.CreateFixture(box);
                _boxes.Add(body);

                body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(220f, -2.5f);
                body.CreateFixture(box);
                _boxes.Add(body);
            }

            // car
            {
                Vertices vertices = new Vertices(8);
                vertices.Add(new Vector2(-2.5f, 0.08f));
                vertices.Add(new Vector2(-2.375f, -0.46f));
                vertices.Add(new Vector2(-0.58f, -0.92f));
                vertices.Add(new Vector2(0.46f, -0.92f));
                vertices.Add(new Vector2(2.5f, -0.17f));
                vertices.Add(new Vector2(2.5f, 0.205f));
                vertices.Add(new Vector2(2.3f, 0.33f));
                vertices.Add(new Vector2(-2.25f, 0.35f));

                PolygonShape chassis = new PolygonShape(vertices, 2f);

                _car = new Body(World);
                _car.BodyType = BodyType.Dynamic;
                _car.Position = new Vector2(0.0f, -1.0f);
                _car.CreateFixture(chassis);

                _wheelBack = new Body(World);
                _wheelBack.BodyType = BodyType.Dynamic;
                _wheelBack.Position = new Vector2(-1.709f, -0.78f);
                Fixture fix = _wheelBack.CreateFixture(new CircleShape(0.5f, 0.8f));
                fix.Friction = 0.9f;

                _wheelFront = new Body(World);
                _wheelFront.BodyType = BodyType.Dynamic;
                _wheelFront.Position = new Vector2(1.54f, -0.8f);
                _wheelFront.CreateFixture(new CircleShape(0.5f, 1f));

                Vector2 axis = new Vector2(0.0f, -1.2f);
                _springBack = new LineJoint(_car, _wheelBack, _wheelBack.Position, axis);
                _springBack.MotorSpeed = 0.0f;
                _springBack.MaxMotorTorque = 20.0f;
                _springBack.MotorEnabled = true;
                _springBack.Frequency = _hzBack;
                _springBack.DampingRatio = _zeta;
                World.AddJoint(_springBack);

                _springFront = new LineJoint(_car, _wheelFront, _wheelFront.Position, axis);
                _springFront.MotorSpeed = 0.0f;
                _springFront.MaxMotorTorque = 10.0f;
                _springFront.MotorEnabled = false;
                _springFront.Frequency = _hzFront;
                _springFront.DampingRatio = _zeta;
                World.AddJoint(_springFront);

                _carBody = new Sprite(ScreenManager.Content.Load<Texture2D>("Samples/car"),
                                      AssetCreator.CalculateOrigin(_car) / _scale);
                _wheel = new Sprite(ScreenManager.Content.Load<Texture2D>("Samples/wheel"));
            }

            Camera.MinRotation = -0.05f;
            Camera.MaxRotation = 0.05f;

            Camera.TrackingBody = _car;
            Camera.EnableTracking = true;
        }
Beispiel #3
0
        private CarTest()
        {
            _hz = 4.0f;
            _zeta = 0.7f;
            _speed = 50.0f;

            Body ground = new Body(World);
            {
                EdgeShape shape = new EdgeShape(new Vector2(-20.0f, 0.0f), new Vector2(20.0f, 0.0f));
                ground.CreateFixture(shape);

                float[] hs = new[] { 0.25f, 1.0f, 4.0f, 0.0f, 0.0f, -1.0f, -2.0f, -2.0f, -1.25f, 0.0f };

                float x = 20.0f, y1 = 0.0f;
                const float dx = 5.0f;

                for (int i = 0; i < 10; ++i)
                {
                    float y2 = hs[i];
                    FixtureFactory.AttachEdge(new Vector2(x, y1), new Vector2(x + dx, y2), ground);
                    y1 = y2;
                    x += dx;
                }

                for (int i = 0; i < 10; ++i)
                {
                    float y2 = hs[i];
                    FixtureFactory.AttachEdge(new Vector2(x, y1), new Vector2(x + dx, y2), ground);
                    y1 = y2;
                    x += dx;
                }

                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x + 40.0f, 0.0f), ground);

                x += 80.0f;
                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x + 40.0f, 0.0f), ground);

                x += 40.0f;
                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x + 10.0f, 5.0f), ground);

                x += 20.0f;
                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x + 40.0f, 0.0f), ground);

                x += 40.0f;
                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x, 20.0f), ground);

                ground.Friction = 0.6f;
            }

            // Teeter
            {
                Body body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(140.0f, 1.0f);

                PolygonShape box = new PolygonShape(1);
                box.SetAsBox(10.0f, 0.25f);
                body.CreateFixture(box);

                RevoluteJoint jd = JointFactory.CreateRevoluteJoint(ground, body, Vector2.Zero);
                jd.LowerLimit = -8.0f * Settings.Pi / 180.0f;
                jd.UpperLimit = 8.0f * Settings.Pi / 180.0f;
                jd.LimitEnabled = true;
                World.AddJoint(jd);

                body.ApplyAngularImpulse(100.0f);
            }

            //Bridge
            {
                const int N = 20;
                PolygonShape shape = new PolygonShape(1);
                shape.SetAsBox(1.0f, 0.125f);

                Body prevBody = ground;
                for (int i = 0; i < N; ++i)
                {
                    Body body = new Body(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(161.0f + 2.0f * i, -0.125f);
                    Fixture fix = body.CreateFixture(shape);
                    fix.Friction = 0.6f;

                    Vector2 anchor = new Vector2(-1, 0);
                    JointFactory.CreateRevoluteJoint(World, prevBody, body, anchor);

                    prevBody = body;
                }

                Vector2 anchor2 = new Vector2(1.0f, 0);
                JointFactory.CreateRevoluteJoint(World, ground, prevBody, anchor2);
            }

            // Boxes
            {
                PolygonShape box = new PolygonShape(0.5f);
                box.SetAsBox(0.5f, 0.5f);

                Body body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 0.5f);
                body.CreateFixture(box);

                body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 1.5f);
                body.CreateFixture(box);

                body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 2.5f);
                body.CreateFixture(box);

                body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 3.5f);
                body.CreateFixture(box);

                body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 4.5f);
                body.CreateFixture(box);
            }

            // Car
            {
                Vertices vertices = new Vertices(8);
                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));

                PolygonShape chassis = new PolygonShape(vertices, 1);

                CircleShape circle = new CircleShape(0.4f, 1);

                _car = new Body(World);
                _car.BodyType = BodyType.Dynamic;
                _car.Position = new Vector2(0.0f, 1.0f);
                _car.CreateFixture(chassis);

                _wheel1 = new Body(World);
                _wheel1.BodyType = BodyType.Dynamic;
                _wheel1.Position = new Vector2(-1.0f, 0.35f);
                Fixture fix = _wheel1.CreateFixture(circle);
                fix.Friction = 0.9f;

                _wheel2 = new Body(World);
                _wheel2.BodyType = BodyType.Dynamic;
                _wheel2.Position = new Vector2(1.0f, 0.4f);
                _wheel2.CreateFixture(circle);

                Vector2 axis = new Vector2(0.0f, 1.0f);
                _spring1 = new WheelJoint(_car, _wheel1, _wheel1.Position, axis);
                _spring1.MotorSpeed = 0.0f;
                _spring1.MaxMotorTorque = 20.0f;
                _spring1.MotorEnabled = true;
                _spring1.Frequency = _hz;
                _spring1.DampingRatio = _zeta;
                World.AddJoint(_spring1);

                _spring2 = new WheelJoint(_car, _wheel2, _wheel2.Position, axis);
                _spring2.MotorSpeed = 0.0f;
                _spring2.MaxMotorTorque = 10.0f;
                _spring2.MotorEnabled = false;
                _spring2.Frequency = _hz;
                _spring2.DampingRatio = _zeta;
                World.AddJoint(_spring2);
            }
        }
Beispiel #4
0
        public override void LoadContent()
        {
            base.LoadContent();

            World.Gravity = new Vector2( 0f, 10f );

            HasCursor = false;
            EnableCameraControl = true;
            HasVirtualStick = true;

            _hzFront = 9.5f;
            _hzBack = 6.0f;
            _zeta = 1f;
            _maxSpeed = 150.0f;

            #if WINDOWS_PHONE
            _scale = 2f / 3f;
            #else
            _scale = 1f;
            #endif

            _mapScale = 2;

            _groundTex = ContentHelper.GetTexture( "tutorial" );
            var terrain = GetVertsFromMapImage( _groundTex, _mapScale, out _groundOrigin );
            // terrain

            _ground = BodyFactory.CreateCompoundPolygon( World, terrain, 1f, BodyType.Static );
            _ground.Friction = 1f;

            // teeter board
            {
                _board = new Body( World );
                _board.BodyType = BodyType.Dynamic;
                _board.Position = new Vector2( 140.0f, -1.0f );

                var box = new PolygonShape( 1f );
                box.SetAsBox( 10.0f, 0.25f );
                _teeter =
                    new PrimitiveSprite( ScreenManager.Assets.TextureFromShape( box, MaterialType.Pavement, Color.LightGray, 1.2f ) );

                _board.CreateFixture( box );

                RevoluteJoint teeterAxis = JointFactory.CreateRevoluteJoint( _ground, _board, Vector2.Zero );
                teeterAxis.LowerLimit = -8.0f * Settings.Pi / 180.0f;
                teeterAxis.UpperLimit = 8.0f * Settings.Pi / 180.0f;
                teeterAxis.LimitEnabled = true;
                World.AddJoint( teeterAxis );

                _board.ApplyAngularImpulse( -100.0f );
            }

            // bridge
            {
                _bridgeSegments = new List<Body>();

                const int segmentCount = 20;
                var shape = new PolygonShape( 1f );
                shape.SetAsBox( 1.0f, 0.125f );
                _bridge =
                    new PrimitiveSprite( ScreenManager.Assets.TextureFromShape( shape, MaterialType.Dots, Color.SandyBrown, 1f ) );

                Body prevBody = _ground;
                for ( int i = 0; i < segmentCount; ++i ) {
                    var body = new Body( World );
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2( 161f + 2f * i, 0.125f );
                    Fixture fix = body.CreateFixture( shape );
                    fix.Friction = 0.6f;
                    JointFactory.CreateRevoluteJoint( World, prevBody, body, -Vector2.UnitX );

                    prevBody = body;
                    _bridgeSegments.Add( body );
                }
                JointFactory.CreateRevoluteJoint( World, _ground, prevBody, Vector2.UnitX );
            }

            // boxes
            {
                _boxes = new List<Body>();
                var box = new PolygonShape( 1f );
                box.SetAsBox( 0.5f, 0.5f );
                _box =
                    new PrimitiveSprite( ScreenManager.Assets.TextureFromShape( box, MaterialType.Squares, Color.SaddleBrown, 2f ) );

                var body = new Body( World );
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2( 220f, -0.5f );
                body.CreateFixture( box );
                _boxes.Add( body );

                body = new Body( World );
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2( 220f, -1.5f );
                body.CreateFixture( box );
                _boxes.Add( body );

                body = new Body( World );
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2( 220f, -2.5f );
                body.CreateFixture( box );
                _boxes.Add( body );
            }

            // car
            {
                var vertices = new Vertices( 8 );
                vertices.Add( new Vector2( -2.5f, 0.08f ) );
                vertices.Add( new Vector2( -2.375f, -0.46f ) );
                vertices.Add( new Vector2( -0.58f, -0.92f ) );
                vertices.Add( new Vector2( 0.46f, -0.92f ) );
                vertices.Add( new Vector2( 2.5f, -0.17f ) );
                vertices.Add( new Vector2( 2.5f, 0.205f ) );
                vertices.Add( new Vector2( 2.3f, 0.33f ) );
                vertices.Add( new Vector2( -2.25f, 0.35f ) );

                var chassis = new PolygonShape( vertices, 1f );

                _car = new Body( World );
                _car.BodyType = BodyType.Dynamic;
                _car.Position = new Vector2( 0.0f, -1.0f );
                _car.CreateFixture( chassis );
                //_car.AngularDamping = 24f;

                _wheelBack = new Body( World );
                _wheelBack.BodyType = BodyType.Dynamic;
                _wheelBack.Position = new Vector2( -1.709f, -0.78f );
                Fixture fix = _wheelBack.CreateFixture( new CircleShape( 0.5f, .2f ) );
                fix.Friction = 1f;

                _wheelFront = new Body( World );
                _wheelFront.BodyType = BodyType.Dynamic;
                _wheelFront.Position = new Vector2( 1.54f, -0.8f );
                _wheelFront.CreateFixture( new CircleShape( 0.5f, .2f ) ).Friction = 1f;

                var axis = new Vector2( 0.0f, -1.2f );
                _springBack = new LineJoint( _car, _wheelBack, _wheelBack.Position, axis );
                _springBack.MotorSpeed = 0.0f;
                _springBack.MaxMotorTorque = 90.0f;
                _springBack.MotorEnabled = true;
                _springBack.Frequency = _hzBack;
                _springBack.DampingRatio = _zeta;
                World.AddJoint( _springBack );

                _springFront = new LineJoint( _car, _wheelFront, _wheelFront.Position, axis );
                _springFront.MotorSpeed = 0.0f;
                _springFront.MaxMotorTorque = 60.0f;
                _springFront.MotorEnabled = false;
                _springFront.Frequency = _hzFront;
                _springFront.DampingRatio = _zeta;
                World.AddJoint( _springFront );

                _carBody = new PrimitiveSprite( ContentHelper.GetTexture( "car" ),
                                                 AssetCreator.CalculateOrigin( _car ) / _scale );
                _wheel = new PrimitiveSprite( ContentHelper.GetTexture( "wheel" ) );
            }

            Camera.MinRotation = -0.01f;
            Camera.MaxRotation = 0.01f;

            Camera.TrackingBody = _car;
            Camera.EnableTracking = true;

            //Just for preview stuff
            _car.Position -= ConvertUnits.ToSimUnits( 3600, 300 );
            _wheelBack.Position -= ConvertUnits.ToSimUnits( 3600, 300 );
            _wheelFront.Position -= ConvertUnits.ToSimUnits( 3600, 300 );
            Camera.Position -= new Vector2( 0, 300 );
        }
Beispiel #5
0
        public override void LoadContent()
        {
            base.LoadContent();

            World.Gravity = new Vector2(0f, 10f);

            HasCursor = false;
            EnableCameraControl = true;

            _hzFront = 8.5f;
            _hzBack = 5.0f;
            _zeta = 0.85f;
            _maxSpeed = 50.0f;

            // terrain
            _ground = new Body(World);
            {
                Vertices terrain = new Vertices();
                terrain.Add(new Vector2(-20f, -5f));
                terrain.Add(new Vector2(-20f, 0f));
                terrain.Add(new Vector2(20f, 0f));
                terrain.Add(new Vector2(25f, -0.25f));
                terrain.Add(new Vector2(30f, -1f));
                terrain.Add(new Vector2(35f, -4f));
                terrain.Add(new Vector2(40f, 0f));
                terrain.Add(new Vector2(45f, 0f));
                terrain.Add(new Vector2(50f, 1f));
                terrain.Add(new Vector2(55f, 2f));
                terrain.Add(new Vector2(60f, 2f));
                terrain.Add(new Vector2(65f, 1.25f));
                terrain.Add(new Vector2(70f, 0f));
                terrain.Add(new Vector2(75f, -0.3f));
                terrain.Add(new Vector2(80f, -1.5f));
                terrain.Add(new Vector2(85f, -3.5f));
                terrain.Add(new Vector2(90f, 0f));
                terrain.Add(new Vector2(95f, 0.5f));
                terrain.Add(new Vector2(100f, 1f));
                terrain.Add(new Vector2(105f, 2f));
                terrain.Add(new Vector2(110f, 2.5f));
                terrain.Add(new Vector2(115f, 1.3f));
                terrain.Add(new Vector2(120f, 0f));
                terrain.Add(new Vector2(160f, 0f));
                terrain.Add(new Vector2(159f, 10f));
                terrain.Add(new Vector2(201f, 10f));
                terrain.Add(new Vector2(200f, 0f));
                terrain.Add(new Vector2(240f, 0f));
                terrain.Add(new Vector2(250f, -5f));
                terrain.Add(new Vector2(250f, 10f));
                terrain.Add(new Vector2(270f, 10f));
                terrain.Add(new Vector2(270f, 0));
                terrain.Add(new Vector2(310f, 0));
                terrain.Add(new Vector2(310f, -5));

                for (int i = 0; i < terrain.Count - 1; ++i)
                {
                    FixtureFactory.AttachEdge(terrain[i], terrain[i + 1], _ground);
                }

                _ground.Friction = 0.6f;
            }

            // teeter board
            {
                _board = new Body(World);
                _board.BodyType = BodyType.Dynamic;
                _board.Position = new Vector2(140.0f, -1.0f);

                PolygonShape box = new PolygonShape(1f);
                box.Vertices = PolygonTools.CreateRectangle(10.0f, 0.25f);
                _teeter = new Sprite(ContentWrapper.TextureFromShape(box, "Stripe", ContentWrapper.Gold, ContentWrapper.Black, ContentWrapper.Black, 1f));

                _board.CreateFixture(box);

                RevoluteJoint teeterAxis = JointFactory.CreateRevoluteJoint(World, _ground, _board, Vector2.Zero);
                teeterAxis.LowerLimit = -8.0f * Settings.Pi / 180.0f;
                teeterAxis.UpperLimit = 8.0f * Settings.Pi / 180.0f;
                teeterAxis.LimitEnabled = true;

                _board.ApplyAngularImpulse(-100.0f);
            }

            // bridge
            {
                _bridgeSegments = new List<Body>();

                const int segmentCount = 20;
                PolygonShape shape = new PolygonShape(1f);
                shape.Vertices = PolygonTools.CreateRectangle(1.0f, 0.125f);

                _bridge = new Sprite(ContentWrapper.TextureFromShape(shape, ContentWrapper.Gold, ContentWrapper.Black));

                Body prevBody = _ground;
                for (int i = 0; i < segmentCount; ++i)
                {
                    Body body = new Body(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(161f + 2f * i, 0.125f);
                    Fixture fix = body.CreateFixture(shape);
                    fix.Friction = 0.6f;
                    JointFactory.CreateRevoluteJoint(World, prevBody, body, -Vector2.UnitX);

                    prevBody = body;
                    _bridgeSegments.Add(body);
                }
                JointFactory.CreateRevoluteJoint(World, _ground, prevBody, Vector2.UnitX);
            }

            // boxes
            {
                _boxes = new List<Body>();
                PolygonShape box = new PolygonShape(1f);
                box.Vertices = PolygonTools.CreateRectangle(0.5f, 0.5f);
                _box = new Sprite(ContentWrapper.TextureFromShape(box, "Square", ContentWrapper.Sky, ContentWrapper.Sunset, ContentWrapper.Black, 1f));

                Body body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(220f, -0.5f);
                body.CreateFixture(box);
                _boxes.Add(body);

                body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(220f, -1.5f);
                body.CreateFixture(box);
                _boxes.Add(body);

                body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(220f, -2.5f);
                body.CreateFixture(box);
                _boxes.Add(body);
            }

            // car
            {
                Vertices vertices = new Vertices(8);
                vertices.Add(new Vector2(-2.5f, 0.08f));
                vertices.Add(new Vector2(-2.375f, -0.46f));
                vertices.Add(new Vector2(-0.58f, -0.92f));
                vertices.Add(new Vector2(0.46f, -0.92f));
                vertices.Add(new Vector2(2.5f, -0.17f));
                vertices.Add(new Vector2(2.5f, 0.205f));
                vertices.Add(new Vector2(2.3f, 0.33f));
                vertices.Add(new Vector2(-2.25f, 0.35f));

                PolygonShape chassis = new PolygonShape(vertices, 2f);

                _car = new Body(World);
                _car.BodyType = BodyType.Dynamic;
                _car.Position = new Vector2(0.0f, -1.0f);
                _car.CreateFixture(chassis);

                _wheelBack = new Body(World);
                _wheelBack.BodyType = BodyType.Dynamic;
                _wheelBack.Position = new Vector2(-1.709f, -0.78f);
                Fixture fix = _wheelBack.CreateFixture(new CircleShape(0.5f, 0.8f));
                fix.Friction = 0.9f;

                _wheelFront = new Body(World);
                _wheelFront.BodyType = BodyType.Dynamic;
                _wheelFront.Position = new Vector2(1.54f, -0.8f);
                _wheelFront.CreateFixture(new CircleShape(0.5f, 1f));

                Vector2 axis = new Vector2(0.0f, -1.2f);
                _springBack = new WheelJoint(_car, _wheelBack, _wheelBack.Position, axis, true);
                _springBack.MotorSpeed = 0.0f;
                _springBack.MaxMotorTorque = 20.0f;
                _springBack.MotorEnabled = true;
                _springBack.Frequency = _hzBack;
                _springBack.DampingRatio = _zeta;
                World.AddJoint(_springBack);

                _springFront = new WheelJoint(_car, _wheelFront, _wheelFront.Position, axis, true);
                _springFront.MotorSpeed = 0.0f;
                _springFront.MaxMotorTorque = 10.0f;
                _springFront.MotorEnabled = false;
                _springFront.Frequency = _hzFront;
                _springFront.DampingRatio = _zeta;
                World.AddJoint(_springFront);

                // GFX
                _carBody = new Sprite(ContentWrapper.GetTexture("Car"), ContentWrapper.CalculateOrigin(_car));
                _wheel = new Sprite(ContentWrapper.GetTexture("Wheel"));
            }

            Camera.MinRotation = -0.05f;
            Camera.MaxRotation = 0.05f;

            Camera.TrackingBody = _car;
            Camera.EnableTracking = true;
        }