Actionscript 3 AS3-游戏计时器未正确计算开始时间

Actionscript 3 AS3-游戏计时器未正确计算开始时间,actionscript-3,timer,Actionscript 3,Timer,我正在根据Gary Rosenzweig最新的Actionscript 3书,在AS3中构建一个游戏。它有一个游戏计时器的问题,不只是我的问题,还有他的演示,我想不出来 游戏就像小行星一样,开始时四块石头被放置在舞台的角落,然后开始在舞台周围随机移动。问题是使用的计时器是在flash文件启动时启动的,而不是在播放器单击开始按钮时启动的。因此,如果你在开始屏幕上停留了5秒钟,然后在游戏实际开始时单击“玩”,那么在玩了5秒钟后,石头就会在那里,这可能就在玩家上方 我已经发布了我认为适用的代码部分。有

我正在根据Gary Rosenzweig最新的Actionscript 3书,在AS3中构建一个游戏。它有一个游戏计时器的问题,不只是我的问题,还有他的演示,我想不出来

游戏就像小行星一样,开始时四块石头被放置在舞台的角落,然后开始在舞台周围随机移动。问题是使用的计时器是在flash文件启动时启动的,而不是在播放器单击开始按钮时启动的。因此,如果你在开始屏幕上停留了5秒钟,然后在游戏实际开始时单击“玩”,那么在玩了5秒钟后,石头就会在那里,这可能就在玩家上方

我已经发布了我认为适用的代码部分。有人能告诉我如何修改这个,这样当玩家真正开始游戏时,石头会在适当的位置开始。我很确定这是我最后一个包含的函数,这就是问题所在,但我已经包含了其他相关部分,以提供更完整的图片

