# Box2D joints: Prismatic Joints

Time to learn something about Box2D prismatic joints.

A prismatic joint provides one degree of freedom: translation along an axis fixed relative to the first body. Relative rotation is prevented.

In other words, prismatic joints can be used to represent pistons and other sliding objects.

In this tutorial I am going to show how to create a prismatic joint, and later I’ll show you some real-world examples.

The script is the one you can find at Box2D joints: Revolute Joint – Building motors with some modifications in order to create prismatic joints.

```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.*;
import flash.events.MouseEvent;
public class prismatic_joint extends Sprite {
var mouseJoint:b2MouseJoint;
var mousePVec:b2Vec2 = new b2Vec2();
var bd:b2BodyDef;
var the_box:b2PolygonDef = new b2PolygonDef();
var the_prism_joint:b2PrismaticJointDef = new b2PrismaticJointDef();
public function prismatic_joint() {
// world setup
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-100.0, -100.0);
worldAABB.upperBound.Set(100.0, 100.0);
var gravity:b2Vec2=new b2Vec2(0.0,10.0);
var doSleep:Boolean=true;
m_world=new b2World(worldAABB,gravity,doSleep);
// debug draw
var m_sprite:Sprite;
m_sprite = new Sprite();
var dbgDraw:b2DebugDraw = new b2DebugDraw();
var dbgSprite:Sprite = new Sprite();
dbgDraw.m_sprite=m_sprite;
dbgDraw.m_drawScale=30;
dbgDraw.m_alpha=1;
dbgDraw.m_fillAlpha=0.5;
dbgDraw.m_lineThickness=1;
dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit;
m_world.SetDebugDraw(dbgDraw);
// box for the prismatic joint
the_box.SetAsBox(0.5,0.5);
the_box.density=0.01;
the_box.friction=1;
the_box.restitution=0.1;
bd = new b2BodyDef();
bd.position.Set(8.5,5);
var prism_box:b2Body=m_world.CreateBody(bd);
prism_box.CreateShape(the_box);
prism_box.SetMassFromShapes();
// prismatic joint
the_prism_joint.Initialize(m_world.GetGroundBody(), prism_box, new b2Vec2(8.5,5),new b2Vec2(1,0));
the_prism_joint.lowerTranslation=-6;
the_prism_joint.upperTranslation=6
the_prism_joint.enableLimit=true;
the_prism_joint.maxMotorForce=100;
the_prism_joint.motorSpeed=4.0;
the_prism_joint.enableMotor=true;
// listeners
}
public function createMouse(evt:MouseEvent):void {
var body:b2Body=GetBodyAtMouse();
if (body) {
var mouseJointDef:b2MouseJointDef=new b2MouseJointDef  ;
mouseJointDef.body1=m_world.GetGroundBody();
mouseJointDef.body2=body;
mouseJointDef.target.Set(mouseX/30, mouseY/30);
mouseJointDef.maxForce=30000;
mouseJointDef.timeStep=m_timeStep;
mouseJoint=m_world.CreateJoint(mouseJointDef) as b2MouseJoint;
}
}
public function destroyMouse(evt:MouseEvent):void {
if (mouseJoint) {
m_world.DestroyJoint(mouseJoint);
mouseJoint=null;
}
}
public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body {
var mouseXWorldPhys = (mouseX)/30;
var mouseYWorldPhys = (mouseY)/30;
mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys);
var aabb:b2AABB = new b2AABB();
aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001);
aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001);
var k_maxCount:int=10;
var shapes:Array = new Array();
var count:int=m_world.Query(aabb,shapes,k_maxCount);
var body:b2Body=null;
for (var i:int = 0; i < count; ++i) {
if (shapes[i].GetBody().IsStatic()==false||includeStatic) {
var tShape:b2Shape=shapes[i] as b2Shape;
var inside:Boolean=tShape.TestPoint(tShape.GetBody().GetXForm(),mousePVec);
if (inside) {
body=tShape.GetBody();
break;
}
}
}
return body;
}
public function Update(e:Event):void {
m_world.Step(m_timeStep, m_iterations);
if (mouseJoint) {
var mouseXWorldPhys=mouseX/30;
var mouseYWorldPhys=mouseY/30;
var p2:b2Vec2=new b2Vec2(mouseXWorldPhys,mouseYWorldPhys);
mouseJoint.SetTarget(p2);
}
}
public var m_world:b2World;
public var m_iterations:int=10;
public var m_timeStep:Number=1.0/30.0;
}
}
```

Line 15: Declaring `the_prism_joint` variable, `b2PrismaticJointDef` type. This is how I define prismatic joints.

Line 49: Initializing the prismatic joint. This is the most difficult and unclear part of the process. The first two parameters represent the objects tied by the joint, the third one is the point where to tie the joint and the fourth is a vector representing the movement allowed. In this case, being an horizontal vector, the movement allowed is horizontal

Notice about this 4th parameter that values inside `b2Vec2()` cannot be greater than 1 or you may experience strange results.

All in all, there is no need to write (100,0) to represent an horizontal vector, when you can just use (1,0)

Lines 50-51: upperTranslation and lowerTranslation represent the upper and lower translation limits, in meters. To avoid strange results, try to keep

`lowerTranslation <= 0 <= upperTranslation`

Line 52: Enabling the limits for upper and lower translations. If you don't set `enableLimit` to `true`, limits won't be considered.

Lines 53-55: Adding a simple motor. For a brief introduction about motors, refer to Box2D joints: Revolute Joint - Building motors.

And this is the result. Try to drag the box

215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 10000000
// 2 Cars
// 2048
// Avoider
// Ballz
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Breakout
// Bricks
// Columns
// CubesOut
// Dots
// DROP'd
// Dudeski
// Eskiv
// Filler
// Fling
// Globe
// HookPod
// Hundreds
// InkTd
// Iromeku
// Lumines
// Magick
// MagOrMin
// Maze
// Memdot
// Nano War
// Nodes
// o:anquan
// Ononmin
// Pacco
// Phyballs
// Platform
// Poker
// Pool
// Poux
// Pudi
// qomp
// Racing
// Renju
// SameGame
// Security
// Sling
// Slingy
// Sokoban
// Splitter
// Sproing
// Stack
// Stairs
// Stringy
// Sudoku
// Tetris
// Threes
// Toony
// Turn
// TwinSpin
// vvvvvv
// Wordle
// Worms
// Yanga
// Zhed
// zNumbers