Using to move an object with arrow keys using ApplyForce is not working

577 Views Asked by At

part of learning game coding in javascript using box2d I am trying to just move a rectangular body (thinking as a Car) in 4 directions using arrow key events.

For this I created a no-gravity world with static body (which are 2 parlallel edges) as road and one dynamic body (rectangle) and using ApplyImpulse function.

But I see it is not moving the rectangle body at all. Honestly no clue why it is not working.

Below is my complete code. Sorry for bothering with full code

<html>
<head>      
 <style>
   #gcrCanvas{
      border:1px #000000 solid;
  }
</style>
</head>

<body>
<div id="canvasWrapper" >
  <canvas id="gcrCanvas" width="900" height="400" tabindex="0"></canvas>
</div> 

  <input type="button"  onclick="gameObj.init()" />

</body>
<script type="text/javascript" src="Box2dWeb-2.1.a.3.min.js"></script>
<script type="text/javascript">

 var box2dVars = {
   b2Vec2:Box2D.Common.Math.b2Vec2,
   b2BodyDef: Box2D.Dynamics.b2BodyDef,
   b2Body: Box2D.Dynamics.b2Body,
   b2FixtureDef: Box2D.Dynamics.b2FixtureDef,
   b2Fixture: Box2D.Dynamics.b2Fixture,
   b2World: Box2D.Dynamics.b2World,
   b2MassData: Box2D.Collision.Shapes.b2MassData,
   b2PolygonShape: Box2D.Collision.Shapes.b2PolygonShape,
   b2CircleShape: Box2D.Collision.Shapes.b2CircleShape,
   b2DebugDraw: Box2D.Dynamics.b2DebugDraw       
 };

 var gameObj = {
      world:null,     
  canvasContext:null,
  debugDraw:null,
      carX:12,
  carY:12,
  scale: 30,
  carBody:null,

  init: function(){
    var cavnasDiv = document.getElementById("canvasWrapper");
    var canvas = document.getElementById("gcrCanvas");
    canvasContext = canvas.getContext("2d");

   cavnasDiv.addEventListener("keydown", gameObj.carMotionHandler);

   gameObj.world = new box2dVars.b2World(
           new box2dVars.b2Vec2(0, 0)    //gravity
        ,  true                 //allow sleep
     );


     gameObj.debugDraw = new box2dVars.b2DebugDraw;
     gameObj.debugDraw.SetSprite(canvasContext);
     gameObj.debugDraw.SetDrawScale(gameObj.scale);
     gameObj.debugDraw.SetFillAlpha(0.3);
     gameObj.debugDraw.SetLineThickness(1.0);
     gameObj.debugDraw.SetFlags(box2dVars.b2DebugDraw.e_shapeBit |
           box2dVars.b2DebugDraw.e_jointBit);
     gameObj.world.SetDebugDraw(gameObj.debugDraw);

     gameObj.createRoad();
     gameObj.createCar();
     gameObj.game_loop();

    },

createRoad: function(){
   var roadBodyDef = new box2dVars.b2BodyDef();
  roadBodyDef.type = box2dVars.b2Body.b2_staticBody;
   roadBodyDef.position.Set(0,0);              
       var roadFixDef = new box2dVars.b2FixtureDef;      
       roadFixDef.density = 1.0;
       roadFixDef.friction = 0.5;
       roadFixDef.restitution = 0.7;

       roadFixDef.shape = new box2dVars.b2PolygonShape;
       roadFixDef.shape.SetAsEdge(new box2dVars.b2Vec2(8,20),
                 new box2dVars.b2Vec2(8,0));
       gameObj.world.CreateBody(roadBodyDef).CreateFixture(roadFixDef);
       roadFixDef.shape.SetAsEdge(new box2dVars.b2Vec2(20,20),
           new box2dVars.b2Vec2(20,0));
   gameObj.world.CreateBody(roadBodyDef).CreateFixture(roadFixDef);
    },

   createCar: function(){
       var carBodyDef = new box2dVars.b2BodyDef();
       carBodyDef.type = box2dVars.b2Body.b2_dynamicBody;
       carBodyDef.position.Set(gameObj.carX, gameObj.carY);

       var carFixDef = new box2dVars.b2FixtureDef;
       carFixDef.density = 1.0;
       carFixDef.friction = 0.5;
       carFixDef.restitution = 0.7;

       carFixDef.shape = new box2dVars.b2PolygonShape;
       carFixDef.shape.SetAsBox(0.5, 0.5);
       gameObj.carBody = gameObj.world.CreateBody(carBodyDef);
       gameObj.carBody.CreateFixture(carFixDef);
    },

updateCar: function(){
   **gameObj.carBody.ApplyImpulse(
           new box2dVars.b2Vec2(gameObj.carX*gameObj.scale,
                gameObj.carY*gameObj.scale),
        gameObj.carBody.GetWorldCenter());**
    },


    game_loop:function(){
        var fps = 60;
        var time_step = 1.0/fps;
        gameObj.updateCar();
        gameObj.world.Step(time_step , 8 , 3);         
        gameObj.world.ClearForces();

        gameObj.drawCanvas();

        setTimeout('gameObj.game_loop', 1000/60);
   },

    drawCanvas: function(){
        gameObj.world.DrawDebugData();
    },

    carMotionHandler: function(event){      
        console.log(gameObj.carBody.GetWorldCenter());
        switch(event.keyCode)
       {
           case 37: //left arrow key                       
                   break;
           case 38: //up arrow key
                   gameObj.carX++;                     
                   break;
           case 39: //right arrow key
                   break;
           case 40: //left arrow key
                   break;
       }          
    }       
  }; 

 </script>    
</html>
1

There are 1 best solutions below

2
On BEST ANSWER

First problem: your game loop isn't running. setTimeout('gameObj.game_loop', 1000/60) simply accesses the value of game_loop 60 times per second. If you drop the quotes, it will actually run: setTimeout(gameObj.game_loop, 1000/60).

Fixing this will allow your square to move, but there are a few other serious issues.

Second problem: you use carX and carY for both initial position and rate of acceleration.

Third problem: you apply acceleration (via ApplyImpulse) with every loop of game_loop, so your square very quickly (i.e., within a few milliseconds) is travelling hundreds of units per second and instantly leaves the screen.