Do you like my tutorials?

Then consider supporting me on Ko-fi

Talking about Actionscript 3, Box2D, Flash and Game development.

This post is virtually a mix of step by step creation of a Box2D car/truck with motors and shocks and the second example of two ways to make Box2D cars, and will allow you to create the same truck you can see in the second example, just using the latest Box2D version, without inverting y axis and making the truck fully configurable.

Look at the amount of values you can set:

and let’s explain them in detail:

carPosX: the horizontal center of the car body, in pixels

carPosY: the vertical center of the car body, in pixels

carWidth: the half width of the car, in pixels

carHeight: the half height of the car, in pixels

axleContainerDistance: horizontal distance of the axle containers from the center of the car

axleContainerWidth: half width of the axle container

axleContainerHeight: half height of the axle container

axleContainerDepth: vertical distance of the axle containers from the center of the car

axleAngle: angle of the axles, in degrees

wheelRadius: radius of the wheels, in pixels

This is the script:

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.Joints.*;
	public class Main extends Sprite {
		private const degreesToRadians:Number=0.0174532925;
		//
		private var world:b2World=new b2World(new b2Vec2(0,10),true);
		private var worldScale:int=30;
		private var car:b2Body;
		private var leftWheelRevoluteJoint:b2RevoluteJoint;
		private var rightWheelRevoluteJoint:b2RevoluteJoint;
		private var left:Boolean=false;
		private var right:Boolean=false;
		private var motorSpeed:Number=0;
		private var leftAxlePrismaticJoint:b2PrismaticJoint;
		private var rightAxlePrismaticJoint:b2PrismaticJoint;
		//
		private var carPosX:Number=320;
		private var carPosY:Number=250;
		private var carWidth:Number=45;
		private var carHeight:Number=10;
		private var axleContainerDistance:Number=30;
		private var axleContainerWidth:Number=5;
		private var axleContainerHeight:Number=20;
		private var axleContainerDepth:Number=10;
		private var axleAngle:Number=20;
		private var wheelRadius:Number=25;
		public function Main():void {
			debugDraw();
			// ************************ THE FLOOR ************************ //
			var floorShape:b2PolygonShape = new b2PolygonShape();
			floorShape.SetAsBox(640/worldScale,10/worldScale);
			var floorFixture:b2FixtureDef = new b2FixtureDef();
			floorFixture.density=0;
			floorFixture.friction=10;
			floorFixture.restitution=0;
			floorFixture.shape=floorShape;
			var floorBodyDef:b2BodyDef = new b2BodyDef();
			floorBodyDef.position.Set(320/worldScale,480/worldScale);
			var floor:b2Body=world.CreateBody(floorBodyDef);
			floor.CreateFixture(floorFixture);
			// ************************ THE CAR ************************ //
			var carShape:b2PolygonShape = new b2PolygonShape();
			carShape.SetAsBox(carWidth/worldScale,carHeight/worldScale);
			var carFixture:b2FixtureDef = new b2FixtureDef();
			carFixture.density=5;
			carFixture.friction=3;
			carFixture.restitution=0.3;
			carFixture.filter.groupIndex=-1;
			carFixture.shape=carShape;
			var carBodyDef:b2BodyDef = new b2BodyDef();
			carBodyDef.position.Set(carPosX/worldScale,carPosY/worldScale);
			carBodyDef.type=b2Body.b2_dynamicBody;
			// ************************ LEFT AXLE CONTAINER ************************ //
			var leftAxleContainerShape:b2PolygonShape = new b2PolygonShape();
			leftAxleContainerShape.SetAsOrientedBox(axleContainerWidth/worldScale,axleContainerHeight/worldScale,new b2Vec2(-axleContainerDistance/worldScale,axleContainerDepth/worldScale),axleAngle*degreesToRadians);
			var leftAxleContainerFixture:b2FixtureDef = new b2FixtureDef();
			leftAxleContainerFixture.density=3;
			leftAxleContainerFixture.friction=3;
			leftAxleContainerFixture.restitution=0.3;
			leftAxleContainerFixture.filter.groupIndex=-1;
			leftAxleContainerFixture.shape=leftAxleContainerShape;
			// ************************ RIGHT AXLE CONTAINER ************************ //
			var rightAxleContainerShape:b2PolygonShape = new 
			b2PolygonShape();
			rightAxleContainerShape.SetAsOrientedBox(axleContainerWidth/worldScale,axleContainerHeight/worldScale,new b2Vec2(axleContainerDistance/worldScale,axleContainerDepth/worldScale),-axleAngle*degreesToRadians);
			var rightAxleContainerFixture:b2FixtureDef = new 
			b2FixtureDef();
			rightAxleContainerFixture.density=3;
			rightAxleContainerFixture.friction=3;
			rightAxleContainerFixture.restitution=0.3;
			rightAxleContainerFixture.filter.groupIndex=-1;
			rightAxleContainerFixture.shape=rightAxleContainerShape;
			// ************************ MERGING ALL TOGETHER ************************ //
			car=world.CreateBody(carBodyDef);
			car.CreateFixture(carFixture);
			car.CreateFixture(leftAxleContainerFixture);
			car.CreateFixture(rightAxleContainerFixture);
			// ************************ THE AXLES ************************ //
			var leftAxleShape:b2PolygonShape = new b2PolygonShape();
			leftAxleShape.SetAsOrientedBox(axleContainerWidth/worldScale/2,axleContainerHeight/worldScale,new b2Vec2(0,0),axleAngle*degreesToRadians);
			var leftAxleFixture:b2FixtureDef = new b2FixtureDef();
			leftAxleFixture.density=0.5;
			leftAxleFixture.friction=3;
			leftAxleFixture.restitution=0;
			leftAxleFixture.shape=leftAxleShape;
			leftAxleFixture.filter.groupIndex=-1;
			var leftAxleBodyDef:b2BodyDef = new b2BodyDef();
			leftAxleBodyDef.type=b2Body.b2_dynamicBody;
			var leftAxle:b2Body=world.CreateBody(leftAxleBodyDef);
			leftAxle.CreateFixture(leftAxleFixture);
			leftAxle.SetPosition(new b2Vec2(carPosX/worldScale-axleContainerDistance/worldScale-axleContainerHeight/worldScale*Math.cos((90-axleAngle)*degreesToRadians),carPosY/worldScale+axleContainerDepth/worldScale+axleContainerHeight/worldScale*Math.sin((90-axleAngle)*degreesToRadians)));
			var rightAxleShape:b2PolygonShape = new b2PolygonShape();
			rightAxleShape.SetAsOrientedBox(axleContainerWidth/worldScale/2,axleContainerHeight/worldScale,new b2Vec2(0,0),-axleAngle*degreesToRadians);
			var rightAxleFixture:b2FixtureDef = new b2FixtureDef();
			rightAxleFixture.density=0.5;
			rightAxleFixture.friction=3;
			rightAxleFixture.restitution=0;
			rightAxleFixture.shape=rightAxleShape;
			rightAxleFixture.filter.groupIndex=-1;
			var rightAxleBodyDef:b2BodyDef = new b2BodyDef();
			rightAxleBodyDef.type=b2Body.b2_dynamicBody;
			var rightAxle:b2Body=world.CreateBody(rightAxleBodyDef);
			rightAxle.CreateFixture(rightAxleFixture);
			rightAxle.SetPosition(new b2Vec2(carPosX/worldScale+axleContainerDistance/worldScale+axleContainerHeight/worldScale*Math.cos((90-axleAngle)*degreesToRadians),carPosY/worldScale+axleContainerDepth/worldScale+axleContainerHeight/worldScale*Math.sin((90-axleAngle)*degreesToRadians)));
			// ************************ THE WHEELS ************************ //;
			var wheelShape:b2CircleShape=new 
			b2CircleShape(wheelRadius/worldScale);
			var wheelFixture:b2FixtureDef = new b2FixtureDef();
			wheelFixture.density=1;
			wheelFixture.friction=15;
			wheelFixture.restitution=0.2;
			wheelFixture.filter.groupIndex=-1;
			wheelFixture.shape=wheelShape;
			var wheelBodyDef:b2BodyDef = new b2BodyDef();
			wheelBodyDef.type=b2Body.b2_dynamicBody;
			wheelBodyDef.position.Set(carPosX/worldScale-axleContainerDistance/worldScale-2*axleContainerHeight/worldScale*Math.cos((90-axleAngle)*degreesToRadians),carPosY/worldScale+axleContainerDepth/worldScale+2*axleContainerHeight/worldScale*Math.sin((90-axleAngle)*degreesToRadians));
			var leftWheel:b2Body=world.CreateBody(wheelBodyDef);
			leftWheel.CreateFixture(wheelFixture);
			wheelBodyDef.position.Set(carPosX/worldScale+axleContainerDistance/worldScale+2*axleContainerHeight/worldScale*Math.cos((90-axleAngle)*degreesToRadians),carPosY/worldScale+axleContainerDepth/worldScale+2*axleContainerHeight/worldScale*Math.sin((90-axleAngle)*degreesToRadians));
			var rightWheel:b2Body=world.CreateBody(wheelBodyDef);
			rightWheel.CreateFixture(wheelFixture);
			// ************************ REVOLUTE JOINTS ************************ //
			var leftWheelRevoluteJointDef:b2RevoluteJointDef=new b2RevoluteJointDef();
			leftWheelRevoluteJointDef.Initialize(leftWheel,leftAxle,leftWheel.GetWorldCenter());
			leftWheelRevoluteJointDef.enableMotor=true;
			leftWheelRevoluteJoint=world.CreateJoint(leftWheelRevoluteJointDef) as b2RevoluteJoint;
			leftWheelRevoluteJoint.SetMaxMotorTorque(10);
			var rightWheelRevoluteJointDef:b2RevoluteJointDef=new b2RevoluteJointDef();
			rightWheelRevoluteJointDef.Initialize(rightWheel,rightAxle,rightWheel.GetWorldCenter());
			rightWheelRevoluteJointDef.enableMotor=true;
			rightWheelRevoluteJoint=world.CreateJoint(rightWheelRevoluteJointDef) as b2RevoluteJoint;
			rightWheelRevoluteJoint.SetMaxMotorTorque(10);
			// ************************ PRISMATIC JOINTS ************************ //
			var leftAxlePrismaticJointDef:b2PrismaticJointDef=new b2PrismaticJointDef();
			leftAxlePrismaticJointDef.lowerTranslation=0;
			leftAxlePrismaticJointDef.upperTranslation=axleContainerDepth/worldScale;
			leftAxlePrismaticJointDef.enableLimit=true;
			leftAxlePrismaticJointDef.enableMotor=true;
			leftAxlePrismaticJointDef.Initialize(car,leftAxle,leftAxle.GetWorldCenter(), new b2Vec2(-Math.cos((90-axleAngle)*degreesToRadians),Math.sin((90-axleAngle)*degreesToRadians)));
			leftAxlePrismaticJoint=world.CreateJoint(leftAxlePrismaticJointDef) as b2PrismaticJoint;
			leftAxlePrismaticJoint.SetMaxMotorForce(10);                         
			leftAxlePrismaticJoint.SetMotorSpeed(10);                         			
			var rightAxlePrismaticJointDef:b2PrismaticJointDef=new b2PrismaticJointDef();
			rightAxlePrismaticJointDef.lowerTranslation=0;
			rightAxlePrismaticJointDef.upperTranslation=axleContainerDepth/worldScale;
			rightAxlePrismaticJointDef.enableLimit=true;
			rightAxlePrismaticJointDef.enableMotor=true;
			rightAxlePrismaticJointDef.Initialize(car,rightAxle,rightAxle.GetWorldCenter(), new b2Vec2(Math.cos((90-axleAngle)*degreesToRadians),Math.sin((90-axleAngle)*degreesToRadians)));
			rightAxlePrismaticJoint=world.CreateJoint(rightAxlePrismaticJointDef) as b2PrismaticJoint;
			rightAxlePrismaticJoint.SetMaxMotorForce(10);                         
			rightAxlePrismaticJoint.SetMotorSpeed(10);      
			addEventListener(Event.ENTER_FRAME,updateWorld);
			stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressed);
			stage.addEventListener(KeyboardEvent.KEY_UP,keyReleased);
		}
		private function debugDraw():void {
			var worldDebugDraw:b2DebugDraw=new b2DebugDraw();
			var debugSprite:Sprite = new Sprite();
			addChild(debugSprite);
			worldDebugDraw.SetSprite(debugSprite);
			worldDebugDraw.SetDrawScale(worldScale);
			worldDebugDraw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit);
			worldDebugDraw.SetFillAlpha(0.5);
			world.SetDebugDraw(worldDebugDraw);
		}
		private function keyPressed(e:KeyboardEvent):void {
			switch (e.keyCode) {
				case 37 :
					left=true;
					break;
				case 39 :
					right=true;
					break;
			}
		}
		private function keyReleased(e:KeyboardEvent):void {
			switch (e.keyCode) {
				case 37 :
					left=false;
					break;
				case 39 :
					right=false;
					break;
			}
		}
		private function updateWorld(e:Event):void {
			if (left) {
				motorSpeed+=0.1;
			}
			if (right) {
				motorSpeed-=0.1;
			}
			motorSpeed*=0.99;
			if (motorSpeed>10) {
				motorSpeed=10;
			}
			leftWheelRevoluteJoint.SetMotorSpeed(motorSpeed);
			rightWheelRevoluteJoint.SetMotorSpeed(motorSpeed);
			world.Step(1/30,10,10);
			world.ClearForces();
			world.DrawDebugData();
		}
	}
}

and this is the result:

no need to download anything, just overwrite Main class in the step by step creation of a Box2D car.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.