+ -
当前位置:首页 → 问答吧 → shineZ 菜鸟学物理引擎 as3 APE教程

shineZ 菜鸟学物理引擎 as3 APE教程

时间:2009-08-12

来源:互联网

FLASH的物理引擎.应用好像并不多.不过拿来玩玩也挺不错的..如果能够应用得好的话.放到游戏中效果应该不错..
我本人是从前两个月才开始正式使用as3的.所以算是菜鸟级了..现在来献献丑咯..毕竟在这论坛里也呆了几年了..学了不少东西..现在有机会也来教教新人啦..忽忽...

目前我知道的FLASH 2d物理引擎,应用比较多的大概就是Box2D和APE了..而Box2D虽然强大.但是太过于复杂了..所以本人也就选择了轻量级的APE了..简单好学.效果也并不差...
那么首先.大家可以到http://www.cove.org/ape/这里下载APE的最新版..其实很早以前就是这个版本了.好像一直没更新..右上角Downloads下第一个alpha 0.45 is the current release.

题外话.在GoogleCode上面有修改版.所以网上的教程有的出错的原因就是在于你的版本可能和教程作者的版本不同..我目前使用的是GoogleCode上面的修改版.其实就是先下载上面网站的alpha 0.45版.然后下载http://ape.googlecode.com/svn/trunk/source/org/cove/ape/这里的文件覆盖一下你下载的alpha 0.45版就行了..

在本文的结尾我会将已经下载并覆盖的版本用附件上传..当然如果能够上传的话..呵呵..

接下来.因为也是今天才刚接触了下APE.如果有不对的地方请高手多指点.大家一起进步..目前这还只是个初级教程..

APE的使用步骤.我归纳为5步.具体有哪5步呢?我列出一段代码并添加注释..
复制内容到剪贴板
代码:
//1.导入类包
import org.cove.ape.*;
import flash.events.Event;
//2.初始化引擎:
APEngine.init();//初始化引擎
APEngine.container = this;//指定容器;
APEngine.addForce(new VectorForce(false,0,5));//添加力;
//3.添加物体(粒子,约束,复合体,组...)
var defaultGroup:Group = new Group();//建一个默认组;
defaultGroup.collideInternal = true;//组内的对象互相之间有作用力;
var a:CircleParticle = new CircleParticle(350,30,5,false);//创建一个圆形粒子;
var b:CircleParticle = new CircleParticle(100,150,4,false);//创建一个圆形子;
var c:RectangleParticle = new RectangleParticle(stage.stageWidth/2,stage.stageHeight-10,stage.stageWidth,10,0,true);//创建一个矩形粒子;
var d:RectangleParticle = new RectangleParticle(0,stage.stageHeight/2,10,stage.stageHeight,0,true);
var e:RectangleParticle = new RectangleParticle(stage.stageWidth,stage.stageHeight/2,10,stage.stageHeight,0,true);
var wa: WheelParticle = new WheelParticle(150,10,15,false,2);//创建一个轮子粒子;
var wb: WheelParticle = new WheelParticle(200,10,15,false,2);//创建一个轮子粒子;
var wc:SpringConstraint = new SpringConstraint(wa, wb, 1, false);//创建一个约束,将两个轮子粒子连接起来;
defaultGroup.addParticle(a);//在组中添加a粒子;
defaultGroup.addParticle(b);//在组中添加b粒子;
defaultGroup.addParticle(c);//在组中添加c粒子;
defaultGroup.addParticle(d);//在组中添加d粒子;
defaultGroup.addParticle(e);//在组中添加e粒子;
defaultGroup.addParticle(wa);//在组中添加wa轮子粒子;
defaultGroup.addParticle(wb);//在组中添加wb轮子粒子;
defaultGroup.addConstraint(wc);//在组中添加约束;
//<!--这里应该调用Object.setStyle()或Object.setDisplay()来显示自己想要的外观-->
//4.将组添加到引擎;
APEngine.addGroup(defaultGroup);//将组添加到引擎,因为组的collideInternal属性为true,所以组内部的粒子会互相产生物理作用;
//5.添加侦听器.刷新粒子引擎;
stage.addEventListener(Event.ENTER_FRAME, run);
function run(evt:Event):void {
    APEngine.step();
    APEngine.paint();
}
//<!--额外添加代码-->
import flash.events.KeyboardEvent;
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyHandler);
stage.addEventListener(KeyboardEvent.KEY_UP,keyHandler);
function keyHandler(event:KeyboardEvent) {
    if (event.type==KeyboardEvent.KEY_DOWN) {
        if (event.keyCode==Keyboard.LEFT) {
            wa.angularVelocity = -0.1;
            wb.angularVelocity = -0.1;
            //轮子粒子向左滚动;
        } else if (event.keyCode==Keyboard.RIGHT) {
            wa.angularVelocity = 0.1;
            wb.angularVelocity = 0.1;
        }//轮子粒子向右滚动;
    } else {
        wa.angularVelocity = 0;
        wb.angularVelocity = 0;
        //轮子粒子停止滚动;
    }
}
代码看起来很多..实际上大家看一下我归纳的5步..并不复杂..这样就构建了一个简单的物理世界...快复制代码到flash的第一帧上去导出看效果吧.记得语言版本是AS3.0 哦!~
中间不明白的可以在楼下提问...构造函数中的参数大家可以自行查找API文档..
本篇文档中的例子部分修改自http://www.emanueleferonato.com/2007/10/23/ape-actionscript-physics-engine-tutorial-part-2/