package {
import flash.display.*;
import flash.events.*;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.text.*;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.geom.Point;
import flash.net.SharedObject;
import flash.media.Sound;
import flash.media.SoundMixer;
import flash.media.SoundTransform;
import flash.media.SoundChannel;

Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

public class VirusDefender extends MovieClip {
    static const shipRotationSpeed:Number = .1;
    static const rockSpeedStart:Number = .03;
    static const rockSpeedIncrease:Number = .01;
    static const missileSpeed:Number = .2;
    static const thrustPower:Number = .15;
    static const shipRadius:Number = 20;
    static const startingShips:uint = 3;

    // game objects
    private var ship:Ship;
    private var rocks:Array;
    private var missiles:Array;

    // animation timer
    private var lastTime:uint;

    // arrow keys
    private var rightArrow:Boolean = false;
    private var leftArrow:Boolean = false;
    private var upArrow:Boolean = false;

    // ship velocity
    private var shipMoveX:Number;
    private var shipMoveY:Number;

    // timers
    private var delayTimer:Timer;
    private var shieldTimer:Timer;

    // game mode
    private var gameMode:String;
    private var shieldOn:Boolean;

    // ships and shields
    private var shipsLeft:uint;
    private var shieldsLeft:uint;
    private var shipIcons:Array;
    private var shieldIcons:Array;
    private var scoreDisplay:TextField;

    // score and level
    private var gameScore:Number;
    private var gameLevel:uint;

    // sprites
    private var gameObjects:Sprite;
    private var scoreObjects:Sprite;
    var gameBackground:GameBackground = new GameBackground();

    // sounds
    var sndFire:fire_sound;
    var sndFireChannel:SoundChannel;
    var sndThruster:thruster_sound;
    var sndThrusterChannel:SoundChannel;
    var sndShield:shield_sound;
    var sndShieldChannel:SoundChannel;
    var sndExplosion:explosion_sound;
    var sndExplosionChannel:SoundChannel;
    var sndBubble:bubble_sound;
    var sndBubbleChannel:SoundChannel;


    // start the game
    public function startSpaceRocks() {

        // set up sprites
        addChild(gameBackground);
        setChildIndex(gameBackground,0); // I added this
        gameObjects = new Sprite();
        addChild(gameObjects);
        scoreObjects = new Sprite();
        addChild(scoreObjects);

        // reset score objects
        gameLevel = 1;
        shipsLeft = startingShips;
        gameScore = 0;
        createShipIcons();
        createScoreDisplay();

        // set up listeners
        trace("add moveGameObjects event listener");
        addEventListener(Event.ENTER_FRAME,moveGameObjects);

        leftButton.addEventListener(TouchEvent.TOUCH_OVER,leftPress);
        leftButton.addEventListener(TouchEvent.TOUCH_OUT,leftRelease);

        rightButton.addEventListener(TouchEvent.TOUCH_OVER,rightPress);
        rightButton.addEventListener(TouchEvent.TOUCH_OUT,rightRelease);

        thrusterButton.addEventListener(TouchEvent.TOUCH_OVER,thrusterPress);
        thrusterButton.addEventListener(TouchEvent.TOUCH_OUT,thrusterRelease);

        shieldButton.addEventListener(TouchEvent.TOUCH_OVER,shieldPress);

        fireButton.addEventListener(TouchEvent.TOUCH_OVER,firePress);



        // Left Button
        function leftPress(event:TouchEvent):void{
            leftArrow = true;
        }           
        function leftRelease(event:TouchEvent):void{
            leftArrow = false;
        }

        // Right button
        function rightPress(event:TouchEvent):void{
            rightArrow = true;
        }
        function rightRelease(event:TouchEvent):void{
            rightArrow = false;
        }

        // Thruster button
        function thrusterPress(event:TouchEvent):void{
            sndThruster=new thruster_sound();
            sndThrusterChannel=sndThruster.play();
            upArrow = true;
            if (gameMode == "play") ship.gotoAndStop(2);
        }
        function thrusterRelease(event:TouchEvent):void{
            sndThrusterChannel.stop();
            upArrow = false;
            if (gameMode == "play") ship.gotoAndStop(1);
        }

        // Fire button
        function firePress(event:TouchEvent):void{
            sndFire=new fire_sound();
            sndFireChannel=sndFire.play();
            newMissile();
        }

        // Shield button
        function shieldPress(event:TouchEvent):void{
            startShield(false);
        }


        // start 
        gameMode = "delay";
        trace("gameMode - delay");
        shieldOn = false;
        missiles = new Array();
        trace("nextRockWave fired");
        nextRockWave(null);
        newShip(null);
    }


    // SCORE OBJECTS

    // draw number of ships left
    public function createShipIcons() {
        shipIcons = new Array();
        for(var i:uint=0;i<shipsLeft;i++) {
            var newShip:ShipIcon = new ShipIcon();
            newShip.x = 165+i*25; //165
            newShip.y = 273; //273
            scoreObjects.addChild(newShip);
            shipIcons.push(newShip);
        }
    }

    // draw number of shields left
    public function createShieldIcons() {
        shieldIcons = new Array();
        for(var i:uint=0;i<shieldsLeft;i++) {
            var newShield:ShieldIcon = new ShieldIcon();
            newShield.x = 310-i*25; //530
            newShield.y = 273; //15
            scoreObjects.addChild(newShield);
            shieldIcons.push(newShield);
        }
    }

    // put the numerical score at the upper right
    public function createScoreDisplay() {
        updateScore();
    }

    // new score to show
    public function updateScore() {
        score.text = addCommaInNumber(gameScore);
    }

    // remove a ship icon
    public function removeShipIcon() {
        scoreObjects.removeChild(shipIcons.pop());
    }

    // remove a shield icon
    public function removeShieldIcon() {
        scoreObjects.removeChild(shieldIcons.pop());
    }

    // remove the rest of the ship icons
    public function removeAllShipIcons() {
        while (shipIcons.length > 0) {
            removeShipIcon();
        }
    }

    // remove the rest of the shield icons
    public function removeAllShieldIcons() {
        while (shieldIcons.length > 0) {
            removeShieldIcon();
        }
    }


    // SHIP CREATION AND MOVEMENT

    // create a new ship
    public function newShip(event:TimerEvent) {
        // if ship exists, remove it
        if (ship != null) {
            gameObjects.removeChild(ship);
            ship = null;
        }

        // no more ships
        if (shipsLeft < 1) {
            endGame();
            return;
        }

        // create, position, and add new ship
        ship = new Ship();
        ship.gotoAndStop(1);
        ship.x = 240; //275
        ship.y = 160; //200
        ship.rotation = -90;
        ship.shield.visible = false;
        gameObjects.addChild(ship);

        // set up ship properties
        shipMoveX = 0.0;
        shipMoveY = 0.0;
        gameMode = "play";

        // set up shields
        shieldsLeft = 3;
        createShieldIcons();

        // all lives but the first start with a free shield
        if (shipsLeft != startingShips) {
            startShield(true);
            sndShield=new shield_sound();
            sndShieldChannel=sndShield.play();
        }
    }

    // animate ship
    public function moveShip(timeDiff:uint) {

        // rotate and thrust
        if (leftArrow) {
            ship.rotation -= shipRotationSpeed*timeDiff;
        } else if (rightArrow) {
            ship.rotation += shipRotationSpeed*timeDiff;
        } else if (upArrow) {
            shipMoveX += Math.cos(Math.PI*ship.rotation/180)*thrustPower;
            shipMoveY += Math.sin(Math.PI*ship.rotation/180)*thrustPower;
        }

        // move
        ship.x += shipMoveX;
        ship.y += shipMoveY;

        // wrap around screen
        if ((shipMoveX > 0) && (ship.x > 470)) {
            ship.x -= 490;
        }
        if ((shipMoveX < 0) && (ship.x < -20)) {
            ship.x += 500;
        }
        if ((shipMoveY > 0) && (ship.y > 320)) {
            ship.y -= 340;
        }
        if ((shipMoveY < 0) && (ship.y < -20)) {
            ship.y += 340;
        }
    }

    // remove ship
    public function shipHit() {
        gameMode = "delay";
        ship.gotoAndPlay("explode");
        sndExplosion=new explosion_sound();
        sndExplosionChannel=sndExplosion.play();
        removeAllShieldIcons();
        delayTimer = new Timer(2000,1);
        delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,newShip);
        delayTimer.start();
        removeShipIcon();
        shipsLeft--;
    }

    // turn on shield for 3 seconds
    public function startShield(freeShield:Boolean) {
        if (shieldsLeft < 1) return; // no shields left
        if (shieldOn) return; // shield already on

        // turn on shield and set timer to turn off
        ship.shield.visible = true;
        sndShield=new shield_sound();
        sndShieldChannel=sndShield.play();
        shieldTimer = new Timer(3000,1);
        shieldTimer.addEventListener(TimerEvent.TIMER_COMPLETE,endShield);
        shieldTimer.start();

        // update shields remaining
        if (!freeShield) {
            removeShieldIcon();
            shieldsLeft--;
        }
        shieldOn = true;
    }

    // turn off shield
    public function endShield(event:TimerEvent) {
        ship.shield.visible = false;
        shieldOn = false;
    }

    // ROCKS        

    // create a single rock of a specific size
    public function newRock(x,y:int, rockType:String) {
        trace("newRock fired");
        // create appropriate new class
        var newRock:MovieClip;
        var rockRadius:Number;
        if (rockType == "Big") {
            newRock = new Rock_Big();
            rockRadius = 35;
        } else if (rockType == "Medium") {
            newRock = new Rock_Medium();
            rockRadius = 20;
        } else if (rockType == "Small") {
            newRock = new Rock_Small();
            rockRadius = 10;
        }


        // choose a random look
        newRock.gotoAndStop(Math.ceil(Math.random()*3));

        // set start position
        newRock.x = x;
        newRock.y = y;

        // set random movement and rotation
        var dx:Number = Math.random()*2.0-1.0;
        var dy:Number = Math.random()*2.0-1.0;
        var dr:Number = Math.random();

        // add to stage and to rocks list
        gameObjects.addChild(newRock);
        setChildIndex(gameObjects,1); // I added this
        rocks.push({rock:newRock, dx:dx, dy:dy, dr:dr, rockType:rockType, rockRadius: rockRadius});
    }

    // create four rocks
    public function nextRockWave(event:TimerEvent) {
        rocks = new Array();
        newRock(30,30,"Big"); //100 100
        newRock(30,290,"Big"); // 100 300
        newRock(450,30,"Big"); // 450 100
        newRock(450,290,"Big"); // 450 300
        gameMode = "play";
    }

    // animate all rocks
    public function moveRocks(timeDiff:uint) {
        for(var i:int=rocks.length-1;i>=0;i--) {

            // move the rocks
            var rockSpeed:Number = rockSpeedStart + rockSpeedIncrease*gameLevel;
            rocks[i].rock.x += rocks[i].dx*timeDiff*rockSpeed;
            rocks[i].rock.y += rocks[i].dy*timeDiff*rockSpeed;

            // rotate rocks
            rocks[i].rock.rotation += rocks[i].dr*timeDiff*rockSpeed;

            // wrap rocks
            if ((rocks[i].dx > 0) && (rocks[i].rock.x > 470)) {
                rocks[i].rock.x -= 490;
            }
            if ((rocks[i].dx < 0) && (rocks[i].rock.x < -20)) {
                rocks[i].rock.x += 490;
            }
            if ((rocks[i].dy > 0) && (rocks[i].rock.y > 325)) {
                rocks[i].rock.y -= 345;
            }
            if ((rocks[i].dy < 0) && (rocks[i].rock.y < -25)) {
                rocks[i].rock.y += 345;
            }
        }
    }

    public function rockHit(rockNum:uint) {
        // create two smaller rocks
        sndBubble=new bubble_sound();
        sndBubbleChannel=sndBubble.play();
        if (rocks[rockNum].rockType == "Big") {
            newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Medium");
            newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Medium");
        } else if (rocks[rockNum].rockType == "Medium") {
            newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Small");
            newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Small");
        }
        // remove original rock
        gameObjects.removeChild(rocks[rockNum].rock);
        rocks.splice(rockNum,1);
    }


    // MISSILES

    // create a new Missile
    public function newMissile() {
        // create
        var newMissile:Missile = new Missile();

        // set direction
        newMissile.dx = Math.cos(Math.PI*ship.rotation/180);
        newMissile.dy = Math.sin(Math.PI*ship.rotation/180);

        // placement
        newMissile.x = ship.x + newMissile.dx*shipRadius;
        newMissile.y = ship.y + newMissile.dy*shipRadius;

        // add to stage and array
        gameObjects.addChild(newMissile);
        missiles.push(newMissile);
    }

    // animate missiles
    public function moveMissiles(timeDiff:uint) {
        for(var i:int=missiles.length-1;i>=0;i--) {
            // move
            missiles[i].x += missiles[i].dx*missileSpeed*timeDiff;
            missiles[i].y += missiles[i].dy*missileSpeed*timeDiff;
            // moved off screen
            if ((missiles[i].x < 0) || (missiles[i].x > 485) || (missiles[i].y < 0) || (missiles[i].y > 325)) {
                gameObjects.removeChild(missiles[i]);
                delete missiles[i];
                missiles.splice(i,1);
            }
        }
    }

    // remove a missile
    public function missileHit(missileNum:uint) {
        gameObjects.removeChild(missiles[missileNum]);
        missiles.splice(missileNum,1);
    }

    // GAME INTERACTION AND CONTROL
    public function moveGameObjects(event:Event) {
        // get timer difference and animate
        var timePassed:uint = getTimer() - lastTime;
        lastTime += timePassed;
        moveRocks(timePassed);

        if (gameMode != "delay") {
            moveShip(timePassed);
        }
        moveMissiles(timePassed);
        checkCollisions();
    }

    // look for missiles colliding with rocks
    public function checkCollisions() {
        // loop through rocks
        rockloop: for(var j:int=rocks.length-1;j>=0;j--) {
            // loop through missiles
            missileloop: for(var i:int=missiles.length-1;i>=0;i--) {
                // collision detection 
                if (Point.distance(new Point(rocks[j].rock.x,rocks[j].rock.y),
                        new Point(missiles[i].x,missiles[i].y))
                            < rocks[j].rockRadius) {

                    // remove rock and missile
                    rockHit(j);
                    missileHit(i);

                    // add score
                    gameScore += 10;
                    updateScore();

                    // break out of this loop and continue next one
                    continue rockloop;
                }
            }

            // check for rock hitting ship
            if (gameMode == "play") {
                if (shieldOn == false) { // only if shield is off
                    if (Point.distance(new Point(rocks[j].rock.x,rocks[j].rock.y),
                            new Point(ship.x,ship.y))
                                < rocks[j].rockRadius+shipRadius) {

                        // remove ship and rock
                        shipHit();
                        rockHit(j);
                    }
                }
            }
        }

        // all out of rocks, change game mode and trigger more
        if ((rocks.length == 0) && (gameMode == "play")) {
            gameMode = "betweenlevels";
            gameLevel++; // advance a level
            levelTextBox.text = "Infection: " + gameLevel;
            delayTimer = new Timer(2000,1);
            delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,nextRockWave);
            delayTimer.start();
        }
    }

    public function endGame() {
        // remove all objects and listeners
        removeChild(gameObjects);
        removeChild(scoreObjects);
        removeChild(gameBackground);
        gameObjects = null;
        scoreObjects = null;
        removeEventListener(Event.ENTER_FRAME,moveGameObjects);
        gameMode = "gameOver";
        gotoAndStop("gameover");
    }

    /***** ADD COMMAS TO NUMBERS *******/
    function addCommaInNumber (number : Number) : String
    {
        var integer : String = "" ;
        var fraction : String = "" ;
        var string : String = number.toString();
        var array : Array = string.split(".");
        var regex : RegExp = /(\d+)(\d{3})/;

        integer = array[0];

        while( regex.test(integer) )
        {
            integer = integer.replace(regex,'$1' + ',' + '$2');
        }

        if (array[1])
        { fraction = integer.length > 0 ? '.' + array[1] : ''; }

        return integer + fraction;
    }


}
包{
导入flash.display.*;
导入flash.events.*;
导入flash.events.TouchEvent;
导入flash.ui.multi-touch;
导入flash.ui.multi-touchinputmode;
导入flash.text.*;
导入flash.utils.getTimer;
导入flash.utils.Timer;
导入flash.geom.Point;
导入flash.net.SharedObject;
导入flash.media.Sound;
导入flash.media.SoundMixer;
导入flash.media.SoundTransform;
导入flash.media.SoundChannel;
Multitouch.inputMode=MultitouchInputMode.TOUCH\u点;
公共类VirusDefender扩展了MovieClip{
静态常数shipRotationSpeed:Number=.1;
静态常数rockSpeedStart:Number=.03;
静态常数rockSpeedIncrease:Number=.01;
静态常数导弹速度:数字=.2;
静态恒推力功率:数字=0.15;
静态常数shipRadius:编号=20;
静态常数启动船舶:uint=3;
//游戏物品
私人船舶:船舶;
私有变量:数组;
私人var导弹:阵列;
//动画定时器
上次私人var:uint;
//箭头键
私有变量rightArrow:Boolean=false;
私有变量leftArrow:Boolean=false;
私有变量向上箭头:布尔值=false;
//船速
私有var shipMoveX:编号;
私有var shipMoveY:编号;
//计时器
专用var延时定时器:定时器;
专用var屏蔽定时器:定时器;
//游戏模式
私有模式:字符串;
私有变量shieldOn:布尔值;
//船与盾
私人var shipsLeft:uint;
私有var-shieldsLeft:uint;
私有图标:数组;
私有变量屏蔽图标:数组;
私有变量显示:TextField;
//分数和水平
私有var gameScore:数字;
私有级别:uint;
//精灵
私人游戏对象:精灵;
私有对象:精灵;
var gameBackground:gameBackground=new gameBackground();
//听起来
var sndFire:火灾声;
var sndFireChannel:声音频道;
var sndThruster:推进器声音;
var sndThrusterChannel:声音通道;
var sndShield:屏蔽声音;
var sndShieldChannel:声音频道;
var sndExplosion:爆炸声;
var sndExplosionChannel:SoundChannel;
var SNDBUBLE:气泡声;
var sndBubbleChannel:SoundChannel;
//开始比赛
公共功能启动SpaceRocks(){
//设置精灵
addChild(游戏背景);
setChildIndex(gameBackground,0);//我添加了这个
gameObjects=新精灵();
addChild(游戏对象);
scoreObjects=新精灵();
addChild(scoreObjects);
//重置分数对象
游戏级别=1;
shipsLeft=启动船舶;
游戏分数=0;
createShipIcons();
createScoreDisplay();
//设置侦听器
跟踪(“添加moveGameObjects事件侦听器”);
addEventListener(事件输入帧,移动游戏对象);
leftButton.addEventListener(TouchEvent.TOUCH_OVER,leftPress);
leftButton.addEventListener(TouchEvent.TOUCH_OUT,leftRelease);
右键。添加EventListener(触摸事件。触摸结束,右按);
rightButton.addEventListener(TouchEvent.TOUCH_OUT,rightRelease);
推力器按钮。addEventListener(触摸事件。触摸结束,推力器按下);
PurcherButton.addEventListener(TouchEvent.TOUCH_OUT,PurcherRelease);
shieldButton.addEventListener(TouchEvent.TOUCH_OVER,shieldPress);
fireButton.addEventListener(TouchEvent.TOUCH\u OVER,firePress);
//左键
函数leftPress(事件:TouchEvent):无效{
leftArrow=true;
}           
函数leftRelease(事件:TouchEvent):void{
leftArrow=false;
}
//右键
功能rightPress(事件:TouchEvent):无效{
右箭头=真;
}
功能rightRelease(事件:TouchEvent):无效{
右箭头=假;
}
//推力器按钮
功能推进器压力(事件:触摸事件):无效{
sndThruster=新推进器_声音();
sndThrusterChannel=sndThruster.play();
向上箭头=真;
如果(游戏模式==“玩”)ship.gotoAndStop(2);
}
函数推力释放(事件:TouchEvent):无效{
sndThrusterChannel.stop();
向上箭头=假;
如果(gameMode==“play”)ship.gotoAndStop(1);
}
//点火按钮
功能壁炉(事件:TouchEvent):无效{
sndFire=新的火灾声音();
sndFireChannel=sndFire.play();
新导弹();
}
//屏蔽按钮
功能屏蔽按下(事件:TouchEvent):无效{
startShield(假);
}
//开始
gameMode=“延迟”;
跟踪(“游戏模式-延迟”);
谢尔顿=假;
导弹=新阵列();
跟踪(“发射下一次冲击波”);
下纵波(空);
新闻(空);
}
//记分对象
//画出剩余的船数
公共职能
private var myTimer:Timer = new Timer(delay, repeat);
// timers
private var delayTimer:Timer;
private var shieldTimer:Timer;
  // GAME INTERACTION AND CONTROL
  public function moveGameObjects(event:Event) {

        //Current Time
        var currentTime:uint = getTimer();

        //Initiate lastTime
        if(lastTime == 0) lastTime = currentTime;

        // get timer difference and animate
        var timePassed:uint = currentTime - lastTime;
        lastTime += timePassed;

        moveRocks(timePassed);

        if (gameMode != "delay") {
            moveShip(timePassed);
        }
        moveMissiles(timePassed);
        checkCollisions();
  }