About

<#TEMPLATE_INCLUDE_NINEPAGE_ABOUTME#>
  • May

    27

    AS 判断奇偶速度对比

    • 0 Comments
    • Flash Platform
    (i % 2) == 0                //10106,最慢
    ((i * 0.5)(i >> 1)) == 0 //2974,好奇葩
    (i & 1) == 1                //2277,最快
    !(i & 1)                    //2612,还可以

    May

    19

    字符串与数字作为键时,优先转换成数字索引优先,数字索引从 0 开始:

    import flash.utils.Dictionary;
    var d:Dictionary = new Dictionary();
    var obj1:Object = new Object();
    var obj2:Object = new Object();
    d["a"] = 1;//a string
    d[0] = "1";//0 number
    d["1"] = 1;//1 number
    d[1] = 1;//1 number
    //特别注意下面这两行
    d[-1] = "2";//-1 string
    d["-1"] = -1;//-1 string
    for(var key:* in d)
     trace(key , typeof key);

    上面看起来好像是加了 6 个键,但实际上因为 Key 会自动转型,所以只有 4 个键。当字符串"1"出现在键时,数字段先的原则,会变成 1;当数字 -1 出现在键时,因为数字索引从 0 开始,所以无法变成数字索引,变成了字符串的键"-1"。

    May

    12

    血浓于水的亲情:《失孤》

    • 0 Comments
    • Movies, TV and Celebrities

     

    无论相隔多远,相隔多么久远,血浓于水的亲情是永远不会断的。

    May

    9

     

    国内第一本 Apple Watch 软件开发实战书,与 Apple Watch 硬件同步上市,全面讲解 Apple Watch 软件开发的知识体系,从理论到实践一步到位。

    May

    9

     

    多年来,Box2D 这款物理引擎深受开发者喜爱。既便是在新起的 HTML5 技术中,因为 Box2D 它的跨平台性,使得它仍然可以完美的应用在基于 JS 的 HTML5 项目。而《Box2D 物理游戏编程初学者指南》正是引领初学者进入物理引擎少有的好书(本身专门讲解某个物理引擎的中文书籍就不多)书中有大量的游戏效果示例,想要学习物理游戏开发者强烈建议购买。

    May

    8

    private function ballToWallInteractionListener(cb:InteractionCallback):void 
    {
          //虽然没有看过 Haxe 的源码,但可以确定 Nape 刚体在清除之前并不需要调用 clear() 方法
          //ball.shapes.clear();

          space.bodies.remove(ball);

          ball.space = space;    

          //如果不添加新的形状,刚体的 ShapeList 实际上并没有保留任何对象,在 remove 时已经清空了 ShapeList
          //但刚体的速率 velocity,位置 position 之类引用的 Vec2 属性值是仍然保留的,并不会被重置
          ball.shapes.add(new Circle(10));
    }

    May

    8

    Nape:碰撞检测时移除刚体

    • 1 Comments
    • Flash Platform

    Rigid body(刚体)在选择从 Nape 中移除时,要选择好“时机”,否则在 step()  将会引发错误。比如在小球撞击墙面使用如下代码:

    //假装很高级的样子,省略了一些代码
    //......
    private var preListener:PreListener = new PreListener(InteractionType.COLLISION, ballType, wallType, ballToWallPreListener);

    //......
    space.listeners.add(preListener);

    //重点来了
    private function ballToWallPreListener(cb:PreCallback):void 
    {
        space.bodies.remove(ball);
    }

    这时就会引发一个类似如下的错误(因为在迭代运算时需要继续用到刚体对象):

    TypeError: Error #1009: 无法访问空对象引用的属性或方法。
        at zpp_nape.space::ZPP_Space/narrowPhase()
        at zpp_nape.space::ZPP_Space/continuousCollisions()
        at zpp_nape.space::ZPP_Space/step()
        at nape.space::Space/step()

     修改成下面这样子就可以了(迭代运算结束了):  

    //假装很高级的样子,省略了一些代码
    //......
    private var interactionListener:InteractionListener = new InteractionListener(CbEvent.BEGIN, InteractionType.COLLISION, ballType, wallType, ballToWallInteractionListener);

    //......
    space.listeners.add(interactionListener);

    //重点来
     private function ballToWallInteractionListener(cb:InteractionCallback):void 
    {
      space.bodies.remove(ball);// OK
    }

    May

    8

    碎碎念:程序员的问题

    • 0 Comments
    • Babblings

    程序员的问题在于他永远都有处理不完的问题。

    May

    8

    对刚体的弹性系数 elasticity 设为最大值1,所有摩擦力 Friction 设为 0,但仍然发现它在撞击之后有速率的损失(能量损失?)

    样例代码如下,如果没有最后面那一段注释掉的代码,会发现它的速率一直在变小,虽然它变小的比较慢,它确实在变小(按官方的在线帮助手册 API 资料中所介绍的,elasticity 设为 1 的时候应该没有速率损失才对)。

    package
    {
        import flash.display.Sprite;
        import flash.events.Event;

        import nape.callbacks.CbType;
        import nape.geom.Vec2;
        import nape.phys.Body;
        import nape.phys.BodyType;
        import nape.shape.Circle;
        import nape.shape.Polygon;
        import nape.space.Space;
        import nape.util.BitmapDebug;

        [SWF(backgroundColor="#333333", frameRate="60", width="640", height="480")]    
        public class MainDemo extends Sprite 
        {
            private var space:Space = new Space(new Vec2(0,0));//无重力空间

            private var debug:BitmapDebug = new BitmapDebug(640480, 0x000000, true);

            private var wallType:CbType=new CbType();//墙类型
            private var ballType:CbType=new CbType();//球类型

            private var ball:Body;

            public function MainDemo():void 
            {
                addChild(debug.display);

                ball = addCircle();

                addWall(320,0,640,10);
                addWall(320,480,640,10);
                addWall(0,240,10,480);
                addWall(640,240,10,480);

                addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            }

            private function addCircle():Body 
            {
                var circle:Circle = new Circle(10);
                    circle.material.elasticity = 1;//弹性系数设到最大
                    circle.material.staticFriction = 0;//所有摩擦力为0
                    circle.material.dynamicFriction = 0;
                    circle.material.rollingFriction = 0;

                var napeBody:Body = new Body(BodyType.DYNAMIC, new Vec2(300300));
                    napeBody.cbTypes.add(ballType);                    
                    napeBody.shapes.add(circle);
                    napeBody.space = space;                
                    napeBody.velocity = new Vec2(400 , 400);//给它一个初始速度

                return napeBody;
            }

            private function addWall(pX:Number,pY:Number,w:Number,h:Number):void 
            {
                var polygon:Polygon = new Polygon(Polygon.box(w,h));
                    polygon.material.elasticity = 1;//弹性系数设到最大
                    polygon.material.staticFriction = 0;//所有摩擦力为0
                    polygon.material.dynamicFriction = 0;
                    polygon.material.rollingFriction = 0;

                var napeBody:Body = new Body(BodyType.STATIC,new Vec2(pX,pY));
                    napeBody.cbTypes.add(wallType);
                    napeBody.shapes.add(polygon);
                    napeBody.space = space;
            }

            private function enterFrameHandler(e:Event):void 
            {
                space.step(1/60);

                /*
                ///////////////////////
                //如果没有以下 5 行代码,速度就会越变越小
                var circleSpeed:Number = 500;
                var velocity:Vec2 = ball.velocity;
                var speed:Number = velocity.length;
                var ratio:Number = circleSpeed/speed;
                ball.velocity.muleq(ratio);
                ///////////////////////
                */


                trace(ball.velocity.length);//输出速率大小

                debug.clear();
                debug.draw(space);
                debug.flush();
            }

        }

    }

    使用了最后一段注释掉的代码之后,其实也可以设定更小的弹性系数,比如 elasticity 值为 0.5,它仍然可以保持恒定的速率(但从外部动态的修改刚体的速率这会让我觉的很不科学的样子 - -!)。

    May

    5

    认识 Nape 三种刚体的类型

    • 0 Comments
    • Flash Platform

    如果不认识这三种刚体类型的特性,会遇到不少奇葩的问题。

    1、A static body - once assigned to a Space - is fixed; it cannot be moved or rotated, or have Shapes removed from it; a static body has no velocity. We can, however, perform mutations such as changing the shape materials.

    静态刚体:在添加到空间之前,就要确定好它的位置,否则一旦添加之后就不再允许改变位置,也不允许旋转之类的操作。如果对已经添加到空间的静态对象进行位置或旋转之类的操作,那么有可能会影响整个 Nape 空间的物理模似(亲测,碰撞检测真的失效了,不排除其它的物理特性也会失效)。但可以改变静态刚体的 Material 材质属性。所以一般很少用它,它用的最多的情况就是固定不变的对象模似,比如“地面”。

    2、A kinematic body is similar to a static body, except that it is permitted to have a velocity which will strictly define how the kinematic body moves. Such bodies will not be effected by gravity or any constraints including contacts. You can think of kinematic bodies as being animated.

    运动刚体:它和静态刚体类似,但允许设置它的速率,可以让它产生位置之类的变化。它不会受到物理模似的影响,比如重力、浮力或碰撞等。纯粹可以把这种类型的刚体当成动画对象。所以一般也很少用它。

    3、A dynamic body is under control of the physics simulation, it will fall under gravity, be pulled at by constraints and be effected by collisions and buoyancy forces.

    动态刚体:用的最多的就是这种类型,它是刚体的默认参数类型,它会受所有物理模似的影响,比如重力,浮力,弹力,拉力,碰撞等神马神马的一切。因为要参与物理模似,所以这个对象要有质量,如果质量为 0,那么它就不会参与任何物理模似,包括位置和速度的模似。