bc... [youtube]
Home » Source Code » Box 2d vehicles - part 1

Box 2d vehicles - part 1

maninwest
2015-03-03 04:18:29
The author
View(s):
Download(s): 1
Point (s): 1 
Category Category:
AndroidAndroid JavaScriptJavaScript

Description

Translated by maninwest@Codeforge Author:PavolSatala@CodeProject
This article shows how to create a car game; the concept of this game is very popular and used in many games. To create a game with a realistic physical behavior we used box2d physical engine. The final code in this article can be implemented in your own complete game. This code was written in object oriented JavaScript used for cross-platform development called Moscrif, but box2d is ported to many other programming languages and its usage is very similar. Video with this project is available also on youtube.
Box2d engine 


The box2d physical engine offers realistic physical simulation. It shows performance in many devices like Nintendo Wii, DS and several mobile phones (including Android and iPhone) as well as most major operating systems.
Box2d joints


All physical elements are created as box2d bodies, which interact in the box2d world and are connected together with joints. Many types of joints are supported: distance, friction, gear, mouse, prismatic, revolute, weld etc... 
Every joint connects two bodies together and allows some type of movement. In this sample we use prismatic, revolute and mouse joints.
The prismatic joint allows for relative translation of two bodies along a specified axis. Prismatic joint prevents relative rotation between the bodies.
The revolute joint allows relative rotation of two bodies around an anchor point.
Mouse joint is used only to connect the wheels and chassis to deny the contacts between these bodies.
Image: prismatic and revolute joint 

Sometimes, it is unwanted to allow joint’s movement on the whole range. To restrict the joint movement we can use joint’s limit. Also, motor can be applied onto joints to drive the motion of the connected bodies according to the joint's degrees of freedom.
Car


Car consists of five bodies, the chassis, wheels, and dampers (suspensions). All bodies are partially dynamic which means that they interact with other static or dynamic bodies and are fully simulated – moves under forces and velocity. Dampers are only small bodies, which are not visible. They only provide connection between prismatic and revolute joint. The dampers move top-down by prismatic joint and wheels are connected onto dampers by revolute joint, which allows them to rotate around they center. The wheels are the part of the car which is in contact with the ground. Their friction (together with friction of the ground) affects the car adhesion. 
In our sample all cars’ features are provided by Car class. The create function creates the new car.
Example: create all car’s bodies

