先看API文档
ApplyForce()method
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.
Parameters
force:b2Vec2 — the world force vector, usually in Newtons (N). 单位:牛顿
point:b2Vec2 — the world position of the point of application.
ApplyImpulse()method
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.
Parameters
impulse:b2Vec2 — the world impulse vector, usually in N-seconds or kg-m/s. 单位:牛顿·秒 或者 千克·米/秒
point:b2Vec2 — the world position of the point of application.
SetLinearVelocity()method
public function SetLinearVelocity(v:b2Vec2):void
Set the linear velocity of the center of mass.
物体在休眠状态下,这个函数不起作用。因此先要唤醒物体,才能使用。
Parameters
v:b2Vec2 — the new linear velocity of the center of mass.
我该使用那个外力?
1.当物体静止不动的时候
这个静止不动包括了2种情况:一个是静止在地面 一个是上升到最高阶段即将下落的那一刻(速度为0)
2.当物体处于上升阶段的时候
3.当物体处于下降阶段的时候
源码:
package { import Box2D.Collision.Shapes.b2PolygonShape; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2Fixture; import Box2D.Dynamics.b2FixtureDef; import Box2D.Dynamics.b2World; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; /** * ... * @author Childhood */ public class Main extends Sprite { private var world:b2World = new b2World(new b2Vec2(0, 10), true); private var worldScale:uint = 30; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); getStarted(); } private function getStarted():void { debugDraw(); drawBox(0,800,1600,100,false,"ground"); drawBox(100,500,100,100,true,"left"); drawBox(400,500,10,10,true,"middle"); drawBox(700,500,10,10,true,"right"); addEventListener(Event.ENTER_FRAME, update); stage.addEventListener(MouseEvent.CLICK, applyForces); } private function drawBox(px:Number,py:Number,width:Number,height:Number,d:Boolean,userData:*):void { var boxBodyDef:b2BodyDef = new b2BodyDef(); boxBodyDef.position.Set(px / worldScale, py / worldScale); if (d) { boxBodyDef.type = b2Body.b2_dynamicBody; } var boxBody:b2Body = world.CreateBody(boxBodyDef); boxBody.SetUserData(userData); var boxShape:b2PolygonShape = new b2PolygonShape(); boxShape.SetAsBox(width / 2 / worldScale, height / 2 / worldScale); var boxFixtureDef:b2FixtureDef = new b2FixtureDef(); boxFixtureDef.shape = boxShape; var boxFixture:b2Fixture = boxBody.CreateFixture(boxFixtureDef); } private function applyForces(e:MouseEvent):void { var force:b2Vec2; //Makes a for loop scanning all the bodys in the World for (var worldBody:b2Body = world.GetBodyList(); worldBody; worldBody = worldBody.GetNext()) { switch(worldBody.GetUserData()) { case "left": force = new b2Vec2(0, -480); //worldBody.ApplyForce(force, worldBody.GetWorldCenter()); worldBody.ApplyForce(force, worldBody.GetLocalPoint(new b2Vec2(15,15))); break; case "middle": force = new b2Vec2(0, -16); worldBody.ApplyImpulse(force, worldBody.GetWorldCenter()); break; case "right": force = new b2Vec2(0, -16); worldBody.SetAwake(true); worldBody.SetLinearVelocity(force); break; } } } private function update(e:Event):void { world.Step(1 / 30, 10, 10); world.ClearForces(); world.DrawDebugData(); } private function debugDraw():void { var debugDraw:b2DebugDraw = new b2DebugDraw(); var debugSprite:Sprite = new Sprite(); addChild(debugSprite); debugDraw.SetSprite(debugSprite); debugDraw.SetDrawScale(worldScale); debugDraw.SetFillAlpha(0.8); debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit); world.SetDebugDraw(debugDraw); } } }
源码及其效果下载:
http://115.com/file/an83qkmw#ApplyForce&ApplyImpulse.rar
大家可以在以上3种情况下点击舞台,体会下3者的不同之处。
这里的ApplyForce()中的-480 和ApplyImpulse()中的-16是什么关系呢?
为什么这样子左边的箱子和中间的箱子分别给定这数值后运动保持一致呢?
大家记得物理中的p=F*t 吧,动量=力*施加的时间,world的时间步是1/30s,-480*(1/30)=-16,-480是力,单位是牛顿,-16是动量,单位是牛顿*秒。所以左箱子和中间的箱子其实给定的冲量是一样的。不妨把时间步改成1/40,那么-480*(1/40)=-12,那我敢肯定当点击舞台的时候,左边的箱子给定的冲量12小于中间的箱子的冲量16(负号仅代表向上),左边的箱子没有中间的箱子蹦的高。
ApplyImpulse可以立即改变物体的速度,而ApplyForce施加的力需要world的时间步来改变物体的速度。(不知道这么理解对不对?)
SetLinearVelocity()每次使用的时候会把原来的动量清0然后加上给定的冲量。ApplyForce和ApplyImpulse会在原来的动量上进行加减运算。