<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DFdou&#039;s Blog &#187; APE</title>
	<atom:link href="http://nwhy.org/tag/ape/feed" rel="self" type="application/rss+xml" />
	<link>http://nwhy.org</link>
	<description>Life is short,Be yourself.</description>
	<lastBuildDate>Wed, 08 Sep 2010 05:34:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Flash-APE物理引擎学习</title>
		<link>http://nwhy.org/flash-ape-2.html</link>
		<comments>http://nwhy.org/flash-ape-2.html#comments</comments>
		<pubDate>Tue, 09 Mar 2010 02:46:34 +0000</pubDate>
		<dc:creator>DFdou</dc:creator>
				<category><![CDATA[AIR+FB+AS3]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[APE]]></category>
		<category><![CDATA[Physics Engine]]></category>

		<guid isPermaLink="false">http://nwhy.org/?p=5148</guid>
		<description><![CDATA[昨天整理了下代码，新的Demo在这里： 在说具体实现之前，丢个Flash物理引擎在产品展示中的应用：http://www.carlosulloa.com/. 这是一款汽车产品的展示平台，用方向键控制机车移动，点鼠标左键复... ]]></description>
			<content:encoded><![CDATA[<p>昨天整理了下代码，新的Demo在这里：</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="600" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://nwhy.org/nwhy/game/bubble-bobble.swf" /><embed type="application/x-shockwave-flash" width="400" height="600" src="http://nwhy.org/nwhy/game/bubble-bobble.swf"></embed></object></p>
<p>在说具体实现之前，丢个Flash物理引擎在产品展示中的应用：<a  href="http://www.carlosulloa.com/">http://www.carlosulloa.com/</a>.<br />
这是一款汽车产品的展示平台，用方向键控制机车移动，点鼠标左键复位汽车初始位置。<br />
不过，这个不是2d物理引擎完成的，而是基于PV3D的，，，，恩，3D物理引擎是在比较难搞……有时间尝试整理下……</p>
<p>下边来说下Demo的具体实现，首先要收下物理引擎，物理引擎是干嘛用的呢？<br />
物理引擎是一个处理物理现象的引擎。</p>
<p>那什么是物理现象呢？<br />
举个例子，一个风筝在天上飞，它会受到风力，阻力，摩擦力，还有重力，绳子的作用力，etc。。。而物理引擎就是帮你处理这些力的一个框架集。<br />
你要做的就是给它个重力，然后都作用在风筝上，至于这些里之间的相互作用，都由引擎来搞定。</p>
<p>下边来代码，先是文档类，也就是主容器了：<br />
[js]<br />
package org.nwhy.bubble_bobble{<br />
	import flash.display.*;<br />
	import flash.events.Event;<br />
	import org.cove.ape.*;</p>
<p>	public class BubbleBobble extends Sprite{<br />
		private var bulletHolder:Group;</p>
<p>		public function BubbleBobble(){<br />
			init();<br />
		}<br />
		private function init(){<br />
			initStage();<br />
			initGroups()<br />
		}<br />
		private function initStage(){<br />
			stage.scaleMode = StageScaleMode.NO_SCALE;//设置为不缩放<br />
			//stage.align = StageAlign.TOP_LEFT;<br />
			stage.frameRate = 55;//设置帧频<br />
			stage.addEventListener(Event.ENTER_FRAME, run);<br />
		}<br />
		private function initGroups(){<br />
			//初始化2D物理引擎<br />
			APEngine.init(1/4);<br />
			APEngine.container = this;<br />
			APEngine.addForce(new VectorForce (false,0,1));//加上重力</p>
<p>			//放bullet的容器,bullet就是那个各种颜色的球～<br />
			bulletHolder = new Group(true);<br />
			APEngine.addGroup(bulletHolder);</p>
<p>			//加入墙壁<br />
			var wall:Wall = new Wall();<br />
			APEngine.addGroup(wall);</p>
<p>			//gun,就是下边那个大伯说有点像啥的那个啥……囧一个<br />
			var gunGroup:GunGroup = new GunGroup(stage);<br />
			APEngine.addGroup(gunGroup);</p>
<p>			//设置bullet的碰撞检测内容<br />
			bulletHolder.addCollidableList(new Array(wall,gunGroup));<br />
		}<br />
		private function run(e:Event) {<br />
			APEngine.step();<br />
			APEngine.paint();<br />
		}<br />
		//增加bullet的对外接口<br />
		public function addBullet(bullet:CircleParticle){<br />
			bulletHolder.addParticle(bullet);<br />
		}<br />
	}<br />
}<br />
[/js]<br />
这里边干的事就是加入各种Group(APE物理引擎里的碰撞单元是Particle，单个或多个Particle组成Group)，至于Group里具体是啥Group里自己处理。<br />
<span id="more-5148"></span><br />
接下去是简单的Wall类，里边就是4个方块放在四周：<br />
[js]<br />
package org.nwhy.bubble_bobble{<br />
	import org.cove.ape.*;</p>
<p>	public class Wall extends Group {<br />
		private var left:RectangleParticle;<br />
		private var right:RectangleParticle;<br />
		private var top:RectangleParticle;<br />
		private var bottom:RectangleParticle;</p>
<p>		public function Wall() {<br />
			//上边的挡板<br />
			top = new RectangleParticle(200,-10,440,20,0,true);//PS:APE是以坐标中心点为坐标原点,所以x,y的起始位置是宽高的一半<br />
			addParticle(top);<br />
			top.sprite.cacheAsBitmap = true;<br />
			//下边的挡板<br />
			bottom = new RectangleParticle(200,610,440,20,0,true);<br />
			addParticle(bottom);<br />
			bottom.sprite.cacheAsBitmap = true;<br />
			//左边的挡板<br />
			left = new RectangleParticle(-10,300,20,640,0,true);<br />
			addParticle(left);<br />
			left.sprite.cacheAsBitmap = true;<br />
			//右边的挡板<br />
			right = new RectangleParticle(410,300,20,640,0,true);<br />
			addParticle(right);<br />
			right.sprite.cacheAsBitmap = true;<br />
		}<br />
	}<br />
}<br />
[/js]<br />
很简单的一个类，什么功能都木有，就是加入4个方块，放在四周。<br />
然后是这个例子里比较复杂的GunGroup.as:<br />
[js]<br />
package org.nwhy.bubble_bobble{<br />
	import flash.display.DisplayObjectContainer;<br />
	import flash.display.Stage;<br />
	import flash.events.MouseEvent;<br />
	import org.cove.ape.*;</p>
<p>	public class GunGroup extends Group {<br />
		private var gun:RectangleParticle;//gun实例<br />
		private var angle:Number;//gun的角度<br />
		private var mStage:Stage;//stage值,用来添加鼠标事件用的</p>
<p>		public function GunGroup(mStage:Stage,collideInternal:Boolean = false) {<br />
			//生成gun实例<br />
			gun = new RectangleParticle(200,600,82,10,0,true,1,0.75);<br />
			addParticle(gun);<br />
			gun.setDisplay(new Gun());<br />
			gun.sprite.cacheAsBitmap = true;</p>
<p>			//添加监听<br />
			this.mStage = mStage;<br />
			this.mStage.addEventListener(MouseEvent.MOUSE_MOVE, rotateGun);<br />
			this.mStage.addEventListener(MouseEvent.MOUSE_DOWN, fire);<br />
		}<br />
		//处理鼠标移动时gun的角度旋转<br />
		private function rotateGun(e:MouseEvent) {<br />
			angle = Math.atan2(550-mStage.mouseY,mStage.mouseX-200)* 180 / Math.PI;<br />
			gun.sprite.rotation = -angle;<br />
		}<br />
		//处理鼠标点击时gun的bullet发射<br />
		private function fire(e:MouseEvent) {<br />
			var bullet:Bullet=new Bullet();<br />
			//生成一个bullet实例,具体位置是个比较复杂的数学公式……<br />
			var b:CircleParticle = new CircleParticle(200+45*Math.sin((90-angle)*Math.PI/180),550+45*(1-Math.cos((90-angle)*Math.PI/180)),6,false,2);<br />
			//给bullet一个力<br />
			b.addForce(new VectorForce(false,150*Math.sin((90-angle)*Math.PI/180),-130*(Math.cos((90-angle)*Math.PI/180))));<br />
			//监听下碰撞<br />
			b.addEventListener(CollisionEvent.COLLIDE, checkCollision);<br />
			//给它一个皮肤<br />
			b.setDisplay(bullet);<br />
			//调用主容器里的addBullet接口函数<br />
			(DisplayObjectContainer)(APEngine.container).addBullet(b);<br />
		}<br />
		//碰撞处理,这里是随机一个1/4的几率让粒子固定<br />
		private function checkCollision(e:CollisionEvent) {<br />
			if (Math.random()>0.75) {<br />
				e.currentTarget.fixed = true;<br />
			}<br />
		}<br />
	}<br />
}<br />
[/js]<br />
最后是最简单的一个类，Bullet.as<br />
[js]<br />
package org.nwhy.bubble_bobble{<br />
	import flash.display.Sprite;<br />
    import flash.geom.ColorTransform;</p>
<p>	import org.cove.ape.*;</p>
<p>	public class Bullet extends Sprite {<br />
		public function Bullet() {<br />
			//随机改变一下颜色<br />
            var rOffset:Number = this.transform.colorTransform.redOffset + rand(-255,255);<br />
            var gOffset:Number = this.transform.colorTransform.greenOffset + rand(-255,255);<br />
			var bOffset:Number = this.transform.colorTransform.blueOffset + rand(-255,255);<br />
            this.transform.colorTransform = new ColorTransform(1, 1, 1, 1, rOffset, gOffset, bOffset, 0);<br />
		}<br />
		private function rand(min:Number,max:Number):Number{<br />
			return (Math.random()*(max-min)+min);<br />
		}<br />
	}<br />
}<br />
[/js]<br />
其实这个类啥也没干，就是一个皮肤类，每次实例化的时候给个随机颜色。<br />
整个东西就是这个样子，.fla文件里有2个豆哥涂鸦的元件，源文件在这里：<br />
<a  href="http://dl.dropbox.com/u/477487/flash/game/bubble-bobble.rar">http://dl.dropbox.com/u/477487/flash/game/bubble-bobble.rar</a><br />
Have fun!~</p>
<h4  class="related_post_title">Some Related Posts</h4><ul class="related_post"><li>2010/03/05 -- <a href="http://nwhy.org/flash-ape-1.html" title="Flash &#8211; APE物理引擎学习<一>">Flash &#8211; APE物理引擎学习<一></a> (2)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://nwhy.org/flash-ape-2.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Flash &#8211; APE物理引擎学习</title>
		<link>http://nwhy.org/flash-ape-1.html</link>
		<comments>http://nwhy.org/flash-ape-1.html#comments</comments>
		<pubDate>Fri, 05 Mar 2010 05:01:49 +0000</pubDate>
		<dc:creator>DFdou</dc:creator>
				<category><![CDATA[AIR+FB+AS3]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[APE]]></category>
		<category><![CDATA[Physics Engine]]></category>

		<guid isPermaLink="false">http://nwhy.org/?p=5147</guid>
		<description><![CDATA[APE是什么就不介绍了，下边先上Demo: 点击鼠标发射子弹，击中那个囧就过关了。 代码实现其实也很简单，APE里边所有的Item都是以Group的形式存在。 在这个Demo里，上边的5个球是一组，例子里是A... ]]></description>
			<content:encoded><![CDATA[<p>APE是什么就不介绍了，下边先上Demo:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="500" height="400" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://nwhy.org/nwhy/game/JustForFun.swf" /><embed type="application/x-shockwave-flash" width="500" height="400" src="http://nwhy.org/nwhy/game/JustForFun.swf"></embed></object><br />
点击鼠标发射子弹，击中那个囧就过关了。<br />
代码实现其实也很简单，APE里边所有的Item都是以Group的形式存在。<br />
在这个Demo里，上边的5个球是一组，例子里是Avatar类，里边有5个WheelParticle，不知道为何CircleParticle没有旋转的。<br />
<span id="more-5147"></span><br />
来来，看代码:<br />
[js]<br />
package org.nwhy.JustForFun{<br />
	import org.cove.ape.*;</p>
<p>	public class Avatars extends Group {<br />
		public var ball1:WheelParticle;<br />
		public var ball2:WheelParticle;<br />
		public var ball3:WheelParticle;<br />
		public var ball4:WheelParticle;<br />
		public var ball5:WheelParticle;</p>
<p>		public function Avatars() {<br />
			ball1 = new WheelParticle(50,100,15,true,10);<br />
			var avatar = new Avatar();<br />
			avatar.gotoAndStop(1);<br />
			ball1.setDisplay(avatar);<br />
			addParticle(ball1);<br />
			ball1.sprite.cacheAsBitmap = true;</p>
<p>			ball2 = new WheelParticle(150,100,15,true,10);<br />
			avatar = new Avatar();<br />
			avatar.gotoAndStop(2);<br />
			ball2.setDisplay(avatar);<br />
			addParticle(ball2);<br />
			ball2.sprite.cacheAsBitmap = true;</p>
<p>			ball3 = new WheelParticle(250,100,15,true,10);<br />
			avatar = new Avatar();<br />
			avatar.gotoAndStop(3);<br />
			ball3.setDisplay(avatar);<br />
			addParticle(ball3);<br />
			ball3.sprite.cacheAsBitmap = true;</p>
<p>			ball4 = new WheelParticle(350,100,15,true,10);<br />
			avatar = new Avatar();<br />
			avatar.gotoAndStop(4);<br />
			ball4.setDisplay(avatar);<br />
			addParticle(ball4);<br />
			ball4.sprite.cacheAsBitmap = true;</p>
<p>			ball5 = new WheelParticle(450,100,15,true,10);<br />
			avatar = new Avatar();<br />
			avatar.gotoAndStop(5);<br />
			ball5.setDisplay(avatar);<br />
			addParticle(ball5);<br />
			ball5.sprite.cacheAsBitmap = true;<br />
		}<br />
	}<br />
}<br />
[/js]<br />
手动生成5个头像，当然你可以循环生成，这里本来是为了个性化定义的……<br />
然后就是文档类，JustForFun.as:<br />
[js]<br />
package org.nwhy.JustForFun{<br />
	import flash.display.*;<br />
	import flash.events.*;<br />
	import org.cove.ape.*;</p>
<p>	public class JustForFun extends Sprite {<br />
		var gun:Gun;<br />
		var bullet:Bullet;<br />
		private var target:WheelParticle;<br />
		private var bulletHolder:Group;<br />
		private var targetHolder:Group;<br />
		private var angle:Number;//gun的角度<br />
		private var avatars:Avatars;</p>
<p>		public function JustForFun() {<br />
			stage.scaleMode = StageScaleMode.NO_SCALE;<br />
			stage.align = StageAlign.TOP_LEFT;<br />
			stage.frameRate = 55;</p>
<p>			APEngine.init(1/4);<br />
			APEngine.container = this;<br />
			APEngine.addForce(new VectorForce (false,0,0.98));</p>
<p>			avatars = new Avatars();<br />
			for (var i:uint=1; i&lt;6; i++) {<br />
				avatars["ball" + i].addEventListener(CollisionEvent.COLLIDE, handleCollision);<br />
			}<br />
			APEngine.addGroup(avatars);</p>
<p>			bulletHolder = new Group();<br />
			APEngine.addGroup(bulletHolder);</p>
<p>			targetHolder = new Group();<br />
			target = new WheelParticle(100,20,15,true,10);<br />
			var targetDisplay:Target = new Target();<br />
			target.setDisplay(targetDisplay);<br />
			targetHolder.addParticle(target);<br />
			target.addEventListener(CollisionEvent.COLLIDE, handleCollision);<br />
			APEngine.addGroup(targetHolder);</p>
<p>			var gunGroup:GunGroup = new GunGroup();<br />
			gunGroup.gun.addEventListener(CollisionEvent.COLLIDE, handleCollision);<br />
			gun = new Gun();<br />
			gunGroup.gun.setDisplay(gun);<br />
			APEngine.addGroup(gunGroup);</p>
<p>			bulletHolder.addCollidableList(new Array(avatars,targetHolder));</p>
<p>			stage.addEventListener(Event.ENTER_FRAME, run);<br />
			stage.addEventListener(MouseEvent.MOUSE_MOVE, rotateGun);<br />
			stage.addEventListener(MouseEvent.MOUSE_DOWN, fireGun);<br />
		}<br />
		private function run(e:Event):void {<br />
			APEngine.step();<br />
			APEngine.paint();<br />
		}<br />
		private function rotateGun(e:MouseEvent) {<br />
			angle = Math.atan2(400-mouseY,mouseX-250)* 180 / Math.PI;<br />
			//trace(90-angle);<br />
			gun.rotation = -angle;<br />
		}<br />
		private function fireGun(e:MouseEvent) {<br />
			var b:CircleParticle = new CircleParticle(250+45*Math.sin((90-angle)*Math.PI/180),350+45*(1-Math.cos((90-angle)*Math.PI/180)),5,false,2);<br />
			b.addForce(new VectorForce(false,120*Math.sin((90-angle)*Math.PI/180),-120*(Math.cos((90-angle)*Math.PI/180))));<br />
			bullet = new Bullet();<br />
			b.setDisplay(bullet);<br />
			bulletHolder.addParticle(b);<br />
			bulletHolder.collideInternal = true;<br />
			//trace(90-angle,Math.sin((90-angle)* Math.PI / 180),100*Math.sin(90-angle));<br />
		}<br />
		// Everytime the ball hits a target or the pong, a CollisionEvent is raised and delt with here<br />
		private function handleCollision(e:CollisionEvent):void {<br />
			trace("Collision");<br />
			e.target.fixed = false;<br />
			if (e.target == target ) {<br />
				trace("succ");<br />
			}<br />
			e.target.removeEventListener(CollisionEvent.COLLIDE, handleCollision);<br />
		}<br />
	}<br />
}<br />
[/js]<br />
要注意的是APE的注册点是在中心，所以定位置的时候要注意，唉，如果你没注意到这个，肯定会被弄死。<br />
另外，Google group里边有个加强版的APE 0.45，加入了不少有用的类。如果你要扩展APE，一定要去看看。<br />
今天就到这里，下次见？</p>
<h4  class="related_post_title">Some Related Posts</h4><ul class="related_post"><li>2010/03/09 -- <a href="http://nwhy.org/flash-ape-2.html" title="Flash-APE物理引擎学习<二>">Flash-APE物理引擎学习<二></a> (7)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://nwhy.org/flash-ape-1.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