附件

source.rar (96.42 KB)

2009-8-12 19:03, 下载次数: 168

作者: zijiguang   发布时间: 2009-08-12

有办法关闭横向碰撞。只检测纵向碰撞吗?

作者: enc0717   发布时间: 2009-08-12

老大..别玩我啦..忽忽...不好意思上午有点点小忙..
你这个问题我相信你自己是可以解决的吧..吓..我也才刚看这个类呢..
要关闭横向碰撞的话.其实可以通过一种变通的方式来做...我的思路如下.如有不对请指教:
APEngine通过静态的paint()方法让引擎运行.看API可以知道APEngine只能addGroup.而静态的paint()实际上也就是调用各个group实例的paint()方法..那么从继承关系来看修改Group的父类AbstractCollection的paint方法就可以实现您要的效果了.
:
复制内容到剪贴板
代码:
if ((! c.fixed) || c.alwaysRepaint) c.paint();
当然Group和Composite都是AbstractCollection的子类.所以上面的修改对Composite也是有效的.但是Group还可以包含AbstractItem的子类.所以还需要修改AbstractItem的子类源码.这里我奇怪的是为什么作者不在AbstractItem中直接写出paint函数的代码.而要在子类中override.这样的话就要分别修改各个子类的源码了.

大体思路就是这样..我目前也就只看到这些..接下来多做点实例再说...

PS:发现Group和Composite不能添加力.要添加只能给它们的内部的AbstractItem子类实例添加力.有些麻烦..并且AbstractItem的子类都有addForce却没有removeForce..实际上有.但是定义成了私有方法.不明白为什么.如果做游戏的时候需要在特定的物体上面增加主角的受力.可以增加却不能删除?或是再增加个反向的受力?APEngine有静态的removeForce和removeAllForce(并没有在API文档上使出.但源代码中有).AbstractItem子类也应该有吧.忽忽..还是得自己修改了.

作者: zijiguang   发布时间: 2009-08-13

物理引擎我真没研究。等你的Demo和讲解
很感谢你的分析,的确花了心思。

作者: enc0717   发布时间: 2009-08-13

实际上我想说还有个相当相当简单的办法..呵呵..
function run(evt:Event):void {
    APEngine.step();
    APEngine.paint();
}
这个函数是不停的触发的..可以将不受横向力影响的对象存入数组.然后在这个run里面循环设置所有的对象.让这些对象在paint后马上又移回之前的坐标..呵呵..应该不会出现抖动的吧..

这个类比较简单..也挺实用的..昨天那个游戏机智的朋友所需要的效果也正是这个效果了..不受横向力的影响.呵呵..

作者: zijiguang   发布时间: 2009-08-13

添加力addForce,我也没看到removeForce这个方法,我觉得力,说白了就是每一帧与原位置的位移就是力,比如一个力为:force.vx = 3; force.vy = 3;添加一个反方向的力vforce= new VectorForce (false, -1, -2); 就是在原力的基础上force.vx=3-1, force.vy = 3-2。
    楼主我有个疑问:Object.setDisplay(),我所添加粒子的外观并不是规则的,碰撞检测时候,很不准确,怎样可以提高准确度?期待楼主帮助!

作者: whjzuiai   发布时间: 2009-08-13

不规则的外观需要使用复合体...我还不太明白复合体和组的区别...
复合体中用多个基本形状+弹性约束来达到你想要的形态...不过太复杂的还是会很占CPU的..
关于力...APE将力存入了一个数组中..不知道有什么意义...呵呵..先用熟了再说..

作者: zijiguang   发布时间: 2009-08-13

附件中的源码在fb下报错,貌似是调用父类的构造方法中参数传递不正确,哪个类我给忘了。。

[ 本帖最后由 junlas 于 2010-3-15 23:30 编辑 ]

作者: junlas   发布时间: 2010-03-13

google code的修改版本 修改了哪些内容??

作者: hack86   发布时间: 2010-05-02

复制楼主的发的code 报错了~~~
汗~~~

作者: hack86   发布时间: 2010-05-02

感谢楼主的精心教程,很用心。谢谢!

作者: loveroseboy   发布时间: 2010-12-06