11RIA 闪客社区 - 最赞 Animate Flash 论坛

搜索
查看: 2061|回复: 0
上一主题 下一主题

[2D 物理引擎] 【9RIA—ladeng6666】—【Box2D系列教程 19】Box2D关节——”距离关节”b2DistanceJoint

[复制链接] TA的其它主题
发表于 2018-2-6 14:24:40 | 显示全部楼层 |阅读模式

【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

转载:9RIA游戏开发者社区(天地会)
作者:ladeng6666(拉登大叔)
作者博客:http://www.ladeng6666.com/blog/


【Box2D系列教程-导航帖】—拉登大叔出品(总贴)


在上一篇文章中,我们初步认识了Box2D中的b2Joint关节类。今天我们开始学习具体的Box2D关节类,即b2Joint的子类。首先我们从b2DistanceJoint类开始。

b2DistanceJoint关节,从它的名字可以猜到距离关节的作用:通过固定长度的关节将两刚体联系到一起,使这两个刚体始终保持一定的距离。可以像想象的出来吗?如果这样解释很难理解,那就想想自行车吧。把自行车的两个轱辘当成刚体,车架就是关节,两个轱辘可以自由的旋转,但是因为有车架的限制,两个轱辘之间始终保持一定的距离。

zixingche.jpg
了解了b2DistanceJoint的定义,下面我们来看看创建过程。在初认识Box2D中的b2Joint关节类中,我们知道所有的关节都可以用initialize方法来创建,b2DistanceJoint也不例外,它的initialize方法结构如下:
[Actionscript3] 纯文本查看 复制代码
	public function Initialize(
		bA:b2Body,
		bB:b2Body,
		anchorA:b2Vec2,
		anchorB:b2Vec2) : void


方法的每个参数功能如下:
    bA:即bodyA,关节连接的一个刚体。
    bB:即bodyB,关节连接的另一个刚体。
    anchorA:关节的端点A,通常为bodyA的中心位置。
    anchorB:关节的端点B,通常为bodyB的中心位置。
结合上图来看,两个车轮分别表示b2Distance的连接的两个刚体bA和bB,车轮中的两个红点分别表示关节的两个控制点,即车轮的中心点。

另外还可以用关节的collideConnected属性,设置关节连接的两个刚体之间是否进行碰撞检测。

在下面的示例中,我创建了两个大小不一的圆形刚体,大的为bodyA,小的为bodyB,选择右上角的radio选项,设置A或B为静态刚体,或者两个刚体都是动态刚体,同时给bodyA添加一个角速度,就成了一个简单的”自行车”。



完整的代码和注释如下:
[Actionscript3] 纯文本查看 复制代码
package
{
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2World;
	import Box2D.Dynamics.Joints.b2DistanceJoint;
	import Box2D.Dynamics.Joints.b2DistanceJointDef;
	import com.bit101.components.Panel;
	import com.bit101.components.RadioButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
 
	/**
	 * [url]http://www.ladeng6666.com[/url]
	 * @author ladeng6666
	 */
	public class DistanceJointTest extends Sprite
	{
		private var world:b2World;
		private var debugSprite:Sprite;
		private var bodyA:b2Body, bodyB:b2Body;
		private var posA:Point, posB:Point;
 
		private var joint:b2DistanceJoint;
 
		public function DistanceJointTest()
		{
			//设置Box2D舞台
			LDEasyBox2D.stage = stage;
			//用LDEasyBox2D快速创建世界
			world=LDEasyBox2D.createWorld();
			debugSprite=LDEasyBox2D.createDebug(world);
			addChild(debugSprite);
 
			//创建地面,
			LDEasyBox2D.createWrapWall(world, stage);
			//添加事件侦听器
			addEventListener(Event.ENTER_FRAME, loop);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
 
			//创建关节连接的两个刚体
			createBodies();
			//创建关节
			createDistanceJoint();
			//设置右上角的UI
			setUI();
		}
 
		private function createDistanceJoint():void
		{
			//声明关节需求
			var distanceJoint:b2DistanceJointDef = new b2DistanceJointDef();
			//实例化关节需求
			distanceJoint.Initialize(bodyA, bodyB, new b2Vec2(posA.x/30,posA.y/30), new b2Vec2(posB.x/30, posB.y/30));
			distanceJoint.collideConnected = false;
			//创建关节
			joint=world.CreateJoint(distanceJoint) as b2DistanceJoint;
		}
 
		private function createBodies(staticA:Boolean=false,staticB:Boolean=false):void
		{
			//设置连接刚体的坐标
			posA = new Point(100, 100);
			posB = new Point(200, 100);
			//用LDEasyBox2D静态类创建两个刚体
			bodyA = LDEasyBox2D.createCircle(world, posA.x, posA.y, 30, staticA);
			//给刚体A添加一个角速度,这样可以做一个简单的自行车
			bodyA.SetAngularVelocity(30/ 180 * Math.PI*30);
			bodyB = LDEasyBox2D.createCircle(world, posB.x, posB.y, 10, staticB);
 
		}
 
		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);
			//把下面的注释去点,看看更有趣的效果
			//bodyA.ApplyTorque(5*bodyA.GetMass());
		}
 
		private function setUI():void {
			var panel:Panel = new Panel(stage, 400, 30);
			panel.width = 100;
			panel.height = 60;
			var radio1:RadioButton = new RadioButton(panel, 5, 5, "no static", true,onRadioChange);
			var radio2:RadioButton = new RadioButton(panel, 5, 25, "bodyA is static", false,onRadioChange);
			var radio3:RadioButton = new RadioButton(panel, 5, 45, "bodyB is static", false,onRadioChange);
		}
 
		private function onRadioChange(e:Event):void
		{
			world.DestroyBody(bodyA);
			world.DestroyBody(bodyB);
			world.DestroyJoint(joint);
 
			switch(e.target.label) {
				case "no static":
					createBodies();
					break;
				case "bodyA is static":
					createBodies(true);
					break;
				case "bodyB is static":
					createBodies(false, true);
					break;
			}
			createDistanceJoint();
		}
	}
 
}


代码中用到了我写的静态类LDEasyBox2D。

点击刚体,还可以进行拖动,如果对鼠标拖动刚体,我建议你看看之前的让刚体听我的——鼠标拖动刚体。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

感谢所有支持论坛的朋友:下面展示最新的5位赞助和充值的朋友……更多赞助和充值朋友的信息,请查看:永远的感谢名单

SGlW(66139)、 anghuo(841)、 whdsyes(255)、 longxia(60904)、 囫囵吞澡(58054)

下面展示总排行榜的前3名(T1-T3)和今年排行榜的前3名的朋友(C1-C3)……更多信息,请查看:总排行榜今年排行榜

T1. fhqu1462(969)、 T2. lwlpluto(14232)、 T3. 1367926921(962)  |  C1. anghuo(147)、 C2. fdisker(27945)、 C3. 囫囵吞澡(58054)



快速回复 返回顶部 返回列表