Two ways to make Box2D cars

I am showing you two ways to make cars with Box2d, with source codes included

These are examples I found on the web – I will make my ones later – you can find interesting in order to make cars using Box2D.

Top Down Car Simulation

Making a top down game in Box2D is not that different than making a side view game… you just don’t have to set gravity.

Here it is a top-down racing game

And this is the script to handle it

import Box2D.Collision.*;// bounding box of our world
import Box2D.Common.Math.*;// for vector(define gravity)
import Box2D.Dynamics.*;// define bodies and define world
import Box2D.Dynamics.Joints.*;
import Box2D.Collision.Shapes.*;// define our shapes
import flash.display.*;// sprite class

const MAX_STEER_ANGLE:Number = Math.PI/3;
const STEER_SPEED = 1.5;
const SIDEWAYS_FRICTION_FORCE:Number = 10;
const HORSEPOWERS:Number = 40
const CAR_STARTING_POS:b2Vec2 = new b2Vec2(10,10);

const leftRearWheelPosition:b2Vec2 = new b2Vec2(-1.5,1.90);
const rightRearWheelPosition:b2Vec2 = new b2Vec2(1.5,1.9);
const leftFrontWheelPosition:b2Vec2 = new b2Vec2(-1.5,-1.9);
const rightFrontWheelPosition:b2Vec2 = new b2Vec2(1.5,-1.9);

var engineSpeed:Number =0;
var steeringAngle:Number = 0

var myWorld:b2World;

var worldBox:b2AABB = new b2AABB();
worldBox.lowerBound.Set(-100,-100);
worldBox.upperBound.Set(100,100);

myWorld = new b2World(worldBox, new b2Vec2(0,0) , true);

//Create some static stuff
var staticDef = new b2BodyDef();
staticDef.position.Set(5,20);
var staticBox = new b2PolygonDef();
staticBox.SetAsBox(5,5);
myWorld.CreateBody(staticDef).CreateShape(staticBox);
staticDef.position.x = 25;
myWorld.CreateBody(staticDef).CreateShape(staticBox);
staticDef.position.Set(15, 24);
myWorld.CreateBody(staticDef).CreateShape(staticBox);


// define our body
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.linearDamping = 1;
bodyDef.angularDamping = 1;
bodyDef.position = CAR_STARTING_POS.Copy()

var body:b2Body = myWorld.CreateBody(bodyDef);
body.SetMassFromShapes();

var leftWheelDef:b2BodyDef = new b2BodyDef();
leftWheelDef.position = CAR_STARTING_POS.Copy();
leftWheelDef.position.Add(leftFrontWheelPosition);
var leftWheel:b2Body = myWorld.CreateBody(leftWheelDef);

var rightWheelDef:b2BodyDef = new b2BodyDef();
rightWheelDef.position = CAR_STARTING_POS.Copy();
rightWheelDef.position.Add(rightFrontWheelPosition);
var rightWheel:b2Body = myWorld.CreateBody(rightWheelDef);

var leftRearWheelDef:b2BodyDef = new b2BodyDef();
leftRearWheelDef.position = CAR_STARTING_POS.Copy();
leftRearWheelDef.position.Add(leftRearWheelPosition);
var leftRearWheel:b2Body = myWorld.CreateBody(leftRearWheelDef);

var rightRearWheelDef:b2BodyDef = new b2BodyDef();
rightRearWheelDef.position = CAR_STARTING_POS.Copy();
rightRearWheelDef.position.Add(rightRearWheelPosition);
var rightRearWheel:b2Body = myWorld.CreateBody(rightRearWheelDef);

// define our shapes
var boxDef:b2PolygonDef = new b2PolygonDef();
boxDef.SetAsBox(1.5,2.5);
boxDef.density = 1;
body.CreateShape(boxDef);

//Left Wheel shape
var leftWheelShapeDef = new b2PolygonDef();
leftWheelShapeDef.SetAsBox(0.2,0.5);
leftWheelShapeDef.density = 1;
leftWheel.CreateShape(leftWheelShapeDef);

