Box2D Forums

It is currently Fri Oct 31, 2014 7:07 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Wed Oct 05, 2011 7:10 am 
Offline

Joined: Wed Oct 05, 2011 5:02 am
Posts: 5
Hello

http://projects.omikrosys.com/gaming/racing/moving.html

If you move the car using arrow keys , the wheels would go out of track and start hanging out of the main car body.

The wheel should stick to its position on the wheel.
What is wrong with the code :

Code:
var b2Vec2 = Box2D.Common.Math.b2Vec2
   ,  b2AABB = Box2D.Collision.b2AABB
   ,   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
   ,     b2MouseJointDef =  Box2D.Dynamics.Joints.b2MouseJointDef
   ,     b2Shape = Box2D.Collision.Shapes.b2Shape
   ,   b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef
   ,   b2Joint = Box2D.Dynamics.Joints.b2Joint
   ,   b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef
   ;
         

var game = {
   
   'key_down' : function(e)
   {
      var code = (e.keyCode);
      
      var v = 100;
      
      //left
      if(code == 37)
      {
         steering_angle = -1 * max_steer_angle;
      }
      //up
      if(code == 38)
      {
         engine_speed = -1*top_speed;
      }
      
      //right
      if(code == 39)
      {
         steering_angle = max_steer_angle;
      }
      
      //down
      if(code == 40)
      {
         engine_speed = top_speed;
      }
   } ,
   
   'key_up' : function(e)
   {
      engine_speed = 0;
      steering_angle = 0;
   } ,
   
};

var engine_speed = 0;
var steering_angle = 0;
var steer_speed = 1.5;
var max_steer_angle = Math.PI/3;
var top_speed = 5000;
var world;
var ctx;
var canvasWidth;
var canvasHeight;
var canvasTop;
var canvasLeft;
var car;

/*
   Draw a world
   this method is called in a loop to redraw the world
*/   
function drawWorld(world, context)
{
   for (var j = world.GetJointList() ; j ; j = j.GetNext())
   {
      drawJoint(j, context);
   }
   
   
   for( var b = world.GetBodyList() ; b ; b = b.GetNext())
   {
      for( var f = b.GetFixtureList() ; f != null ; f = f.GetNext())
      {
         var shape = f.GetShape();
         var shapeType = shape.GetType();
         if(isNaN(b.GetPosition().x))
         {
            alert('Invalid Position : ' + b.GetPosition().x);
         }
         else
         {
            drawShape(b , shape , context);
         }
      }
   }
   
   ctx.font = 'bold 18px arial';
   ctx.textAlign = 'center';
   ctx.fillStyle = '#000000';
   ctx.fillText("Use arrow keys to move the car", 400, 20);
   //ctx.font = 'bold 14px arial';
   //ctx.fillText("Performance will vary by browser", 400, 40);

}

function drawJoint(joint, context)
{
   var b1 = joint.GetBodyA();
   var b2 = joint.GetBodyB();
   
   var x1 = b1.GetPosition();
   var x2 = b2.GetPosition();
   
   var p1 = joint.GetAnchorA();
   var p2 = joint.GetAnchorB();
   context.strokeStyle = '#00eeee';
   context.beginPath();
   
   switch (joint.m_type)
   {
      case b2Joint.e_distanceJoint:
         context.moveTo(p1.x, p1.y);
         context.lineTo(p2.x, p2.y);
         break;
   
      case b2Joint.e_pulleyJoint:
         // TODO
         break;
   
      default:
         if (b1 == world.m_groundBody)
         {
            context.moveTo(p1.x, p1.y);
            context.lineTo(x2.x, x2.y);
         }
         
         else if (b2 == world.m_groundBody)
         {
            context.moveTo(p1.x, p1.y);
            context.lineTo(x1.x, x1.y);
         }
         
         else
         {
            context.moveTo(x1.x, x1.y);
            context.lineTo(p1.x, p1.y);
            context.lineTo(x2.x, x2.y);
            context.lineTo(p2.x, p2.y);
         }
         
         break;
   }
   
   context.stroke();
}

