Box2D joints: Gear Joints
2009-10-27 00:00:00 来源:WEB开发网Here I am with some infos about Gear Joints.
Gear joints can be used to create a sophisticated mechanical contraption you might want to use a gears. In principle you can create gears in Box2D by using compound shapes to model gear teeth. This is not very efficient and might be tedious to author. You also have to be careful to line up the gears so the teeth mesh smoothly. Box2D has a simpler method of creating gears: the gear joint.
Unlikely other kinds of joint, the gear joint requires you have two bodies connected to ground by a revolute or prismatic joint.
The following script is the same you already saw in other joint examples, and will create a gear joint between two wheels fixed to the ground with revolute joints.
Try to drag one of the circles and see what happens. This is the source:
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 gear extends Sprite {
var mouseJoint:b2MouseJoint;
var mousePVec:b2Vec2 = new b2Vec2();
var bd:b2BodyDef;
var the_circle:b2CircleDef = new b2CircleDef();
var the_rev_joint:b2RevoluteJointDef = new b2RevoluteJointDef();
var the_gear_joint:b2GearJoint;
public function gear() {
// 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();
addChild(m_sprite);
var dbgDraw:b2DebugDraw = new b2DebugDraw();
var dbgSprite:Sprite = new Sprite();
m_sprite.addChild(dbgSprite);
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);
// 1st gear
the_circle.radius=2;
the_circle.density=5;
bd = new b2BodyDef();
bd.position.Set(5,6.5);
var gear1:b2Body=m_world.CreateBody(bd);
gear1.CreateShape(the_circle);
gear1.SetMassFromShapes();
// 2nd gear
the_circle.radius=3;
the_circle.density=5;
bd = new b2BodyDef();
bd.position.Set(11,6.5);
var gear2:b2Body=m_world.CreateBody(bd);
gear2.CreateShape(the_circle);
gear2.SetMassFromShapes();
// joints
the_rev_joint.Initialize(m_world.GetGroundBody(), gear1, new b2Vec2(5,6.5));
var first_joint:b2RevoluteJoint=m_world.CreateJoint(the_rev_joint) as b2RevoluteJoint;
the_rev_joint.Initialize(m_world.GetGroundBody(), gear2, new b2Vec2(11,6.5));
var second_joint:b2RevoluteJoint=m_world.CreateJoint(the_rev_joint) as b2RevoluteJoint;
// gear joint
var gear_joint:b2GearJointDef = new b2GearJointDef();
gear_joint.body1=gear1;
gear_joint.body2=gear2;
gear_joint.joint1=first_joint;
gear_joint.joint2=second_joint;
gear_joint.ratio=1;
the_gear_joint=m_world.CreateJoint(gear_joint) as b2GearJoint;
// listeners
stage.addEventListener(MouseEvent.MOUSE_DOWN, createMouse);
stage.addEventListener(MouseEvent.MOUSE_UP, destroyMouse);
addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
}
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;
}
}
更多精彩
赞助商链接