Talking about Actionscript 3, Box2D and Flash.
In Box2d, bodies aren’t only affected by gravity and collisions, but you can also apply forces to them.
Knowing the right force to apply is very important when you want to control a body, as you may want to do in a Flash game
Let’s see the forces you can apply:
Applying a force
public function ApplyForce(force:b2Vec2, point:b2Vec2):void
Apply a force at a world point. If the force is not applied at the center of mass, it will generate a torque and affect the angular velocity. This wakes up the body, so you don’t have to wake it up by yourself.
The force is applied inNewtons (N).
Applying an impulse
public function ApplyImpulse(impulse:b2Vec2, point:b2Vec2):void
Apply an impulse at a point. This immediately modifies the velocity. It also modifies the angular velocity if the point of application is not at the center of mass. This wakes up the body, so you don’t have to wake it up by yourself.
The impulse is applied in Newton-seconds or kg-m/s.
Setting a linear velocity
public function SetLinearVelocity(v:b2Vec2):void
Set the linear velocity of the center of mass. This function will not work if the body is sleeping, so you must wake it up with SetAwake
before applying the velocity.
What force should I apply?
You should choose the force according to the result you want to achieve. Let’s suppose you want to apply a vertical force, to make something jump in the air, and let’s suppose you can apply the force at any time, even when you just applied it.
You will have three cases:
Applying the force when the body is not moving: this happens when you apply the force when the body lies on the ground or when it’s in the air, in the moment it finished its “jumping” speed and it’s about to fall down. In this case there aren’t any noticeable difference among applied forces.
Applying the force when the body is moving up: this happens when the body is in the air and still has “jumping” speed. In this case, applying a force or an impulse will sum the “jumping” speed to the applied force to produce a “boost”, while setting the velocity again will just apply the velocity again, no matter the “jumping speed”
Applying the force when the body is falling down: this happens when the body finished its “jumping” speed and it’s falling down. As in the previous case, applying a force or an impulse will sum the falling speed to the applied force, and according to falling speed and applied force, the body will continue falling or jump a little (how little? the difference between the falling force and the applied one). Setting the velocity will just stop the body to fall and make it jumping again, no matter of the falling speed.
The script
This script will generate three tiny boxes. The left one is moved with a force, the middle one with an impulse, and the third one with a set velocity. You will apply forces clicking the mouse
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
public class forces extends Sprite {
public var world:b2World=new b2World(new b2Vec2(0,10.0),true);
public var world_scale:int=30;
public function forces():void {
debug_draw();
draw_box(250,400,500,10,false,"ground");
draw_box(100,100,10,10,true,"left");
draw_box(250,100,10,10,true,"middle");
draw_box(400,100,10,10,true,"right");
addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(MouseEvent.CLICK,applyforces);
}
public function draw_box(px,py,w,h,d,ud):void {
var my_body:b2BodyDef= new b2BodyDef();
my_body.position.Set(px/world_scale, py/world_scale);
if (d) {
my_body.type=b2Body.b2_dynamicBody;
}
var my_box:b2PolygonShape = new b2PolygonShape();
my_box.SetAsBox(w/2/world_scale, h/2/world_scale);
var my_fixture:b2FixtureDef = new b2FixtureDef();
my_fixture.shape=my_box;
var world_body:b2Body=world.CreateBody(my_body);
world_body.SetUserData(ud);
world_body.CreateFixture(my_fixture);
}
public function debug_draw():void {
var debug_draw:b2DebugDraw = new b2DebugDraw();
var debug_sprite:Sprite = new Sprite();
addChild(debug_sprite);
debug_draw.SetSprite(debug_sprite);
debug_draw.SetDrawScale(world_scale);
debug_draw.SetFlags(b2DebugDraw.e_shapeBit);
world.SetDebugDraw(debug_draw);
}
public function applyforces(e:MouseEvent):void {
var force:b2Vec2;
for (var worldbody:b2Body = world.GetBodyList(); worldbody; worldbody = worldbody.GetNext()) {
switch (worldbody.GetUserData()) {
case "left" :
force=new b2Vec2(0,-450);
worldbody.ApplyForce(force,worldbody.GetWorldCenter());
break;
case "middle" :
force=new b2Vec2(0,-15);
worldbody.ApplyImpulse(force,worldbody.GetWorldCenter());
break;
case "right" :
force=new b2Vec2(0,-15);
worldbody.SetAwake(true);
worldbody.SetLinearVelocity(force);
break;
}
}
}
public function update(e:Event):void {
world.Step(1/30,10,10);
world.ClearForces();
world.DrawDebugData();
}
}
}
And this is the result:
Apply forces by clicking the mouse in various times, to see the difference among ApplyForce
, ApplyImpulse
and SetLinearVelocity
.
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.