Nape中的WeldJoint—焊接关节

WeldJoint,weld的中文意思是”焊接”,所以我们姑且把WeldJoint叫做”焊接关节”。WeldJoint是受限的PivotJoint关节

正常情况下,PivotJoint连接的两个刚体是可以绕着anchor节点旋转的,而WeldJoint因为是”焊接”到一起的,所以无法绕anchor关节旋转。我们来看一下WeldJoint的构造函数:

public function PivotJoint(
	body1:Body,
	body2:Body,
	anchor1:Vec2,
	anchor2:Vec2,
	phase:Number):void

构造函数中的参数和PivotJoint基本一致,所以创建方法也是一样的。另外WeldJoint还多了一个phase参数,表示刚体body1的角度和刚体body2的角度之间的差别。

因为WeldJoint连接的两个刚体无法绕着anchor节点旋转,所以表面上看起来,他和组合法创建的Nape多边形刚体的效果是差不多的。不同的是,WeldJoint中的刚体是两个刚体,刚体之间依然会发生碰撞检测,而组合法创建的多边形刚体中连接的是两个或多个图形,他们之间不会有碰撞检测。

基于这个特性,我们可以用WeldJoint把两个刚体焊接在一起,然后在必要的时候去掉这个”焊点”。在下面的示例中,

  1. 黑色的两个刚体,用WeldJoint关节连接到了一起,点击上面的”Destroy”按钮可以断开和重新焊接这个关节。
  2. 点击舞台空白处,可以创建一个圆形和一个矩形刚体,他们同样用WeldJoint连接到了一起,点击矩形刚体可以进行拖动,点击圆形刚体可以删除WeldJoint关节,把两个刚体”拆开”。动手试试吧!

[swfobject]836[/swfobject]

完整的代码和注释如下:

package learnNape {
	import nape.constraint.Constraint;
	import nape.constraint.PivotJoint;
	import nape.constraint.ConstraintList;
	import nape.shape.ShapeType;
	import ldEasyNape.LDEasyUserData;
	import flash.events.MouseEvent;
	import com.bit101.components.PushButton;
	import nape.geom.Vec2;
	import nape.constraint.WeldJoint;
	import ldEasyNape.LDEasyNape;
	import nape.phys.Body;
	import learnNape.AbstractNapeTest;

	/**
	 * @author yangfei
	 */
	[SWF( width="550", height="400", frameRate="60")]
	public class T17_WeldJoint extends AbstractNapeTest {
		private var weldJoint : WeldJoint;

		private	var graphic : LDEasyUserData = new LDEasyUserData();
		public function T17_WeldJoint(gravity : Number = 600) {

		}

		override protected function onNapeWorldReady() : void {
			//创建黑色的刚体
			createWeldJointBridge();
			//创建舞台顶部的按钮
			createButton();
		}

		private function createWeldJointBridge() : void {
			//用LDEasyUserData快速子定义刚体贴图
			graphic.setGraphicAuotmatically(0);
			var body1 : Body = LDEasyNape.createBox(175, 200, 200, 20, false, false, graphic);
			var body2 : Body = LDEasyNape.createBox(375, 200, 200, 20, false, false, graphic);
			//将两个刚体分别固定在左边和右边,实现"开闸"的效果
			LDEasyNape.fixBodyAt(body1, 75, 200, -100);
			LDEasyNape.fixBodyAt(body2, 475, 200, 100);

			//创建weldJoint的节点
			var anchor : Vec2 = new Vec2(250,200);
			//anchor节点相对于body1和body2本地系统的坐标
			var anchor1 : Vec2 = body1.worldPointToLocal(anchor);
			var anchor2 : Vec2 = body2.worldPointToLocal(anchor);
			//创建weldJoint关节
			weldJoint = new WeldJoint(
										body1, 
										body2, 
										anchor1, 
										anchor2,
										0//表示两个刚体的相对角度,默认值也是0
										);
			weldJoint.space=napeWorld;
		}
		//当鼠标点击空白位置时,随机创建一个矩形刚体和圆形刚体,并用weldJoint关节连接
		private function createWeldJointAtMouse() : void {
			//===========================创建矩形刚体
			//定义随机的坐标
			var randomAngle : Number;
			var posX : Number , posY : Number;
			randomAngle = Math.random()* Math.PI;
			posX = Math.cos(randomAngle)*50 + mouseX;
			posY = Math.sin(randomAngle)*50 + mouseY;

			//用LDEasyUserData快速子定义刚体贴图
			graphic.setGraphicAuotmatically(0xFF0000);
			var body1 : Body = LDEasyNape.createBox(posX, posY, 30, 30, false, false, graphic);
			//===========================创建圆形刚体
			//定义随机的坐标
			randomAngle += Math.random()* Math.PI/2 + Math.PI/3;
			posX = Math.cos(randomAngle)*50 + mouseX;
			posY = Math.sin(randomAngle)*50 + mouseY;

			//用LDEasyUserData快速子定义刚体贴图
			graphic.setGraphicAuotmatically(0x0000FF);
			var body2 : Body = LDEasyNape.createCircle(posX, posY, 15, false, false, graphic);

			//用weldJoint将两个刚体焊接到一起
			var anchor : Vec2 = new Vec2(mouseX,mouseY);
			var anchor1 : Vec2 = body1.worldPointToLocal(anchor);
			var anchor2 : Vec2 = body2.worldPointToLocal(anchor);

			var joint : WeldJoint = new WeldJoint(
										body1, 
										body2, 
										anchor1, 
										anchor2);
			joint.space=napeWorld;
		}

		override protected function mouseEventHanlder(event : MouseEvent) : void {

			switch(event.type)
			{
				case MouseEvent.MOUSE_DOWN:
				{
					var bodyClicked : Body = LDEasyNape.getBodyAtMouse();
					LDEasyNape.startDragBody(bodyClicked);

					if(bodyClicked != null){
						//如果鼠标点击的是圆形刚体,则删除它的weldJoint关节
					   if(bodyClicked.shapes.at(0).type == ShapeType.CIRCLE){
							var joints : ConstraintList = bodyClicked.constraints;
							joints.foreach(function(j:Constraint):void{
								if(j is WeldJoint){
									//用constraints的remove方法,将制定的关节从列表中移除
									napeWorld.constraints.remove(j);
								}
							});
					   }
					}else if(event.target == stage){
						//如果点击的是舞台空白处,则创建weldJoint关节和相应的刚体
						createWeldJointAtMouse();
					}

					break;
				}
				case MouseEvent.MOUSE_UP:
				{
					LDEasyNape.stopDragBody();
					break;
				}
			}
		}
		//用Bit-101的minimalComp创建简单按钮 
		private function createButton() : void {
			var toggleButton : PushButton = new PushButton( this, 275, 20, "Destroy", function():void{
				if (toggleButton.label== "Destroy"){
					toggleButton.label = "Resume";
				}else{
					toggleButton.label = "Destroy";
				}
				//点击按钮后,激活或禁用weldJoint关节
				weldJoint.active = !weldJoint.active;
			});
			toggleButton.toggle = true;
		}
	}
}

点击下载源文件

联系作者

公众号:拉小登 | 微博:拉登Dony | B站:拉小登Excel

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注