Это хорошая реализация игрового цикла?

Я реализовал игровой цикл во Flash/Actionscript/Starling и хочу показать его вам, чтобы убедиться, что это правильная реализация. Я хотел иметь подход с переменным шагом по времени.

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();
    }
}

Что я получил, так это то, что у меня постоянная скорость (более или менее).

Мой вопрос в том, есть ли лучший подход, чтобы движения выглядели еще более плавными.

Что меня действительно удивляет, так это то, что даже при том, что FPS в значительной степени постоянен (60 кадров в секунду), движение иногда неровное, но более плавное, чем с наивным игровым циклом.


person robkuz    schedule 21.02.2013    source источник
comment
Не создавайте новую дату каждый раз. Я думаю, что вместо этого должна быть статическая функция.   -  person Rajavanya Subramaniyan    schedule 27.11.2013


Ответы (2)


Вы на правильном пути - предполагая, что onEnterFrame каким-то образом запускается Event.ENTER_FRAME - вместо того, чтобы пропускать обновление, вызывайте его для каждого кадра, но пропускайте истекшее время:

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
}

В updateGameState вы можете использовать «дельту» для расчета движения и т. д., например:

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

Таким образом, вы получаете плавное движение даже при изменении частоты кадров.

person Community    schedule 21.02.2013
comment
почему и что мне делать в методе обновления с прошедшим временем? - person robkuz; 21.02.2013
comment
извините, случайно сохранил ответ, прежде чем я закончил. имеет больше смысла сейчас? - person ; 22.02.2013
comment
да и нет ;-) что мне действительно трудно понять, так это то, как перемещать долю пикселя. Обычно я перемещаю своего персонажа на 2 пикселя каждые 25 мс. И как сохранить позицию. - person robkuz; 22.02.2013
comment
2 пикселя каждые 25 мс соответствуют 80 пикселям в секунду, поэтому в моем примере вы должны установить myAlienSpeedPerSecond = 80; - person ; 22.02.2013

из вводных страниц Starling видно, что истекшее время встроено в класс EnterFrameEvent.

// 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

person theLucre    schedule 18.11.2013