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

搜索
查看: 2517|回复: 2
上一主题 下一主题

[2D 物理引擎] 【9RIA—ladeng6666】—【Box2D系列教程 8】让刚体听我的——ApplyForce、ApplyImpulse、SetLinearVelocity

[复制链接] TA的其它主题
发表于 2018-2-5 16:11:05 | 显示全部楼层 |阅读模式

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

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

x

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


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



对于大部分游戏来说,允许玩家控制游戏对象,是个非常基本的特性。而到目前为止,在学到的Box2D技巧中,创建了刚体之后,我们只能眼睁睁的看着它自由落体。我想,你肯定迫不及待的想“占有”它了,别急,今天我们就来学习一下,如何让刚体听我们的。

Box2D中控制一个刚体,让它乖乖的听我们的话,有三种方法:ApplyForce、ApplyImpulse和SetLinearVelocity。它们都是b2Body类的公共方法,而且它们都接收一个b2Vec2类型向量参数。关于向量的知识,请参考我之前发的文章"【游戏基础】向量基础".


1.力,循序渐进——ApplyForce
顾名思义,ApplyForce方法会在刚体上施加一个力。学过物理力学的同学都知道,F=ma,有了力F就有了加速度a,有了加速度,物体就会有速度,就会慢慢动起来。(但是不会立马动起来,因为力不会直接影响速度)。

举个简单的例子,小明推一个静止的箱子,箱子不会立马飞出去,而是慢慢的、越来越快的动起来(减速也一样)。

2.速度,叠加——ApplyImpulse
与ApplyForce不同,ApplyImpulse不会产生力,而是直接影响刚体的速度。通过ApplyImpulse方法添加的速度会与刚体原有的速度叠加,产生新的速度。

3.一触即发——SetLinearVelocity
setLinearVelocity与ApplyImpulse一样,直接影响刚体的速度。不一样的是,setLinearVelocity添加的速度会覆盖刚体原有的速度。不过,在SetLinearVelocity方法不会自动唤醒sleeping的刚体,所以在调用该方法之前,记得将刚体body.wakeUp()一下。

在下面的实例的右上角,任意选择其中一种方法,交替按下键盘左右方向键,查看三种方法的区别。



关于三个方法的用法,源代码中已经有详细的备注,我就不再解释了:
[Actionscript3] 纯文本查看 复制代码
package
{
    import com.bit101.components.Panel;
    import com.bit101.components.RadioButton;
    import com.bit101.components.Window;

    import Box2D.Common.Math.b2Vec2;
    import Box2D.Dynamics.b2Body;
    import Box2D.Dynamics.b2World;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;

    /**
     * [url]http://www.ladeng6666.com[/url]
     * @author ladeng6666
     */
    public class Main extends Sprite
    {
        //创建世界的基本元素
        private var world:b2World;
        private var debugSprite:Sprite;
        private var body:b2Body;

        private var vector:b2Vec2 = new b2Vec2();
        private var currentMethod:String = "ApplyForce";

        public function Main()
        {
            world=LDEasyBox2D.createWorld();
            debugSprite=LDEasyBox2D.createDebug(world);
            addChild(debugSprite);

            setWrapWalls();

            //创建矩形刚体
            body = LDEasyBox2D.createBox(world, stage.stageWidth / 2, 0, 30, 30);
            //侦听事件
            addEventListener(Event.ENTER_FRAME, loop);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, onStageKeyUp);

            setUI();
        }

        private function setWrapWalls():void
        {
            //创建左边的墙
            LDEasyBox2D.createBox(world, 0, stage.stageHeight / 2, 10, stage.stageHeight, true);
            //创建右边的墙
            LDEasyBox2D.createBox(world, stage.stageWidth, stage.stageHeight / 2, 10, stage.stageHeight, true);
            //创建地面,
            LDEasyBox2D.createBox(world,stage.stageWidth/2,stage.stageHeight,stage.stageWidth,10,true);
        }

        private function onStageKeyUp(e:KeyboardEvent):void
        {
            //清除速度或力
            vector.SetZero();
        }

        private function onStageKeyDown(ke:KeyboardEvent):void
        {
            switch (ke.keyCode) {
                case Keyboard.LEFT:
                    vector.x = -15;
                    break;
                case Keyboard.RIGHT:
                    vector.x = 15;
                    break;
            }
            trace(currentMethod);
            switch (currentMethod) {
                case "ApplyForce":
                    //在刚体上施加vector压力。
                    //body.GetWorldCenter()方法用来获取刚体的重心
                    body.ApplyForce(vector, body.GetWorldCenter());
                    break;
                case "ApplyImpulse":
                    //为刚体添加速度
                    body.ApplyImpulse(vector, body.GetWorldCenter());
                    break;
                case "SetLinearVelocity":
                    //唤醒刚体
                    body.WakeUp();
                    //设置刚体的线性速度
                    body.SetLinearVelocity(vector);
                    break;
            }            

        }

        private function loop(e:Event):void
        {
            world.Step(1 / 30, 10);
        }

        //下面的方法用来创建UI
        private function setUI():void
        {
            var panel:Panel = new Panel(stage, 400, 10);
            panel.width = 100;
            panel.height = 60;
            var radio1:RadioButton = new RadioButton(panel, 5, 5, "ApplyForce", true,onRadioChange);
            var radio2:RadioButton = new RadioButton(panel, 5, 25, "ApplyImpulse", false,onRadioChange);
            var radio3:RadioButton = new RadioButton(panel, 5, 45, "SetLinearVelocity", false,onRadioChange);
        }
        //侦听UI中的radio按钮变更事件
        private function onRadioChange(e:Event):void {
            currentMethod = e.target.label;
        }
    }

}



下载:
OK 2012-06-15 让刚体听我的——ApplyForce.rar (354.27 KB, 下载次数: 6)
发表于 2018-6-19 11:16:14 | 显示全部楼层
box2d 真的值得好好学学。
回复

使用道具 举报

发表于 2018-10-31 09:35:47 | 显示全部楼层
666666666666666666666
回复

使用道具 举报

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

本版积分规则

关闭

站长推荐 上一条 /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)



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