AS3定时器问题

时间:2013-08-16 00:54:52

标签: actionscript-3 class addeventlistener

所以我刚刚开始尝试从AS2合并到AS3,并且事情已经不像逻辑应该那样。我正在尝试制作一个简单的基于时间的粒子系统,只需一个发光的球影片剪辑即可产生焰火效果。有一个Main类和一个名为Ball的发光球类。问题是当我更改Main类中的addEventListener时,它将圆圈生成为:stage.addEventListener(MouseEvent.CLICK ...),由于某种原因,圆圈并不是都在同一点(中心)开始,并且我等待点击距离越远它们产生的时间越长......世界上我做错了什么?

主类:

package  {

    import flash.display.MovieClip;
    import flash.events.*;


    public class Main extends MovieClip {

        public function Main() {
            addEventListener(Event.ADDED_TO_STAGE, downed);
        }

        private function downed(event:Event){
                for(var i:int = 0; i < 50; i++){
                    var a:Ball = new Ball(275, 200, randomSpeed(), randomSpeed());
                    addChild(a);
                }
        }

        private function randomSpeed():int{
            var speed:int = Math.random()*150;
            if(Math.random() > .5){
                speed *= -1;
            }
            return speed;
        }
    }
}

球类:

package  {

    import flash.display.*;
    import flash.events.*;
    import flash.utils.getTimer;

    public class Ball extends MovieClip {
        private var speedX, speedY:Number;
        private var lastTime:int;
        private var gravity:int = 3.5;

        public function Ball(x:int, y:int, dx:int, dy:int):void {
            this.x = x;
            this.y = y;
            speedX = dx;
            speedY = dy;
            lastTime -= getTimer();
            this.addEventListener(Event.ENTER_FRAME, moveBall);
        }

        private function moveBall(event:Event){
            var timePassed:int = getTimer()-lastTime;
            lastTime += timePassed;

            this.x += (speedX*timePassed)/1000;
            this.y += (speedY*timePassed)/1000;
            speedY += gravity;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

在你的moveBall()方法中使用 getTimer()

Adob​​e说: 对于处理ActionScript 3.0的Flash运行时,此方法返回自ActionScript 3.0(AVM2)的Flash运行时虚拟机启动以来经过的毫秒数。

这意味着当您等待点击时,getTimer()返回的值将继续增长。

这就是为什么你正在经历球进一步分开的原因 - 你等待点击的时间越长,每个球的速度值就会增加,从而将每个球立即移动到速度值对应的第一个位置,这将是永远的你等待的距离越远当您使用添加到舞台事件时不会发生这种情况,因为在Flash文件开始运行时会立即添加球,并且getTimer()的值为0或太小而无法通知。

你的意图是什么?在球移动或减速时加速球?如果是后者,每次循环运行时,你都会从球速度中减去一个摩擦值。

public function moveBall(event:Event)
{
    var friction:Number = .7;
    speedX *= friction;
    speedY *= friction;

    this.x += speedX;
    this.y += speedY;
}

此外,还有一些提示:最好将所有粒子放入一个数组中,这样你就可以访问所有粒子,以便从舞台上移除,碰撞检测等。更好的想法是更新循环您的Main类遍历该粒子数组并在每个粒子中调用update方法,而不是每个粒子都有自己的enterFrame事件。这样你可以做一些事情,比如停止所有粒子,例如,当你想暂停游戏时,或者能够清理事件监听器以进行内存管理。