//Right Wheel shape
var rightWheelShapeDef = new b2PolygonDef();
rightWheelShapeDef.SetAsBox(0.2,0.5);
rightWheelShapeDef.density = 1;
rightWheel.CreateShape(rightWheelShapeDef);

//Left Wheel shape
var leftRearWheelShapeDef = new b2PolygonDef();
leftRearWheelShapeDef.SetAsBox(0.2,0.5);
leftRearWheelShapeDef.density = 1;
leftRearWheel.CreateShape(leftRearWheelShapeDef);

//Right Wheel shape
var rightRearWheelShapeDef = new b2PolygonDef();
rightRearWheelShapeDef.SetAsBox(0.2,0.5);
rightRearWheelShapeDef.density = 1;
rightRearWheel.CreateShape(rightRearWheelShapeDef);

body.SetMassFromShapes();
leftWheel.SetMassFromShapes();
rightWheel.SetMassFromShapes();
leftRearWheel.SetMassFromShapes();
rightRearWheel.SetMassFromShapes();

var leftJointDef:b2RevoluteJointDef = new b2RevoluteJointDef();
leftJointDef.Initialize(body, leftWheel, leftWheel.GetWorldCenter());
leftJointDef.enableMotor = true;
leftJointDef.maxMotorTorque = 100;

var rightJointDef = new b2RevoluteJointDef();
rightJointDef.Initialize(body, rightWheel, rightWheel.GetWorldCenter());
rightJointDef.enableMotor = true;
rightJointDef.maxMotorTorque = 100;

var leftJoint:b2RevoluteJoint = b2RevoluteJoint(myWorld.CreateJoint(leftJointDef));
var rightJoint:b2RevoluteJoint = b2RevoluteJoint(myWorld.CreateJoint(rightJointDef));

var leftRearJointDef:b2PrismaticJointDef = new b2PrismaticJointDef();
leftRearJointDef.Initialize(body, leftRearWheel, leftRearWheel.GetWorldCenter(), new b2Vec2(1,0));
leftRearJointDef.enableLimit = true;
leftRearJointDef.lowerTranslation = leftRearJointDef.upperTranslation = 0;

var rightRearJointDef:b2PrismaticJointDef = new b2PrismaticJointDef();
rightRearJointDef.Initialize(body, rightRearWheel, rightRearWheel.GetWorldCenter(), new b2Vec2(1,0));
rightRearJointDef.enableLimit = true;
rightRearJointDef.lowerTranslation = rightRearJointDef.upperTranslation = 0;

myWorld.CreateJoint(leftRearJointDef);
myWorld.CreateJoint(rightRearJointDef);


// debug draw
var dbgDraw:b2DebugDraw = new b2DebugDraw();
dbgDraw.m_sprite = new Sprite();
addChild(dbgDraw.m_sprite);
dbgDraw.m_drawScale = 20.0;
dbgDraw.m_fillAlpha = 0.3;
dbgDraw.m_lineThickness = 1.0;
dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit |b2DebugDraw.e_centerOfMassBit;
myWorld.SetDebugDraw(dbgDraw);


//========== FUNCTIONS ==========

//This function applies a "friction" in a direction orthogonal to the body's axis.
function killOrthogonalVelocity(targetBody:b2Body){
	var localPoint = new b2Vec2(0,0);
	var velocity:b2Vec2 = targetBody.GetLinearVelocityFromLocalPoint(localPoint);
	
	var sidewaysAxis = targetBody.GetXForm().R.col2.Copy();
	sidewaysAxis.Multiply(b2Math.b2Dot(velocity,sidewaysAxis))

	targetBody.SetLinearVelocity(sidewaysAxis);//targetBody.GetWorldPoint(localPoint));
}

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed_handler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased_handler);

function keyPressed_handler(e:KeyboardEvent) {
	if(e.keyCode == Keyboard.UP){
		body.WakeUp();
		engineSpeed = -HORSEPOWERS;
	}
	if(e.keyCode == Keyboard.DOWN){
		engineSpeed = HORSEPOWERS;
	}
	if(e.keyCode == Keyboard.RIGHT){
		steeringAngle = MAX_STEER_ANGLE
	}
	if(e.keyCode == Keyboard.LEFT){
		steeringAngle = -MAX_STEER_ANGLE
	}
}

