Я пытаюсь создать холст для развлечения и обучения, но мой код работает не так, как я хочу.
У меня есть персонаж в игре, который ходит вправо / влево / вверх / вниз, и каждое движение добавляет пиксель к изображению и создает анимацию.
Это означает, что если персонаж находится на 20px, 40px экрана и вы двигаетесь вправо, это будет 40px, 40px.
Мой код выглядит так:
start() {
this.deltaTime();
this.ctx.clearRect(0, 0, this.gameWindow.width, this.canvas.height);
this.map.drawMap();
this.player.drawPlayer();
this.text.drawText('Coordinates X:'+this.player.position.x+', Y:'+this.player.position.y, 5, 5);
this.text.drawText('FPS: '+this.graphic.lastfps, 5, 17);
this.text.drawText('ms: '+this.graphic.lastDelta, 5, 29);
this.text.drawText('delta: '+this.graphic.delta, 5, 41);
this.text.drawText('Running time: '+this.runningTime, 5, 53);
this.text.drawTextList();
}
deltaTime() {
// Calc FPS
let fps, delta;
let performanceUse = performance.now();
fps = delta = Math.floor(performanceUse / 1000);
if(this.graphic.lastTimeFPSDate !== fps) {
this.graphic.lastTimeFPSDate = fps;
this.graphic.lastfps = this.graphic.fps;
this.graphic.fps = 1;
this.runningTime++;
}
else
this.graphic.fps++;
// Calc Delta
this.graphic.delta = performanceUse - this.graphic.lastTimeDeltaCall;
this.graphic.lastTimeDeltaCall = performanceUse;
if(this.graphic.lastTimeDeltaDate !== delta) {
this.graphic.lastTimeDeltaDate = delta;
this.graphic.lastDelta = Math.floor(this.graphic.delta);
}
}
animationMove(to) {
let target;
let animationSpeed = (this.running) ? this.engine.gameSpeed.runSpeed : this.engine.gameSpeed.walkSpeed;
let distanceBettwenSquares = this.engine.mapSettings.pxPerSquare;
let seconds = 1000;
let everyStepAnimation = Math.ceil((60 / this.engine.graphic.lastfps));
let runLoopForAnimationEveryXMS = Math.floor(seconds / distanceBettwenSquares);
let stopLoop = false;
let sign = null;
//console.clear();
console.log('runLoopForAnimationEveryXMS: '+runLoopForAnimationEveryXMS+', everyStepAnimation: '+everyStepAnimation);
console.log('FPS: '+this.engine.graphic.lastfps+', deltaTime: '+this.engine.graphic.lastDelta);
console.log('REAL FPS: '+this.engine.graphic.fps+', REAL deltaTime: '+this.engine.graphic.delta);
// - - - - - - - - - -
this.engine.animationLoop(true, 0, runLoopForAnimationEveryXMS, (id) => {
// Stop the animation if it is 0 or bigger than the distance that require or stopLoop is true (which mean the numbers get over fed)
if (this.playerAnimation[target] === 0 || Math.abs(this.playerAnimation[target]) > distanceBettwenSquares || stopLoop) {
this.engine.animationLoop.kill(id);
this.playerAnimation.walk = false;
this.playerAnimation.needAnimation = true;
this.playerAnimation[target] = 0;
return;
}
// Do each step of the animation
sign = Math.sign(this.playerAnimation[target]);
this.playerAnimation[target] = sign * (Math.abs(this.playerAnimation[target]) - everyStepAnimation);
if (Math.sign(this.playerAnimation[target]) !== sign)
stopLoop = true;
});
}
function game() {
start();
window.requestAnimationFrame(game);
}
window.requestAnimationFrame(game);
При нажатии на клавишу сначала выполняется анимация (перемещение изображения на несколько пикселей каждый шаг), а затем обновляются переменные для текущей позиции.
Вот проблема:
Иногда анимация идет медленно, даже «прыгает».
Без реальных изменений FPS (1-2 + -).
Итак, мои вопросы:
- Во-первых, я правильно сделал расчет FPS и дельта? (Я не ошибся?)
- Как видите, я использовал в main для рисования деталей, а в setInterval для изменения деталей (чтобы изменения никогда не замедляли код), вот как это должно быть сделано?
- В моем коде я полагаю, что 60FPS является лучшим и основан на этом для каждого шага,
Я не хочу предполагать, что, возможно, в будущем FPS будет еще выше,
Так как же мне сделать, чтобы расчет за один ход (квадрат 20 пикселей) занял одну секунду?
- Иногда код работает медленно, а иногда быстрее, почему?
- Как мне использовать здесь в дельта-время?
- В первую секунду игры все идет на максимальной скорости, потому что FPS по-прежнему равен нулю. Как я могу это исправить?
Спасибо и извините за мой английский, даже ответ на один ответ поможет!