Example #1
0
 private void RenderDebug()
 {
     if (_debugDraw != null)
     {
         _debugDraw.Begin();
         _world.DrawDebugData();
         _debugDraw.End();
     }
 }
Example #2
0
 void RenderDebug()
 {
     if (debugDraw != null)
     {
         debugDraw.Begin();
         world.DrawDebugData();
         debugDraw.End();
     }
 }
Example #3
0
        public void Draw()
        {
            m_debugDraw.Begin();

            // DrawTitle(50, 15, "Hola");
            m_debugDraw.DrawString(50, 15, "bodies");
            m_world.DrawDebugData();
            m_debugDraw.End();
        }
Example #4
0
        protected override void Draw()
        {
            base.Draw();

            if (_debugDraw != null)
            {
                _debugDraw.Begin();
                _world.DrawDebugData();
                _debugDraw.End();
            }
        }
Example #5
0
        void FixedUpdate()
        {
            if (_pause)
            {
                return;
            }
            _world.Step(dt, velocityIterations, positionIterations);
            _world.ClearForces();
#if UNITY_EDITOR
            _world.DrawDebugData();
#endif
        }
Example #6
0
        public void OpenGLDraw()
        {
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();

            Gl.glPushMatrix();

            Gl.glTranslatef(sogc.Width / 2, sogc.Height / 2, 0);
            Gl.glScalef(14, -14, 14);

            world.DrawDebugData();

            Gl.glPopMatrix();
        }
Example #7
0
    //Update()函数调用
    protected void updateBase()
    {
        if (Input.GetMouseButtonDown(0))
        {
            mouseDownHandler();
        }
        if (Input.GetMouseButton(0))
        {
            mouseMoveHandler();
        }
        if (Input.GetMouseButtonUp(0))
        {
            stopDragBody();
        }

        _world.Step(1.0f / ptm_ratio, 8, 8);
        _world.ClearForces();
        _world.DrawDebugData();
    }
Example #8
0
        public override void Draw()
        {
            //
            // IMPORTANT:
            // This is only for debug purposes
            // It is recommend to disable it
            //
            base.Draw();

            //ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );

            //kmGLPushMatrix();

            CCDrawingPrimitives.Begin();
            _world.DrawDebugData();
            CCDrawingPrimitives.End();

            //world.DrawDebugData();

            //kmGLPopMatrix();
        }
Example #9
0
        protected virtual void Draw(Settings settings)
        {
            m_world.DrawDebugData();

            if (settings.drawStats)
            {
                int bodyCount    = m_world.BodyCount;
                int contactCount = m_world.ContactCount;
                int jointCount   = m_world.JointCount;
                m_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints = {0}/{1}/{2}", bodyCount, contactCount,
                                       jointCount);
                m_textLine += 15;

                int   proxyCount = m_world.GetProxyCount();
                int   height     = m_world.GetTreeHeight();
                int   balance    = m_world.GetTreeBalance();
                float quality    = m_world.GetTreeQuality();
                m_debugDraw.DrawString(5, m_textLine, "proxies/height/balance/quality = {0}/{1}/{2}/{3}", proxyCount,
                                       height, balance, quality);
                m_textLine += 15;
            }
