【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 TKCB 于 2018-2-6 13:05 编辑
转载:9RIA游戏开发者社区(天地会)
作者:ladeng6666(拉登大叔)
作者博客:http://www.ladeng6666.com/blog/
【Box2D系列教程-导航帖】—拉登大叔出品(总贴)
昨天我们学习了Box2D 的"距离关节"b2DistanceJoint,并用它模拟了一个简单的自行车。今天我们来学习"马达关节" b2RevoluteJoint 。
"马达关节"b2RevoluteJoint同样连接了两个刚体bodyA和bodyB。不过和"马达关节"不同的是,它只有一个节点anchor,所以两个刚体都只能围绕这一个节点选择。另外,我们可以在这个节点anchor位置施加一个作用力maxMotorTorque,这样节点就会想马达一样转起来,所以我把它叫做"马达关节"。
还是不好理解,对吧!那就再打个比方,我把b2RevoluteJoint关节比作....电风扇。风扇叶是bodyA,马达是anchor,底座是bodyB,下面的图可以更好的解释这一点:
如上图所示,因为节点anchor在bodyA的圆心处,所以bodyA会围绕着节点anchor旋转。
b2RevoluteJoint的initialize方法结构如下:
[Actionscript3] 纯文本查看 复制代码 public function Initialize(
bA:b2Body,
bB:b2Body,
anchor:b2Vec2
) : void
bA即bodyA,bB即bodyB,anchor即节点,具体的功能,我在前面都讲过了,就不再赘述了。
另外,如前面提到的,通过设置b2RevoluteJointDef的maxMotorTorque、motorSpeed和enableMotor,可以模拟马达旋转。这三个参数的作用分别如下:
enableMotor:决定是否使用
motormotorSpeed:设置最大的角速度
maxMotorTorque:要达到角速度应用的扭矩力这三个属性是让节点转起来的必要条件,缺一不可!记住哦。
用b2RevoluteJoint实现风扇的效果如下:
完整的代码和注释如下:
[Actionscript3] 纯文本查看 复制代码 package
{
import Box2D.Collision.Shapes.b2PolygonShape;
import Box2D.Collision.Shapes.b2Shape;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2FixtureDef;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.Joints.b2RevoluteJoint;
import Box2D.Dynamics.Joints.b2RevoluteJointDef;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
/**
* [url=http://www.ladeng6666.com]http://www.ladeng6666.com[/url]
* @author ladeng6666
*/
public class RevoluteJointTest extends Sprite
{
private var world:b2World;
private var debugSprite:Sprite;
private var bodyA:b2Body, bodyB:b2Body;
private var posA:Point, posB:Point;
public function RevoluteJointTest()
{
LDEasyBox2D.stage = stage;
world=LDEasyBox2D.createWorld();
debugSprite=LDEasyBox2D.createDebug(world);
addChild(debugSprite);
//创建地面,
LDEasyBox2D.createWrapWall(world, stage);
createBodies();
createRevoluteJoint();
addEventListener(Event.ENTER_FRAME, loop);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
}
private function createRevoluteJoint():void
{
//创建马达关节需求
var revoluteJoint:b2RevoluteJointDef = new b2RevoluteJointDef();
//用bodyA、bodyB和anchor节点初始化马达关节
revoluteJoint.Initialize( bodyA, bodyB, new b2Vec2(posA.x / 30, posA.y / 30));
//设置连接的两个刚体之间不进行碰撞检测
revoluteJoint.collideConnected = false;
//开启马达
revoluteJoint.enableMotor = true;
//设置马达的最大角速度,单位为 弧度/秒,如设置为Math.PI,即每秒钟转180度
revoluteJoint.motorSpeed = Math.PI;
//设置最大的扭力值
revoluteJoint.maxMotorTorque = 500;
//创建马达关节
world.CreateJoint(revoluteJoint);
}
//创建bodyA和bodyB刚体
private function createBodies():void
{
//设置两个刚体的坐标位置
posA = new Point(275, 100);
posB = new Point(275, 300);
//创建一个十字刚体,赋值给bodyA
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.Set(posA.x / 30, posA.y / 30);
bodyA = world.CreateBody(bodyDef);
//设置刚体属性
var fixtureDef:b2FixtureDef = new b2FixtureDef();
fixtureDef.density = 3;
fixtureDef.restitution = .2;
fixtureDef.friction = .2;
//设置刚体形状,并赋值给fixtureDef
//一个横着的矩形
var shape:b2PolygonShape = new b2PolygonShape();
shape.SetAsBox(50/30, 5/30);
fixtureDef.shape = shape;
bodyA.CreateFixture(fixtureDef);
//加一个竖着的矩形
shape.SetAsBox(5 / 30, 50 / 30);
fixtureDef.shape = shape;
//生成刚体bodyA的形状
bodyA.CreateFixture(fixtureDef);
//创建bodyB刚体
bodyB = LDEasyBox2D.createBox(world, posB.x, posB.y, 200, 50);
}
private function onStageMouseDown(e:MouseEvent):void
{
var dragBody:b2Body = LDEasyBox2D.getBodyAtMouse(world);
if (dragBody != null) {
LDEasyBox2D.startDragBody(world,dragBody,10000*dragBody.GetMass());
}
}
private function onStageMouseUp(e:MouseEvent):void
{
LDEasyBox2D.stopDragBody(world);
}
private function loop(e:Event):void
{
LDEasyBox2D.updateWorld(world);
}
}
}
|