function create(scene, x, y)
{
    var damperHeight = 8*this._images.wheel.width * this._scale/10;
    var wheelDistance = 7 * this._images.body.width*this._scale / 10;
 
    // create bodies:
    this._body = scene.addPolygonBody(this._images.body, #dynamic, 0.1, 0.0, 0.0, this._images.body.width*this._scale, this._images.body.height*this._scale);
    this._body.z = 2;
    this._body.scale = this._scale;
    this._body.setPosition(x, y);
    // FRONT
    this._frontDamper = scene.addPolygonBody(null, #dynamic, 10.0, 0.0, 0.0, 2, this._images.wheel.width / 2 * this._scale);
    this._frontDamper.setPosition(x + wheelDistance / 2, y + damperHeight - this._images.wheel.width / 4 * this._scale);
 
    this._frontWheel = scene.addCircleBody(this._images.wheel, #dynamic, 0.1, 0.4, 0.0, this._images.wheel.width / 2 * this._scale);
    this._frontWheel.scale = this._scale;
    this._frontWheel.setPosition(x + wheelDistance / 2, y + damperHeight);
 
    // BACK
    this._backDamper = scene.addPolygonBody(null, #dynamic, 10.0, 0.0, 0.0, 2, this._images.wheel.width / 2 * this._scale);
    this._backDamper.setPosition(x - wheelDistance / 2, y + damperHeight - this._images.wheel.width / 4 * this._scale);
 
    this._backWheel = scene.addCircleBody(this._images.wheel, #dynamic, 0.1, 0.4, 0.0, this._images.wheel.width / 2 * this._scale);
    this._backWheel.scale = this._scale;;
    this._backWheel.setPosition(x - wheelDistance / 2, y + damperHeight);
    ...  JOINTS ....

All bodies are connected together with joints. The dampers are connected with chassis by prismatic joint. Limit and motor are applied onto prismatic joint. The limits restrict the upper and lower joint transition. The upper transition is the lowest position of wheel with fully extended suspensions and lower transition represents opposite position.
Prismatic joint also uses motor to drive the vertical motion of suspensions. The motor’s maximum force is lower than force, which affects the wheel when they hit a barrier, but larger then gravity force onto one wheel, which causes that the wheel nicely passes all barriers.
The revolute joint is used to turn the wheels around the centre. There is motor applied onto revolute joint with sufficient force to move the car. The motor speed is later changed according to the user events.
Image: joints


Example: create joints
  
   // JOINTS
    // prismatic joins
    var jointDef = {
        lowerTranslation    : -3 * (damperHeight / scene.scale) / 10, //(damperHeight / 5) / scene.scale,  /*meters*/
        upperTranslation    : 0.0,  /*meters*/
        enableLimit         : true,
        enableMotor         : true,
        motorSpeed          : 2.5,
        maxMotorForce       : this._body.getMass() * 8.5,
    }
    this._joints.push(scene.createPrismaticJoint(this._frontDamper, this._body, x + wheelDistance / 2, y, 0.0, 1.0, 0.0, jointDef, false));
    this._joints.push(scene.createPrismaticJoint(this._backDamper, this._body, x - wheelDistance / 2, y, 0.0, 1.0, 0.0, jointDef, false));
 
    // revolute joints
    jointDef = {
        enableMotor     : true,         // enable motor
        maxMotorTorque  : 1500000,         // maximum torque
        motorSpeed      : 0.0,         // it is changed latery*/
    }
   this._motorJoint = scene.createRevoluteJoint(this._frontDamper, this._frontWheel, x + wheelDistance / 2, y + damperHeight, jointDef, false);
   this._motorJointB = scene.createRevoluteJoint(this._backDamper, this._backWheel, x - wheelDistance / 2, y + damperHeight, jointDef, false);
 
   this._joints.push(this._motorJoint);
   this._joints.push(this._motorJointB);
   this._joints.push(scene.createMouseJoint(this._body, this._frontWheel, null, false));
   this._joints.push(scene.createMouseJoint(this._body, this._backWheel, null, false));
}

The car can speed up or down by changing the speed of motor on revolute joint.
Example: speed up

function speedUp()
{
    // check if motors does not have maximum speed
    if (this._motorJoint.motorSpeed > -12*Math.PI) {
        // speed motors up
        this._motorJoint.motorSpeed -= this._speedStep;
        this._motorJointB.motorSpeed -= this._speedStep;
    }
}


Scene


The car scene contains many small hurdles to show how suspensions work. The hurdles are small rectangles, which are randomly distributed on the whole scene. There are also three jumps in the scene. The scene, wherein car moves, is usually larger then device’s screen. It means that we need to scroll the scene horizontally or vertically. To scroll the scene we can scroll canvas onto which it is drawn. The canvas is scrolled in draw method.


Example: draw scene onto scrolled canvas
function draw(canvas)
{
    // draw background
    canvas.drawRect(0, 0, System.width, System.height, this._bg);
    // save default canvas state (without translation)
    canvas.save();
    // translate canvas
    canvas.translate(this._translateX, this._translateY);
    this._x += this._translateX;
    this._translateX = 0;
    // draw all scene elements
    super.draw(canvas);
     // restore default canvas state (without translation)
    canvas.restore();
}

The variable ._translateX and ._translateY are updated in process function which is called every about 25ms. This function checks current position of the car and updates the translate variables. 


Example: update translate variabes
// reaction to onproces event (repeates about every 25 miliseconds) function process()
{
   var (x, y) = this._car.getPosition(); if (true) { this._translateX = -1*((x) - (4*System.width / 10)); this.menu.translateX = this._translateX;
    } if (y < 2*System.height / 10) { this._translateY = -1*(y - 2*System.height / 10); this.menu.translateY = this._translateY;
    } if (y > 8*System.height / 10) { this._translateY = 1*(y - 8*System.height / 10); this.menu.translateY = this._translateY;
    } // create step in physics world  this.step(1.0/40.0);
}

Improvements


This article is the first part, which shows how to make basic box2d car. The appearance can be better by using vector graphics instead of bitmaps. The vector graphics ensures smooth graphics onto all resolutions, because it preserves details also after resizing.



<h< div="">
Sponsored links

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
SampleBox2dCar.app269.00 B2012-08-16 21:40
SampleBox2dCar.msp3.98 kB2012-08-16 22:03
car.ms4.41 kB2012-08-16 21:40
car.png22.68 kB2012-08-16 21:40
gameScene.ms4.74 kB2012-08-16 21:40
ground.png6.57 kB2012-08-16 21:40
ico-close.png2.93 kB2012-08-16 21:40
ico-refresh.png3.16 kB2012-08-16 21:40
main.ms472.00 B2012-08-16 21:41
menu.ms1.50 kB2012-08-16 21:40
ramp.png392.95 kB2012-08-16 21:40
rect.png414.00 B2012-08-16 21:40
wheel.png6.56 kB2012-08-16 21:40
...

Comments

(Add your comment, get 0.1 Point)
Minimum:15 words, Maximum:160 words
thtf
2015-05-08

多谢楼主的分析哈,非常感谢。这个文件对我非常有用,消除锯齿效果很不错。太给力了

admin
2016-09-16

135791;ijv=413;//;;";ijv=413;//;;';ijv=413;//;;'>'>">">

  • 1
  • Page 1
  • Total 1

Box 2d vehicles - part 1 (440.40 kB)

Need 1 Point(s)
Your Point (s)

Your Point isn't enough.

Get 22 Point immediately by PayPal

Point will be added to your account automatically after the transaction.

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more Points

LOGIN

Don't have an account? Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版?

CodeForge Chinese Version
CodeForge English Version

Where are you going?

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!
OK

Warm tip!

CodeForge to FavoriteFavorite by Ctrl+D