#if PROFILING
            // Track maximum profile times
            {
                b2Profile p = m_world.Profile;
                m_maxProfile.step          = Math.Max(m_maxProfile.step, p.step);
                m_maxProfile.collide       = Math.Max(m_maxProfile.collide, p.collide);
                m_maxProfile.solve         = Math.Max(m_maxProfile.solve, p.solve);
                m_maxProfile.solveInit     = Math.Max(m_maxProfile.solveInit, p.solveInit);
                m_maxProfile.solveVelocity = Math.Max(m_maxProfile.solveVelocity, p.solveVelocity);
                m_maxProfile.solvePosition = Math.Max(m_maxProfile.solvePosition, p.solvePosition);
                m_maxProfile.solveTOI      = Math.Max(m_maxProfile.solveTOI, p.solveTOI);
                m_maxProfile.broadphase    = Math.Max(m_maxProfile.broadphase, p.broadphase);

                m_totalProfile.step          += p.step;
                m_totalProfile.collide       += p.collide;
                m_totalProfile.solve         += p.solve;
                m_totalProfile.solveInit     += p.solveInit;
                m_totalProfile.solveVelocity += p.solveVelocity;
                m_totalProfile.solvePosition += p.solvePosition;
                m_totalProfile.solveTOI      += p.solveTOI;
                m_totalProfile.broadphase    += p.broadphase;
            }

            if (settings.drawProfile)
            {
                b2Profile p = m_world.Profile;

                b2Profile aveProfile = new b2Profile();
                if (m_stepCount > 0)
                {
                    float scale = 1.0f / m_stepCount;
                    aveProfile.step          = scale * m_totalProfile.step;
                    aveProfile.collide       = scale * m_totalProfile.collide;
                    aveProfile.solve         = scale * m_totalProfile.solve;
                    aveProfile.solveInit     = scale * m_totalProfile.solveInit;
                    aveProfile.solveVelocity = scale * m_totalProfile.solveVelocity;
                    aveProfile.solvePosition = scale * m_totalProfile.solvePosition;
                    aveProfile.solveTOI      = scale * m_totalProfile.solveTOI;
                    aveProfile.broadphase    = scale * m_totalProfile.broadphase;
                }

                m_debugDraw.DrawString(5, m_textLine, "step [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.step,
                                       aveProfile.step, m_maxProfile.step);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "collide [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.collide,
                                       aveProfile.collide, m_maxProfile.collide);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solve [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.solve,
                                       aveProfile.solve, m_maxProfile.solve);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solve init [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.solveInit,
                                       aveProfile.solveInit, m_maxProfile.solveInit);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solve velocity [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})",
                                       p.solveVelocity, aveProfile.solveVelocity, m_maxProfile.solveVelocity);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solve position [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})",
                                       p.solvePosition, aveProfile.solvePosition, m_maxProfile.solvePosition);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "solveTOI [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.solveTOI,
                                       aveProfile.solveTOI, m_maxProfile.solveTOI);
                m_textLine += 15;
                m_debugDraw.DrawString(5, m_textLine, "broad-phase [ave] (max) = {0:00000.00} [{1:000000.00}] ({2:000000.00})", p.broadphase,
                                       aveProfile.broadphase, m_maxProfile.broadphase);
                m_textLine += 15;
            }