function keyReleased_handler(e:KeyboardEvent){
	if(e.keyCode == Keyboard.UP || e.keyCode == Keyboard.DOWN){
		engineSpeed = 0;
	} 
	if(e.keyCode == Keyboard.LEFT || e.keyCode == Keyboard.RIGHT){
		steeringAngle = 0;
	}
}

addEventListener(Event.ENTER_FRAME, Update, false, 0 , true);

function Update(e:Event):void {
	myWorld.Step(1/30, 8);
	killOrthogonalVelocity(leftWheel);
	killOrthogonalVelocity(rightWheel);
	killOrthogonalVelocity(leftRearWheel);
	killOrthogonalVelocity(rightRearWheel);

	//Driving
	var ldirection = leftWheel.GetXForm().R.col2.Copy();
	ldirection.Multiply(engineSpeed);
	var rdirection = rightWheel.GetXForm().R.col2.Copy()
	rdirection.Multiply(engineSpeed);
	leftWheel.ApplyForce(ldirection, leftWheel.GetPosition());
	rightWheel.ApplyForce(rdirection, rightWheel.GetPosition());
	
	//Steering
	var mspeed:Number;
	mspeed = steeringAngle - leftJoint.GetJointAngle();
	leftJoint.SetMotorSpeed(mspeed * STEER_SPEED);
	mspeed = steeringAngle - rightJoint.GetJointAngle();
	rightJoint.SetMotorSpeed(mspeed * STEER_SPEED);
}

more information at the official forum thread

Truck car game

This is a truck car game, this concept was very popular a couple of years ago.

The truck is made using various joints, such as revolute joints and prismatic joints.

Here it is the source code:

