Is this a good implementation of the gameloop

2020-03-30 02:38发布

I have implemented a gameloop in Flash/Actionscript/Starling and I want to throw it at you to see if this is a valid implementation. I wanted to have a variable time step approach.

private var _deltaTime:Number = 0;
private var _lastTime:Number = 0;
private var _speed = 1000 / 40;

private function onEnterFrame() {
    var now = new Date().getTime();
    var delta = now - _lastTime;
    _deltaTime += delta - _speed;
    _lastTime = now;

    //skip if frame rate to fast
    if (_deltaTime <= -_speed) {
        _deltaTime += _speed;
        return;
    }
    update();
}

private function update() {
    updateGameState();

    if (_deltaTime >= _speed) {
        _deltaTime -= _speed;
        update();
    }
}

What I got sofar is that I have a constant speed (more or less).

My question is is there a better approach so that the movements will appear even smoother.

What is really surprising to me is that even thou the FPS is pretty much constant (60FPS) the movement is sometimes bumpy yet smoother than with the naive gameloop.

2条回答
小情绪 Triste *
2楼-- · 2020-03-30 03:06

Youre on the right track - assuming that onEnterFrame is triggered in some way by Event.ENTER_FRAME - instead of skipping update, call it on every frame but pass in the time elapsed:

private function onEnterFrame() {
    var now = new Date().getTime();
    var delta = now - _lastTime;
    _lastTime = now;
    updateGameState(delta/1000);//divide by 1000 to give time in seconds
}

In updateGameState, you can utilise 'delta' to calculate movement etc, eg:

function updateGameState(timeElapsed:Number):void {
    myAlien.x += myAlienSpeedPerSecond*timeElapsed;
}

This way you get smooth movement even when frame rate varies.

查看更多
ら.Afraid
3楼-- · 2020-03-30 03:10

from the Starling introduction pages, it shows that time elapsed is built into the EnterFrameEvent class.

// the corresponding event listener
private function onEnterFrame(event:EnterFrameEvent):void
{
    trace("Time passed since last frame: " + event.passedTime);
    enemy.moveBy(event.passedTime * enemy.velocity);
}

http://wiki.starling-framework.org/manual/animation#enterframeevent

查看更多
登录 后发表回答