#endif
            if (m_mouseJoint != null)
            {
                b2Vec2 p1 = m_mouseJoint.GetAnchorB();
                b2Vec2 p2 = m_mouseJoint.GetTarget();

                b2Color c = new b2Color();
                c.Set(0.0f, 1.0f, 0.0f);
                m_debugDraw.DrawPoint(p1, 4.0f, c);
                m_debugDraw.DrawPoint(p2, 4.0f, c);

                c.Set(0.8f, 0.8f, 0.8f);
                m_debugDraw.DrawSegment(p1, p2, c);
            }

            if (m_bombSpawning)
            {
                b2Color c = new b2Color();
                c.Set(0.0f, 0.0f, 1.0f);
                m_debugDraw.DrawPoint(m_bombSpawnPoint, 4.0f, c);

                c.Set(0.8f, 0.8f, 0.8f);
                m_debugDraw.DrawSegment(m_mouseWorld, m_bombSpawnPoint, c);
            }

            if (settings.drawContactPoints)
            {
                //const float32 k_impulseScale = 0.1f;
                float k_axisScale = 0.3f;

                for (int i = 0; i < m_pointCount; ++i)
                {
                    ContactPoint point = m_points[i];

                    if (point.state == b2PointState.b2_addState)
                    {
                        // Add
                        m_debugDraw.DrawPoint(point.position, 10.0f, new b2Color(0.3f, 0.95f, 0.3f));
                    }
                    else if (point.state == b2PointState.b2_persistState)
                    {
                        // Persist
                        m_debugDraw.DrawPoint(point.position, 5.0f, new b2Color(0.3f, 0.3f, 0.95f));
                    }

                    if (settings.drawContactNormals == 1)
                    {
                        b2Vec2 p1 = point.position;
                        b2Vec2 p2 = p1 + k_axisScale * point.normal;
                        m_debugDraw.DrawSegment(p1, p2, new b2Color(0.9f, 0.9f, 0.9f));
                    }
                    else if (settings.drawContactForces == 1)
                    {
                        //b2Vec2 p1 = point->position;
                        //b2Vec2 p2 = p1 + k_forceScale * point->normalForce * point->normal;
                        //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
                    }

                    if (settings.drawFrictionForces == 1)
                    {
                        //b2Vec2 tangent = b2Cross(point->normal, 1.0f);
                        //b2Vec2 p1 = point->position;
                        //b2Vec2 p2 = p1 + k_forceScale * point->tangentForce * tangent;
                        //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
                    }
                }
            }
        }
        public StarlingGameSpriteWithPhysics()
        {
            sessionid = random.Next();


            //b2Body ground_current = null;
            //b2Body air_current = null;



            #region ground_b2world
            // first frame  ... set up our physccs
            // zombies!!
            ground_b2world = new b2World(new b2Vec2(0, 0), false);
            ground_b2world.SetContactListener(
                new XContactListener()
                );

            var ground_b2debugDraw = new b2DebugDraw();

            ground_dd = new ScriptCoreLib.ActionScript.flash.display.Sprite();
            ground_dd.transform.colorTransform = new ColorTransform(0.0, 0, 1.0);



            ground_b2debugDraw.SetSprite(ground_dd);
            // textures are 512 pixels, while our svgs are 400px
            // so how big is a meter in our game world? :)
            ground_b2debugDraw.SetDrawScale(16);
            ground_b2debugDraw.SetFillAlpha(0.1);
            ground_b2debugDraw.SetLineThickness(1.0);
            ground_b2debugDraw.SetFlags(b2DebugDraw.e_shapeBit);

            ground_b2world.SetDebugDraw(ground_b2debugDraw);



            #endregion


            #region groundkarma_b2world
            // first frame  ... set up our physccs
            // zombies!!
            groundkarma_b2world = new b2World(new b2Vec2(0, 0), false);

            var groundkarma_b2debugDraw = new b2DebugDraw();

            groundkarma_dd = new ScriptCoreLib.ActionScript.flash.display.Sprite();
            groundkarma_dd.transform.colorTransform = new ColorTransform(0.0, 1.0, 0.0);



            groundkarma_b2debugDraw.SetSprite(groundkarma_dd);
            // textures are 512 pixels, while our svgs are 400px
            // so how big is a meter in our game world? :)
            groundkarma_b2debugDraw.SetDrawScale(16);
            groundkarma_b2debugDraw.SetFillAlpha(0.1);
            groundkarma_b2debugDraw.SetLineThickness(1.0);
            groundkarma_b2debugDraw.SetFlags(b2DebugDraw.e_shapeBit);

            groundkarma_b2world.SetDebugDraw(groundkarma_b2debugDraw);



            #endregion

            #region air_b2world
            // first frame  ... set up our physccs
            // zombies!!
            air_b2world = new b2World(new b2Vec2(0, 0), false);

            var air_b2debugDraw = new b2DebugDraw();

            air_dd = new ScriptCoreLib.ActionScript.flash.display.Sprite();

            // make it red!
            air_dd.transform.colorTransform = new ColorTransform(1.0, 0, 0);
            // make it slave
            air_dd.alpha = 0.3;



            air_b2debugDraw.SetSprite(air_dd);
            // textures are 512 pixels, while our svgs are 400px
            // so how big is a meter in our game world? :)
            air_b2debugDraw.SetDrawScale(16);
            air_b2debugDraw.SetFillAlpha(0.1);
            air_b2debugDraw.SetLineThickness(1.0);
            air_b2debugDraw.SetFlags(b2DebugDraw.e_shapeBit);

            air_b2world.SetDebugDraw(air_b2debugDraw);



            #endregion

            #region damage_b2world
            // first frame  ... set up our physccs
            // zombies!!
            damage_b2world = new b2World(new b2Vec2(0, 0), false);
            damage_b2world.SetContactListener(
                new XContactListener {
                DiscardSmallImpulse = false
            }
                );

            var damage_b2debugDraw = new b2DebugDraw();

            damage_dd = new ScriptCoreLib.ActionScript.flash.display.Sprite();

            // make it red!
            //air_dd.transform.colorTransform = new ColorTransform(1.0, 0, 0);
            // make it slave
            damage_dd.alpha = 0.3;



            damage_b2debugDraw.SetSprite(air_dd);
            // textures are 512 pixels, while our svgs are 400px
            // so how big is a meter in our game world? :)
            damage_b2debugDraw.SetDrawScale(16);
            damage_b2debugDraw.SetFillAlpha(0.1);
            damage_b2debugDraw.SetLineThickness(1.0);
            damage_b2debugDraw.SetFlags(b2DebugDraw.e_shapeBit);

            damage_b2world.SetDebugDraw(damage_b2debugDraw);



            #endregion

            #region smoke_b2world
            // first frame  ... set up our physccs
            // zombies!!
            smoke_b2world = new b2World(new b2Vec2(0, 0), false);

            var smoke_b2debugDraw = new b2DebugDraw();

            smoke_dd = new ScriptCoreLib.ActionScript.flash.display.Sprite();

            // make it red!
            //air_dd.transform.colorTransform = new ColorTransform(1.0, 0, 0);
            // make it slave
            smoke_dd.alpha = 0.3;



            smoke_b2debugDraw.SetSprite(air_dd);
            // textures are 512 pixels, while our svgs are 400px
            // so how big is a meter in our game world? :)
            smoke_b2debugDraw.SetDrawScale(16);
            smoke_b2debugDraw.SetFillAlpha(0.1);
            smoke_b2debugDraw.SetLineThickness(1.0);
            smoke_b2debugDraw.SetFlags(b2DebugDraw.e_shapeBit);

            smoke_b2world.SetDebugDraw(smoke_b2debugDraw);



            #endregion



            //#region obstacles
            //{
            //    var bodyDef = new b2BodyDef();

            //    bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;

            //    // stop moving if legs stop walking!
            //    bodyDef.linearDamping = 10.0;
            //    bodyDef.angularDamping = 0.3;
            //    //bodyDef.angle = 1.57079633;
            //    bodyDef.fixedRotation = true;

            //    var body = air_b2world.CreateBody(bodyDef);
            //    body.SetPosition(new b2Vec2(10, 10));

            //    var fixDef = new Box2D.Dynamics.b2FixtureDef();
            //    fixDef.density = 0.1;
            //    fixDef.friction = 0.01;
            //    fixDef.restitution = 0;


            //    fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(4);


            //    var fix = body.CreateFixture(fixDef);

            //    body.SetPosition(
            //        new b2Vec2(-8, 0)
            //    );
            //}

            //{
            //    var bodyDef = new b2BodyDef();

            //    bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;

            //    // stop moving if legs stop walking!
            //    bodyDef.linearDamping = 10.0;
            //    bodyDef.angularDamping = 0.3;
            //    //bodyDef.angle = 1.57079633;
            //    bodyDef.fixedRotation = true;

            //    var body = ground_b2world.CreateBody(bodyDef);
            //    body.SetPosition(new b2Vec2(10, 10));

            //    var fixDef = new Box2D.Dynamics.b2FixtureDef();
            //    fixDef.density = 0.1;
            //    fixDef.friction = 0.01;
            //    fixDef.restitution = 0;


            //    fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(4);


            //    var fix = body.CreateFixture(fixDef);


            //    body.SetPosition(
            //        new b2Vec2(8, -8)
            //    );
            //}

            //{
            //    var bodyDef = new b2BodyDef();

            //    bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;

            //    // stop moving if legs stop walking!
            //    bodyDef.linearDamping = 10.0;
            //    bodyDef.angularDamping = 0.3;
            //    //bodyDef.angle = 1.57079633;
            //    bodyDef.fixedRotation = true;

            //    var body = groundkarma_b2world.CreateBody(bodyDef);
            //    body.SetPosition(new b2Vec2(10, 10));

            //    var fixDef = new Box2D.Dynamics.b2FixtureDef();
            //    fixDef.density = 0.1;
            //    fixDef.friction = 0.01;
            //    fixDef.restitution = 0;


            //    fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(4);


            //    var fix = body.CreateFixture(fixDef);


            //    body.SetPosition(
            //        new b2Vec2(8, 8)
            //    );
            //}
            //#endregion


            physicstime.Start();

            this.onbeforefirstframe += (stage, s) =>
            {
                if (!disablephysicsdiagnostics)
                {
                    s.nativeOverlay.addChild(ground_dd);
                    s.nativeOverlay.addChild(groundkarma_dd);
                    s.nativeOverlay.addChild(air_dd);
                    s.nativeOverlay.addChild(damage_dd);
                }
                // 1000 / 15
                var syncframeinterval = 1000 / 15;
                var syncframesince    = 0L;
                var syncframeextra    = 0L;


                // NaN ?
                syncframeid   = 0;
                syncframetime = 0;


                var prevvelocity = 0.0;
                onframe +=
                    delegate
                {
                    // drop frames
                    //if (frameid % 2 == 0)
                    //    return;

                    var physicstime_elapsed = physicstime.ElapsedMilliseconds + syncframeextra;
                    syncframeextra = 0;

                    // physicstime_elapsed needs to be split!

                    var physicstime_elapsed_PRE = physicstime_elapsed;



                    physicstime.Restart();

                    // add up the time we are spending
                    syncframesince += physicstime_elapsed;

                    #region raise_onsyncframe
                    var raise_onsyncframe = false;
                    // time for sync frame yet?
                    if (syncframesince >= syncframeinterval)
                    {
                        // time for syncframe!
                        raise_onsyncframe = true;

                        // does it actually help us? disabled for now
                        var dx = syncframesince - syncframeinterval;
                        syncframesince = 0;

                        // Error: raise_onsyncframe: { physicstime_elapsed_PRE = 275, dx = 75, physicstime_elapsed_POST = 0 }

                        physicstime_elapsed_PRE -= dx;
                        syncframeextra          += dx;


                        // dropping frames?
                        //syncframeextra = Math.Min(syncframeextra, syncframeinterval);
                    }
                    #endregion


                    var iterations = 10;

                    syncframetime += physicstime_elapsed_PRE;

                    #region PRE Step

                    //update physics world
                    ground_b2world.Step(physicstime_elapsed_PRE / 1000.0, iterations, iterations);
                    groundkarma_b2world.Step(physicstime_elapsed_PRE / 1000.0, iterations, iterations);
                    air_b2world.Step(physicstime_elapsed_PRE / 1000.0, iterations, iterations);
                    damage_b2world.Step(physicstime_elapsed_PRE / 1000.0, iterations, iterations);
                    smoke_b2world.Step(physicstime_elapsed_PRE / 1000.0, iterations, iterations);
                    #endregion

                    ground_b2world.ClearForces();
                    groundkarma_b2world.ClearForces();
                    air_b2world.ClearForces();
                    damage_b2world.ClearForces();
                    smoke_b2world.ClearForces();


                    #region DrawDebugData ClearForces
                    if (!disablephysicsdiagnostics)
                    {
                        ground_b2world.DrawDebugData();
                        groundkarma_b2world.DrawDebugData();
                        air_b2world.DrawDebugData();
                        damage_b2world.DrawDebugData();
                        smoke_b2world.DrawDebugData();
                    }
                    #endregion

                    // syncframe
                    if (raise_onsyncframe)
                    {
                        syncframeid++;
                        this.onsyncframe(stage, s);

                        foreach (var item in units)
                        {
                            item.FeedKarma();
                        }
                    }


                    #region air_dd vs ground_dd
                    if (current != null)
                    {
                        if (current.body.GetWorld() == air_b2world)
                        {
                            air_dd.alpha    = 0.6;
                            ground_dd.alpha = 0.1;
                        }
                        else
                        {
                            air_dd.alpha    = 0.1;
                            ground_dd.alpha = 0.6;
                        }
                    }
                    #endregion

                    #region DisableDefaultContentDransformation
                    DisableDefaultContentDransformation = true;
                    {
                        var cm = new Matrix();

                        var any_movement = 0.0;

                        if (current != null)
                        {
                            cm.translate(
                                -(current.body.GetPosition().x * 16),
                                -(current.body.GetPosition().y * 16)
                                );



                            cm.rotate(-current.body.GetAngle() - Math.PI / 2 + current.CameraRotation);


                            if (current.body.GetType() == Box2D.Dynamics.b2Body.b2_dynamicBody)
                            {
                                any_movement = (
                                    current.body.GetLinearVelocity().Length() +
                                    Math.Abs(current.body.GetAngularVelocity())
                                    )

                                               / 15.0;
                            }
                            else
                            {
                                // force movement mode in a building
                                any_movement = 1.0;
                            }
                        }


                        //cm.rotate(-current.GetAngle());



                        move_zoom +=
                            (any_movement - 0.5) *
                            physicstime_elapsed * 0.004;
                        move_zoom = move_zoom.Max(0.0).Min(1.0);

                        var xinternalscale = internalscale;

                        if (disable_movezoom_and_altitude_for_scale)
                        {
                            // nop
                        }
                        else
                        {
                            xinternalscale +=
                                +0.20 * (1.0 - current.Altitude)
                                + ((1.0 - move_zoom) * 0.04);
                        }

                        var diagonal = new __vec2
                        {
                            x = stage.stageWidth,
                            y = stage.stageHeight
                        };

                        //stagescale = xinternalscale * (stage.stageWidth) / (800.0);
                        stagescale = xinternalscale * (diagonal.GetLength()) / (1000.0);


                        cm.scale(stagescale, stagescale);


                        cm.translate(
                            (stage.stageWidth * 0.5),
                            (stage.stageHeight * internal_center_y)
                            );


                        Content.transformationMatrix = cm;

                        ground_dd.transform.matrix      = cm;
                        groundkarma_dd.transform.matrix = cm;
                        air_dd.transform.matrix         = cm;
                        damage_dd.transform.matrix      = cm;
                    }
                    #endregion



                    foreach (var item in units)
                    {
                        item.ShowPositionAndAngle();

                        #region driverseat
                        if (item.driverseat != null)
                        {
                            if (item.driverseat.driver != null)
                            {
                                var driver = item.driverseat.driver;

                                driver.SetPositionAndAngle(


                                    item.body.GetPosition().x + Math.Cos(item.body.GetAngle() - Math.PI * 0.5 - item.CameraRotation) * 2.2,
                                    item.body.GetPosition().y + Math.Sin(item.body.GetAngle() - Math.PI * 0.5 - item.CameraRotation) * 2.2
                                    ,
                                    item.body.GetAngle() - item.CameraRotation
                                    );

                                driver.ShowPositionAndAngle();
                            }
                        }
                        #endregion

                        item.ApplyVelocity();
                    }
                };
            };
        }
        // http://blog.allanbishop.com/box2d-2-1a-tutorial-part-1/

        public ApplicationSprite()
        {
            _world = new b2World(new b2Vec2(0, 10), true);

            var groundBodyDef = new b2BodyDef();

            groundBodyDef.position.Set(SWF_HALF_WIDTH / PIXELS_TO_METRE,
                                       SWF_HEIGHT / PIXELS_TO_METRE - 20 / PIXELS_TO_METRE);

            var groundBody = _world.CreateBody(groundBodyDef);

            var groundBox = new b2PolygonShape();

            groundBox.SetAsBox(SWF_HALF_WIDTH / PIXELS_TO_METRE,
                               20 / PIXELS_TO_METRE);

            var groundFixtureDef = new b2FixtureDef();

            groundFixtureDef.shape    = groundBox;
            groundFixtureDef.density  = 1;
            groundFixtureDef.friction = 1;
            groundBody.CreateFixture(groundFixtureDef);

            var bodyDef = new b2BodyDef();

            bodyDef.type = b2Body.b2_dynamicBody;
            bodyDef.position.Set(SWF_HALF_WIDTH / PIXELS_TO_METRE, 4);
            var body = _world.CreateBody(bodyDef);

            var dynamicBox = new b2PolygonShape();

            dynamicBox.SetAsBox(1, 1);

            var fixtureDef = new b2FixtureDef();

            fixtureDef.shape    = dynamicBox;
            fixtureDef.density  = 1;
            fixtureDef.friction = 0.3;

            body.CreateFixture(fixtureDef);

            var debugSprite = new Sprite();

            addChild(debugSprite);
            var debugDraw = new b2DebugDraw();

            debugDraw.SetSprite(debugSprite);
            debugDraw.SetDrawScale(PIXELS_TO_METRE);
            debugDraw.SetLineThickness(1.0);
            debugDraw.SetAlpha(1);
            debugDraw.SetFillAlpha(0.4);
            debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
            _world.SetDebugDraw(debugDraw);


            // Add event for main loop

            this.stage.enterFrame +=
                delegate
            {
                var timeStep           = 1 / 30.0;
                var velocityIterations = 6;
                var positionIterations = 2;

                _world.Step(timeStep, velocityIterations, positionIterations);
                _world.ClearForces();
                _world.DrawDebugData();
            };
        }
        public ApplicationSprite()
        {
            #region AtInitializeConsoleFormWriter

            var w         = new __OutWriter();
            var o         = Console.Out;
            var __reentry = false;

            var __buffer = new StringBuilder();

            w.AtWrite =
                x =>
            {
                __buffer.Append(x);
            };

            w.AtWriteLine =
                x =>
            {
                __buffer.AppendLine(x);
            };

            Console.SetOut(w);

            this.AtInitializeConsoleFormWriter = (
                Action <string> Console_Write,
                Action <string> Console_WriteLine
                ) =>
            {
                try
                {
                    w.AtWrite =
                        x =>
                    {
                        o.Write(x);

                        if (!__reentry)
                        {
                            __reentry = true;
                            Console_Write(x);
                            __reentry = false;
                        }
                    };

                    w.AtWriteLine =
                        x =>
                    {
                        o.WriteLine(x);

                        if (!__reentry)
                        {
                            __reentry = true;
                            Console_WriteLine(x);
                            __reentry = false;
                        }
                    };

                    Console.WriteLine("flash Console.WriteLine should now appear in JavaScript form!");
                    Console.WriteLine(__buffer.ToString());
                }
                catch
                {
                }
            };
            #endregion



            var SCALE    = 15;                    //how many pixels in a meter
            var WIDTH_M  = DefaultWidth / SCALE;  //world width in meters. for this example, world is as large as the screen
            var HEIGHT_M = DefaultHeight / SCALE; //world height in meters

            //initialize font to draw text with
            //var font=new gamejs.font.Font('16px Sans-serif');

            //key bindings
            //var BINDINGS={accelerate:gamejs.event.K_UP,
            //              brake:gamejs.event.K_DOWN,
            //              steer_left:gamejs.event.K_LEFT,
            //               steer_right:gamejs.event.K_RIGHT};



            //initialize display
            //var display = gamejs.display.setMode([WIDTH_PX, HEIGHT_PX]);

            //SET UP B2WORLD
            var b2world = new b2World(new b2Vec2(0, 0), false);

            //set up box2d debug draw to draw the bodies for us.
            //in a real game, car will propably be drawn as a sprite rotated by the car's angle
            var debugDraw = new b2DebugDraw();
            debugDraw.SetSprite(this);
            debugDraw.SetDrawScale(SCALE);
            debugDraw.SetFillAlpha(0.5);
            debugDraw.SetLineThickness(1.0);
            debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
            b2world.SetDebugDraw(debugDraw);

            var wheels = new[] {
                //top left
                new Wheel(b2world: b2world, x: -1, y: -1.2, width: 0.4, length: 0.8, revolving: true, powered: true),

                //top right
                new Wheel(b2world: b2world, x: 1, y: -1.2, width: 0.4, length: 0.8, revolving: true, powered: true),

                //back left
                new Wheel(b2world: b2world, x: -1, y: 1.2, width: 0.4, length: 0.8, revolving: false, powered: false),

                //back right
                new Wheel(b2world: b2world, x: 1, y: 1.2, width: 0.4, length: 0.8, revolving: false, powered: false),
            };
            Func <double, double, double[]> ff = (a, b) => { return(new double[] { a, b }); };

            ////initialize car
            var car = new Car(
                b2world: b2world,
                width: 2,
                length: 4,
                position: ff(10, 10),
                angle: 180,
                power: 60,
                max_steer_angle: 20,
                max_speed: 60,
                wheels: wheels
                );

            var xcar = new Car(
                b2world: b2world,
                width: 2,
                length: 4,
                position: ff(5, 10),
                angle: 180,
                power: 60,
                max_steer_angle: 20,
                max_speed: 60,
                wheels: wheels
                );


            //initialize some props to bounce against
            var props = new List <BoxProp>();


            //outer walls
            props.Add(new BoxProp(b2world, size: ff(WIDTH_M, 1), position: ff(WIDTH_M / 2, 0.5)));
            props.Add(new BoxProp(b2world, size: ff(1, HEIGHT_M - 2), position: ff(0.5, HEIGHT_M / 2)));
            props.Add(new BoxProp(b2world, size: ff(WIDTH_M, 1), position: ff(WIDTH_M / 2, HEIGHT_M - 0.5)));
            props.Add(new BoxProp(b2world, size: ff(1, HEIGHT_M - 2), position: ff(WIDTH_M - 0.5, HEIGHT_M / 2)));

            //pen in the center
            var center = new double[] { WIDTH_M / 2, HEIGHT_M / 2 };
            props.Add(new BoxProp(b2world, size: ff(1, 6), position: ff(center[0] - 3, center[1])));
            props.Add(new BoxProp(b2world, size: ff(1, 6), position: ff(center[0] + 3, center[1])));
            props.Add(new BoxProp(b2world, size: ff(5, 1), position: ff(center[0], center[1] + 2.5)));

            var frameid = 0;

            var KEYS_DOWN = new Dictionary <Keys, bool> {
                { Keys.Left, false },
                { Keys.Up, false },
                { Keys.Right, false },
                { Keys.Down, false },
            }; //keep track of what keys are held down by the player


            this.stage.keyDown +=
                e =>
            {
                Console.WriteLine("keyDown " + new { e.keyCode });
                KEYS_DOWN[(Keys)e.keyCode] = true;
            };

            this.stage.keyUp +=
                e =>
            {
                Console.WriteLine("keyUp " + new { e.keyCode });
                KEYS_DOWN[(Keys)e.keyCode] = false;
            };


            #region tick
            Action <double> tick = (msDuration) =>
            {
                frameid++;

                //if (frameid > 1)
                //    return;

                //Console.WriteLine(new { frameid });
                //GAME LOOP

                //handle events. Key status (depressed or no) is tracked in via KEYS_DOWN associative array
                //gamejs.event.get().forEach(function(event){
                //    //key press
                //    if (event.type === gamejs.event.KEY_DOWN) KEYS_DOWN[event.key] = true;
                //    //key release
                //    else if (event.type === gamejs.event.KEY_UP) KEYS_DOWN[event.key] = false;
                //});

                //set car controls according to player input
                if (KEYS_DOWN[Keys.Up])
                {
                    car.accelerate = ACC_ACCELERATE;
                }
                else if (KEYS_DOWN[Keys.Down])
                {
                    car.accelerate = ACC_BRAKE;
                }
                else
                {
                    car.accelerate = ACC_NONE;
                }

                if (KEYS_DOWN[Keys.Right])
                {
                    car.steer = STEER_RIGHT;
                }
                else if (KEYS_DOWN[Keys.Left])
                {
                    car.steer = STEER_LEFT;
                }
                else
                {
                    car.steer = STEER_NONE;
                }

                ////update car
                car.update(msDuration);

                //update physics world
                b2world.Step(msDuration / 1000.0, 10, 8);

                //clear applied forces, so they don't stack from each update
                b2world.ClearForces();

                //fill background
                //gamejs.draw.rect(display, '#FFFFFF', new gamejs.Rect([0, 0], [WIDTH_PX, HEIGHT_PX]),0)

                //let box2d draw it's bodies
                b2world.DrawDebugData();

                //fps and car speed display
                //display.blit(font.render('FPS: '+parseInt((1000)/msDuration)), [25, 25]);
                //display.blit(font.render('SPEED: '+parseInt(Math.ceil(car.getSpeedKMH()))+' km/h'), [25, 55]);
                //Console.WriteLine(new { frameid } + " done!");
            };

            ////gamejs.time.fpsCallback(tick, this, 60);
            var sw = new Stopwatch();
            sw.Start();

            this.enterFrame +=
                delegate
            {
                tick(sw.ElapsedMilliseconds);
                sw.Restart();
            };
            #endregion
        }