package {
   
   import flash.display.Sprite;
   import flash.events.Event;

   import Box2D.Dynamics.*;
   import Box2D.Collision.*;
   import Box2D.Collision.Shapes.*;
   import Box2D.Common.Math.*;
   import Box2D.Dynamics.Joints.*;
   
   public class TruckGame extends Sprite {
      
      public const ITERATIONS      : int       = 30;
      public const TIME_STEP       : Number    = 1.0/60.0;
      public const SCREEN_WIDTH    : int       = 800;
      public const SCREEN_HEIGHT   : int      = 500;
      public const DRAW_SCALE      : Number   = 50;
      
      private var world    : b2World;
      private var cart    : b2Body;
      private var wheel1    : b2Body;
      private var wheel2    : b2Body;
      private var axle1   : b2Body;
      private var axle2   : b2Body;
      private var motor1   : b2RevoluteJoint;
      private var motor2   : b2RevoluteJoint;
      private var spring1   : b2PrismaticJoint;
      private var spring2   : b2PrismaticJoint;
      
      private var screen   : Sprite;
      private var input   : Input;

      
      public function TruckGame() : void {
         
         // create the drawing screen //
         screen = new Sprite();
         screen.scaleY = -1;
         screen.y = SCREEN_HEIGHT;
         addChild(screen);
         
         // initialize input object //
         input = new Input(this);
         
         // add main loop event listener //
         addEventListener(Event.ENTER_FRAME, update, false, 0, true);
         
         init();
         
      }
      
      private function init() : void {

         // create world //
         var worldAABB:b2AABB = new b2AABB();
         
         worldAABB.lowerBound.Set(-200, -100);
         worldAABB.upperBound.Set(200, 200);
         
         world = new b2World(worldAABB, new b2Vec2(0, -10.0), true);
         
         
         // allow debug drawing //
         var debugDraw : b2DebugDraw = new b2DebugDraw();
         debugDraw.m_sprite          = screen;
         debugDraw.m_drawScale       = DRAW_SCALE;
         debugDraw.m_fillAlpha       = 0.1;
         debugDraw.m_lineThickness    = 2.0;
         debugDraw.m_drawFlags       = 1;
         
         world.SetDebugDraw(debugDraw);
         
         
         // temporary variables for adding new bodies //
         var i               : int;
         var body             : b2Body;
         var bodyDef          : b2BodyDef;
         var boxDef             : b2PolygonDef;
         var circleDef          : b2CircleDef;
         var revoluteJointDef   : b2RevoluteJointDef;
         var prismaticJointDef   : b2PrismaticJointDef;
         
         
         // add the ground //
         bodyDef = new b2BodyDef();
         bodyDef.position.Set(0, 0.5);
         
         boxDef = new b2PolygonDef();
         boxDef.SetAsBox(50, 0.5);
         boxDef.friction = 1;
         boxDef.density = 0; 
         
         body = world.CreateBody(bodyDef);
         body.CreateShape(boxDef);
         
         boxDef.SetAsOrientedBox(1, 2, new b2Vec2(-50, 0.5), 0);
         body.CreateShape(boxDef);
         
         boxDef.SetAsOrientedBox(1, 2, new b2Vec2(50, 0.5), 0);
         body.CreateShape(boxDef);
         
         boxDef.SetAsOrientedBox(3, 0.5, new b2Vec2(5, 1.5), Math.PI/4);
         body.CreateShape(boxDef);
         
         boxDef.SetAsOrientedBox(3, 0.5, new b2Vec2(3.5, 1), Math.PI/8);
         body.CreateShape(boxDef);
         
         boxDef.SetAsOrientedBox(3, 0.5, new b2Vec2(9, 1.5), -Math.PI/4);
         body.CreateShape(boxDef);
         
         boxDef.SetAsOrientedBox(3, 0.5, new b2Vec2(10.5, 1), -Math.PI/8);
         body.CreateShape(boxDef);
         
         body.SetMassFromShapes();
         
         
         // add random shit //
         circleDef = new b2CircleDef();
         circleDef.density = 0.01;
         circleDef.friction = 0.1;
         circleDef.restitution = 0.5;
         
         for (i = 0; i < 30; i++) {
            circleDef.radius = Math.random()/20+0.02;
            
            bodyDef = new b2BodyDef();
            bodyDef.position.Set(Math.random()*35+15, 1);
            bodyDef.allowSleep = true;
            bodyDef.linearDamping = 0.1;
            bodyDef.angularDamping = 0.1;
            
            body = world.CreateBody(bodyDef);
            
            body.CreateShape(circleDef);
            body.SetMassFromShapes();
         }
         
         
         // add cart //
         bodyDef = new b2BodyDef();
         bodyDef.position.Set(0, 3.5);

         cart = world.CreateBody(bodyDef);
         
         boxDef = new b2PolygonDef();
         boxDef.density = 2;
         boxDef.friction = 0.5;
         boxDef.restitution = 0.2;
         boxDef.filter.groupIndex = -1;
         
         boxDef.SetAsBox(1.5, 0.3);
         cart.CreateShape(boxDef);
         
         boxDef.SetAsOrientedBox(0.4, 0.15, new b2Vec2(-1, -0.3), Math.PI/3);
         cart.CreateShape(boxDef);
         
         boxDef.SetAsOrientedBox(0.4, 0.15, new b2Vec2(1, -0.3), -Math.PI/3);
         cart.CreateShape(boxDef);
         
         cart.SetMassFromShapes();
         
         boxDef.density = 1;
         
         
         // add the axles //
         axle1 = world.CreateBody(bodyDef);
         
         boxDef.SetAsOrientedBox(0.4, 0.1, new b2Vec2(-1 - 0.6*Math.cos(Math.PI/3), -0.3 - 0.6*Math.sin(Math.PI/3)), Math.PI/3);
         axle1.CreateShape(boxDef);
         axle1.SetMassFromShapes();
         
         prismaticJointDef = new b2PrismaticJointDef();
         prismaticJointDef.Initialize(cart, axle1, axle1.GetWorldCenter(), new b2Vec2(Math.cos(Math.PI/3), Math.sin(Math.PI/3)));
         prismaticJointDef.lowerTranslation = -0.3;
         prismaticJointDef.upperTranslation = 0.5;
         prismaticJointDef.enableLimit = true;
         prismaticJointDef.enableMotor = true;
         
         spring1 = world.CreateJoint(prismaticJointDef) as b2PrismaticJoint;
         
         
         axle2 = world.CreateBody(bodyDef);
         
         boxDef.SetAsOrientedBox(0.4, 0.1, new b2Vec2(1 + 0.6*Math.cos(-Math.PI/3), -0.3 + 0.6*Math.sin(-Math.PI/3)), -Math.PI/3);
         axle2.CreateShape(boxDef);
         axle2.SetMassFromShapes();
         
         prismaticJointDef.Initialize(cart, axle2, axle2.GetWorldCenter(), new b2Vec2(-Math.cos(Math.PI/3), Math.sin(Math.PI/3)));
         
         spring2 = world.CreateJoint(prismaticJointDef) as b2PrismaticJoint;
         
         
         // add wheels //
         circleDef.radius = 0.7;
         circleDef.density = 0.1;
         circleDef.friction = 5;
         circleDef.restitution = 0.2;
         circleDef.filter.groupIndex = -1;
         
         for (i = 0; i < 2; i++) {
            
            bodyDef = new b2BodyDef();
            if (i == 0) bodyDef.position.Set(axle1.GetWorldCenter().x - 0.3*Math.cos(Math.PI/3), axle1.GetWorldCenter().y - 0.3*Math.sin(Math.PI/3));
            else bodyDef.position.Set(axle2.GetWorldCenter().x + 0.3*Math.cos(-Math.PI/3), axle2.GetWorldCenter().y + 0.3*Math.sin(-Math.PI/3));
            bodyDef.allowSleep = false;
            
            if (i == 0) wheel1 = world.CreateBody(bodyDef);
            else wheel2 = world.CreateBody(bodyDef);
            
            (i == 0 ? wheel1 : wheel2).CreateShape(circleDef);
            (i == 0 ? wheel1 : wheel2).SetMassFromShapes();
            
         }
         
         
         // add joints //
         revoluteJointDef = new b2RevoluteJointDef();
         revoluteJointDef.enableMotor = true;
         
         revoluteJointDef.Initialize(axle1, wheel1, wheel1.GetWorldCenter());
         motor1 = world.CreateJoint(revoluteJointDef) as b2RevoluteJoint;
         
         revoluteJointDef.Initialize(axle2, wheel2, wheel2.GetWorldCenter());
         motor2 = world.CreateJoint(revoluteJointDef) as b2RevoluteJoint;
         
      }
      
      
      public function update(e : Event) : void {
         
         if (input.isPressed(32)) {
            world = null;
            init();
            return;
         }

         motor1.SetMotorSpeed(15*Math.PI * (input.isPressed(40) ? 1 : input.isPressed(38) ? -1 : 0));
         motor1.SetMaxMotorTorque(input.isPressed(40) || input.isPressed(38) ? 17 : 0.5);
         
         motor2.SetMotorSpeed(15*Math.PI * (input.isPressed(40) ? 1 : input.isPressed(38) ? -1 : 0));
         motor2.SetMaxMotorTorque(input.isPressed(40) || input.isPressed(38) ? 12 : 0.5);
         
         spring1.SetMaxMotorForce(30+Math.abs(800*Math.pow(spring1.GetJointTranslation(), 2)));
         //spring1.SetMotorSpeed(-4*Math.pow(spring1.GetJointTranslation(), 1));
         spring1.SetMotorSpeed((spring1.GetMotorSpeed() - 10*spring1.GetJointTranslation())*0.4);         
         
         spring2.SetMaxMotorForce(20+Math.abs(800*Math.pow(spring2.GetJointTranslation(), 2)));
         spring2.SetMotorSpeed(-4*Math.pow(spring2.GetJointTranslation(), 1));
         
         cart.ApplyTorque(30*(input.isPressed(37) ? 1: input.isPressed(39) ? -1 : 0));
         
         screen.x -= (screen.x - (-DRAW_SCALE*cart.GetWorldCenter().x + SCREEN_WIDTH/2 - cart.GetLinearVelocity().x*10))/3;
         screen.y -= (screen.y - (DRAW_SCALE*cart.GetWorldCenter().y + 2*SCREEN_HEIGHT/3 + cart.GetLinearVelocity().y*6))/3;

         world.Step(TIME_STEP, ITERATIONS);
         
         FRateLimiter.limitFrame(60);
         
      }
      
   }
   
}

Follow the official thread here.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers