2015-09-01 3 views
-1
var player = { 
    x : 10.0, 
    y : 10.0, 
    color : "blue", 
    v : 5.0, 
    size : 10, 
    render : function (c) { 
     c.fillStyle = this.color; 
     c.fillRect(Math.round(this.x), Math.round(this.y), this.size, this.size); 
    } 
}; 

function update(delta) { 
    player.x += player.v * (delta/1000); 
    console.log("px = " + player.x); 
} 

function mainLoop(timeStamp) { 
    delta = timeStamp - lastFrameTime; 
    lastFrameTime = timeStamp; 
    /* measure frame rate */ 
    curFps = Math.round((1/delta)*1000); 

    /* game logic */ 
    update(delta); 
    render(); 

    requestAnimationFrame(mainLoop); 
} 

Функция update() вызывается каждый кадр, когда необходимо обновить положение игрока. значение дельта ~ 16.00 (время в мс). Почему значение player.x отображается как NaN при печати?Почему этот результат вычисляется в NaN?

+3

Возможно, 'player.v' или' delta' 'undefined'. Каковы значения, если вы их регистрируете? – Kroltan

+3

Показать, как вы называете 'update' .... – epascarello

+1

Вы должны проверить переменную' delta', я запустил ваш код с передачей 'delta = 16' и' console.log ("px =" + player.x); ' show log обычно –

ответ

2

Ваша первая итерация цикла не будет иметь lastFrameTime, инициализированной нулем, она будет не определена. Number - undefined = NaN. Объявить lastFrameTime в верхней части вашей программы, как 0:

var lastFrameTime = 0; 

Прямо сейчас это неявное глобальный, то есть, потому что вы никогда не определял его var, это случайная глобальная переменная, Javascript создает внутри цикла.

+1

Не видел бы OP * «ReferenceError: lastFrameTime не определен» * или что-то похожее в их консоли? – Phil

+0

Только в первый раз, и если этот код работает один раз каждые 16 мс, его можно легко пропустить со всей другой консолью. – jmlsteele

+0

Я вижу его каждую итерацию – Phil

1

Моя догадка будет первый раз, когда код выполняется, lastFrameTime не определен, и поэтому дельта = метка времени - < неопределенными >, что приведет к дельта является NaN, которая будет приводить к player.x инкрементируется by NaN, превращая его в NaN, который он останется навсегда, так как мы продолжаем его увеличивать.

Я думаю, что ваше исправление либо инициализировать lastFrameTime, когда начинается ваш код (вероятно, к текущей метке времени), или изменить основной цикл константа выглядит

function mainLoop(timeStamp) { 
    delta = timeStamp - lastFrameTime; 
    lastFrameTime = timeStamp; 
    if (!isNaN(delta)) { 
     /* measure frame rate */ 
     curFps = Math.round((1/delta)*1000); 

     /* game logic */ 
     update(delta); 
     render(); 

     requestAnimationFrame(mainLoop); 
    } 
} 

Это будет пропускать первый, ошибочный, игровой цикл, где дельта NaN. Во втором прогоне lastFrameTime не будет неопределенным, дельта будет создана правильно, и все должно получиться.

Если пропустить первый цикл не по какой-либо причине, просто инициализируйте lastFrameTime чем-то здравым, и все должно быть в порядке.

+0

Я бы тоже пошел с 'var delta = ...'. Там уже слишком много глобальных переменных :) – Phil

+0

Я инициализировал lastFrameTime равным 0. Итак, в первом кадре дельта может быть неправильным значением, но это не должно быть NaN. Я также попробовал пропустить первый кадр, чтобы узнать, помогает ли он. Никакой помощи, я все еще вижу, что px является NaN. –

+0

Тогда, честно говоря, я понятия не имею. Я вижу ваш другой комментарий, говорящий, что mainloop вызывается с NaN в первый раз. Вы уверены, что это связано с обратным вызовом от requestAnimationFrame? Причина, по которой я спрашиваю, заключается в том, что я проверил код, который вы разместили локально, и он отлично работает (после того, как установлено lastFrameTime на 0 и удалит вызов для рендеринга). Вы прошли через свой код, чтобы убедиться, что вы его не вызываете случайно? – jmlsteele

Смежные вопросы