function drawShape(body , shape, context)
{
   context.strokeStyle = '#000';
   
   if (shape.density == 1.0)
   {
      context.fillStyle = "red";
   }
   
   else
   {
      context.fillStyle = "#fff";
   }
   
   context.beginPath();
   
   switch (shape.GetType())
   {
      case b2Shape.e_polygonShape:
      {
         var poly = shape;
         var vert = shape.GetVertices();
         
         var position = body.GetPosition();
         //b2Math.MulMV(b.m_xf.R , vert[0]);
         var tV = position.Copy();
         var a = vert[0].Copy();
         a.MulM( body.GetTransform().R );
         tV.Add(a);
         
         //var tV = b2Math.AddVV( position , b2Math.MulMV(b.m_xf.R, vert[0]) );
         
         context.moveTo(tV.x, tV.y);
         
         for (var i = 0; i < vert.length; i++)
         {
            var v = vert[i].Copy();
            //v.MulM( body.m_xf.R );
            v.MulM( body.GetTransform().R );
            v.Add(position);
            //var v = b2Math.AddVV(position, b2Math.MulMV(b.m_xf.R, vert[i]));
            context.lineTo(v.x, v.y);
         }
         
         context.lineTo(tV.x, tV.y);
         
         /*
         //m_position is a (x, y) vector having positions of the body
         var tV = b2Math.AddVV( poly.m_position , b2Math.b2MulMV(poly.m_R , poly.m_vertices[0]) );
         context.moveTo(tV.x, tV.y);
         
         //for square things there are 4 vertices :)
         //for sqyare things m_r is 1 , 0 | 0 , 1 matrix ?? what does it means ? unit matrix of order 2 ?
         
         for (var i = 0; i < poly.m_vertexCount; i++)
         {
            var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
            context.lineTo(v.x, v.y);
         }
         
         context.lineTo(tV.x, tV.y);*/
      }
      
      break;
   }
   //this will fill a shape
   //context.fill();
   
   //this will create the outline of a shape
   context.stroke();
}

/*
   Create box2d world object
*/
function createWorld()
{
   var gravity = new b2Vec2(0, 0);
   var doSleep = true;
   
   world = new b2World(gravity , doSleep);
   
   return world;
}      


/*
   Create standard boxes of given height , width at x,y
*/
function createBox(world, x, y, width, height, options)
{
    //default setting
   options = $.extend(true, {
      'density' : 1.0 ,
      'friction' : 1.0 ,
      'restitution' : 0.2 ,
      
      'linearDamping' : 0.0 ,
      'angularDamping' : 0.0 ,
      
      'gravityScale' : 1.0 ,
      'type' : b2Body.b2_dynamicBody
   }, options);
   
   var body_def = new b2BodyDef();
   var fix_def = new b2FixtureDef;
   
   fix_def.density = options.density;
   fix_def.friction = options.friction;
   fix_def.restitution = options.restitution;
   
   fix_def.shape = new b2PolygonShape();
   
   fix_def.shape.SetAsBox( width , height );
   
   body_def.position.Set(x , y);
   
   body_def.linearDamping = options.linearDamping;
   body_def.angularDamping = options.angularDamping;
   
   body_def.type = options.type;
   body_def.gravityScale = 0;
   
   var b = world.CreateBody( body_def );
   var f = b.CreateFixture(fix_def);
   
   return b;
}

/*
   This method will draw the world again and again
   called by settimeout , self looped
*/
function step(cnt)
{
   var stepping = false;
   
   //fps = 60 , time steps
   var fps = 60;
   var timeStep = 1.0/fps;
   var iteration = 1;
   
   //move the world ahead , step ahead man!!
   world.Step(timeStep, iteration);
   update_car();
   
   //first clear the canvas
   ctx.clearRect( 0 , 0 , game.canvas_width, game.canvas_height );
   
   //redraw the world
   drawWorld(world , ctx);
   
   //call this function again after 10 seconds
   setTimeout('step(' + (cnt || 0) + ')', 10);
}

// main entry point
$(function()
{
   //first create the world
   world = createWorld();
   
   game.ctx = ctx = $('#canvas').get(0).getContext('2d');
   var canvas = $('#canvas');
   
   game.canvas_width = canvasWidth = parseInt(canvas.width());
   game.canvas_height = canvasHeight = parseInt(canvas.height());
   
   //canvasTop = parseInt(canvasElm.style.top);
   //canvasLeft = parseInt(canvasElm.style.left);
   
   create_car();
   
   $('body').keydown(function(e)
   {
      game.key_down(e);
   });
   
   $('body').keyup(function(e)
   {
      game.key_up(e);
   });
   
   step();
});

function create_car()
{
   car_pos = new b2Vec2(300,300);
   car_dim = new b2Vec2(20 ,35);
   car = createBox(world , car_pos.x , car_pos.y , car_dim.x , car_dim.y , true , {});
   
   var wheel_dim = new b2Vec2(4 , 8);
   
   
   //front wheels
   left_wheel = createBox(world , car_pos.x - car_dim.x , car_pos.y - car_dim.y / 2 , wheel_dim.x , wheel_dim.y , {});
   right_wheel = createBox(world , car_pos.x + car_dim.x, car_pos.y - car_dim.y / 2 , wheel_dim.x , wheel_dim.y , {});
   
   //rear wheels
   left_rear_wheel = createBox(world , car_pos.x - car_dim.x , car_pos.y + car_dim.y / 2 , wheel_dim.x , wheel_dim.y , {});
   right_rear_wheel = createBox(world , car_pos.x + car_dim.x, car_pos.y + car_dim.y / 2 , wheel_dim.x , wheel_dim.y , {});
   
   var front_wheels = {'left_wheel' : left_wheel , 'right_wheel' : right_wheel};
   
   for (var i in front_wheels)
   {
      var wheel = front_wheels[i];
      
      var joint_def = new b2RevoluteJointDef();
      joint_def.Initialize(car , wheel, wheel.GetWorldCenter());
   
      //after enablemotor , setmotorspeed is used to make the joins rotate , remember!
      joint_def.enableMotor = true;
      joint_def.maxMotorTorque = 100000;
      
      car[i + '_joint'] = world.CreateJoint(joint_def);
   }
   
   var rear_wheels = {'left_rear_wheel' : left_rear_wheel , 'right_rear_wheel' : right_rear_wheel};
   
   for (var i in rear_wheels)
   {
      var wheel = rear_wheels[i];
      
      var joint_def = new b2PrismaticJointDef();
      joint_def.Initialize( car , wheel, wheel.GetWorldCenter(), new b2Vec2(1,0) );
   
      joint_def.enableLimit = true;
      joint_def.lowerTranslation = joint_def.upperTranslation = 0.0;
      
      car[i + '_joint'] = world.CreateJoint(joint_def);
   }
   
   car.left_wheel = left_wheel;
   car.right_wheel = right_wheel;
   car.left_rear_wheel = left_rear_wheel;
   car.right_rear_wheel = right_rear_wheel;
   
   
   return car;
}

//This function applies a "friction" in a direction orthogonal to the body's axis.
function killOrthogonalVelocity(b)
{
   var localPoint = new b2Vec2(0,0);
   var velocity = b.GetLinearVelocityFromLocalPoint(localPoint);
 
   var sidewaysAxis = b.GetTransform().R.col2.Copy();
   
   //multiply vector with a constant;
   sidewaysAxis.Multiply( velocity.x*sidewaysAxis.x + velocity.y*sidewaysAxis.y)
 
   b.SetLinearVelocity(sidewaysAxis); //b.GetWorldPoint(localPoint));
}

function update_car()
{
   killOrthogonalVelocity(car.left_wheel);
   killOrthogonalVelocity(car.right_wheel);
   killOrthogonalVelocity(car.left_rear_wheel);
   killOrthogonalVelocity(car.right_rear_wheel);
 
   var wheels = ['left' , 'right'];
   
   //Driving
   for(var i in wheels)
   {
      var d = wheels[i] + '_wheel';
      var wheel = car[d];
      
      var direction = wheel.GetTransform().R.col2.Copy();
      direction.Multiply( engine_speed );
      
      wheel.ApplyForce( direction , wheel.GetPosition() );
   }   
   
   //Steering
   for(var i in wheels)
   {
      var d = wheels[i] + '_wheel_joint';
      var wheel_joint = car[d];
      
      //set the motor speed
      var mspeed;
      //max speed - current speed , should be the motor speed , so when max speed reached , speed = 0;
      mspeed = steering_angle - wheel_joint.GetJointAngle();
      wheel_joint.SetMotorSpeed(mspeed * steer_speed);
   }
   
}


Regards
Silver


Top
 Profile  
 
PostPosted: Wed Oct 05, 2011 9:19 pm 
Offline

Joined: Wed Oct 05, 2011 5:02 am
Posts: 5
OK , I fixed it. world step iteration was incorrect.

world.Step(timeStep, 8 , 3); solved it.

Silver


Top
 Profile  
 
PostPosted: Wed Oct 05, 2011 10:17 pm 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1965
Location: Tokyo
Great!
Just a note for the future - I don't think anyone is going to look through an enormous block of code like that to answer the very broad question "What is wrong?" You'll have to narrow it down to a more reasonable scope first.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group