Nape柔体贴图教程2

上一节,我们大致学习了Nape柔体的贴图方法,最后我们还试着用一张图片进行贴图,但可惜的是图像并没有像我们预想的一样,随柔体形状改变,今天我们就来实现逼真的柔体贴图效果。

首先看一下拉登大叔实现的效果。貌似是不错,仔细看看确实很不错,哈哈!

[swfobject]1089[/swfobject]

没错,这就是我们想要实现的效果,很上一节教程一样,我们还是要遍历外围刚体的,但不同的是,现在我们不再使用lineTo和moveTo,而是使用另外一个稍微复杂一点的绘图API,叫做drawTriangles,具体我曾在《Foundation ActionScript3.0 Image effects》中的1.3.5 渲染三角形DrawTriangles一节讲过,具体请点开链接查看。

看过对应的教程之后,可以知道drawTriangles主要有三个参数,分别是vertices,indices和uvtData。首先我们来计算最后一个uvtData。

我们知道uvtData对应的三角形的顶点映射到图像上的位置,下面是柔体里的代码:

	var uvX:Number = (1 + Math.sin(angle))/2;
	var uvY:Number = (1 + Math.cos(angle))/2;
	uvData.push(uvX , uvY);

上面的代码我们不想解释的太复杂,看过下面的图示你就明白了。

uvData

然后一个是vertices数组,它包含了所有的顶点,这就简单了,和上一节我们用的lineTo()参数是一样的,代码如下:

	for(var i:int=0; i<bodyList.length; i++){
		var pos:Vec2 = bodyList.at(i).position.sub(centerBody.position);
		vertices.push(pos.x,pos.y);
		indices.push(0,i+1,((i+2)>bodyList.length?(i+2)%bodyList.length:(i+2)));
	}

最后一个是indices数组,上面的代码已经展现出来了。假设现在我们用4个三角形模拟一个圆形,如下图所示,

indices

图中用5个顶点组成了4个三角形,那么它们对应的indices数组应该是:

indices=[
0,1,2,
0,2,3,
0,3,4,
0,4,1
]

好了这就是本节的内容,具体代码如下:

package learnNape {
	import flash.events.KeyboardEvent;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.display.Sprite;
	import nape.constraint.PivotJoint;
	import nape.phys.BodyList;
	import nape.geom.Vec2;
	import ldEasyNape.LDEasyNape;
	import nape.phys.Body;
	import learnNape.AbstractNapeTest;

	/**
	 * @author yangfei
	 */
	public class T39_SoftBodyWithGraphic3 extends AbstractNapeTest {

		private var centerBody : Body;
		private var cx:Number = 200;
		private var cy:Number = 200;

		private var bodyNumbers:int = 20;
		private var radius : Number = 50;

		private var bodyList:BodyList;

		// use to add Graphic to softbody
		private var softBodyGraphic:Sprite;

		[Embed(source="../assets/ladeng6666.jpg")]
		private var LADENG : Class;
		private var ladeng6666:BitmapData;
		private var vertices:Vector.<Number>;
		private var indices:Vector.<int>;
		private var uvData:Vector.<Number>;

		override protected function onNapeWorldReady() : void {
			initGraphic();
			createSoftBody();
		}

		private function initGraphic() : void {
			softBodyGraphic = new Sprite();
			addChild(softBodyGraphic);

			ladeng6666 = Bitmap(new LADENG()).bitmapData;

			//initialize vertices , indices and uv par
			vertices = new Vector.<Number>();
			indices = new Vector.<int>();
			uvData = new Vector.<Number>();
			uvData.push(0.5,0.5);
		}

		private function createSoftBody() : void {
			centerBody = LDEasyNape.createCircle(cx, cy, 10);
			bodyList = new BodyList();

			for (var i:int = 0; i<bodyNumbers; i++){
				var angle : Number = Math.PI*2*i/bodyNumbers;
				var px : Number = cx + Math.sin(angle)*radius;
				var py : Number = cy + Math.cos(angle)*radius;
				var body :Body = LDEasyNape.createCircle(px, py, 5);
				bodyList.push(body);

				var uvX:Number = (1 + Math.sin(angle))/2;
				var uvY:Number = (1 + Math.cos(angle))/2;
				uvData.push(uvX , uvY);
			}
			var prevBody:Body, currBody:Body;

			for (var j:int=0;j< bodyList.length; j++){
				prevBody=bodyList.at((j-1+bodyList.length)%bodyList.length);
				currBody=bodyList.at(j);
				var sToSJoint : PivotJoint = new PivotJoint(prevBody, currBody, Vec2.weak(), currBody.worldPointToLocal(prevBody.position));
				sToSJoint.stiff = false;
				sToSJoint.space = napeWorld;

				var sToCJoint : PivotJoint = new PivotJoint(centerBody, currBody, centerBody.worldPointToLocal(currBody.position),Vec2.weak());
				sToCJoint.stiff = false;
				sToCJoint.damping = 1;
				sToCJoint.frequency = 3;
				sToCJoint.space = napeWorld;
			}
		}

		override protected function loop(event : Event) : void {
			super.loop(event);

			softBodyGraphic.x = centerBody.position.x;
			softBodyGraphic.y = centerBody.position.y;
			drawGraphic();
		}

		private function drawGraphic() : void {
			softBodyGraphic.graphics.clear();
			softBodyGraphic.graphics.beginBitmapFill(ladeng6666);

			vertices=new Vector.<Number>();
			indices = new Vector.<int>();

			vertices.push(0,0);

			for(var i:int=0; i<bodyList.length; i++){
				var pos:Vec2 = bodyList.at(i).position.sub(centerBody.position);

				vertices.push(pos.x,pos.y);
				indices.push(0,i+1,((i+2)>bodyList.length?(i+2)%bodyList.length:(i+2)));
			}
			softBodyGraphic.graphics.drawTriangles(vertices,indices,uvData);
			softBodyGraphic.graphics.endFill();
			softBodyGraphic.graphics.lineStyle(2);
			for(var j:int=0; j<bodyList.length; j++){
				var p:Vec2 = bodyList.at(j).position.sub(centerBody.position);

				softBodyGraphic.graphics.lineTo(p.x, p.y);
			}
		}

		override protected function keyBoardEventHanlder(event : KeyboardEvent) : void {
			super.keyBoardEventHanlder(event);
			if(event.type == KeyboardEvent.KEY_DOWN && event.keyCode ==32){
				centerBody.applyImpulse(Vec2.weak(0,-2000));
			}
		}
	}
}

点击下载源文件

 

联系作者

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

4 Replies to “Nape柔体贴图教程2”

发表回复

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