HTML5 Canvas + js游戏 |死亡重置游戏会改变游戏速度吗?
HTML5 Canvas + js game | Reset game on death changes the game speeds up?
我正在尝试使用 HTML5 的 canvas 和 javascript 制作游戏。我相信我一直在做所有事情 "okay" 直到我需要在死亡时重置游戏。我不太确定是什么导致了意外行为,但我有想法。
差不多,游戏以 'x' 速度运行,然后当它重置时一切都移动得更快。我没有改变任何速度的任何变量,在调试和检查我的代码时,新创建的对象的速度与游戏第一次启动时的速度相同,但它们移动得更快。如果您再次死亡,它会再次重置并运行得更快。死亡、冲洗、重复,它一直在加速,直到页面可能达到 "not responding" 状态。
我不确定我做错了什么导致速度差异或至少是速度差异的错觉。我有一个想法,它与我的游戏循环有关 运行 每次重置时都会多次进入永远,但我不明白 how/why 它会那样做。感谢任何反馈。
此外,如果您需要的代码比我在下面发布的更多,您可以访问我的测试页面查看所有代码:game test playground
var windowx,
windowy,
canvas,
player,
quadTree,
ctx;
var drawObjects;
var keyState;
var mainloop;
var animFrame;
var ONE_FRAME_TIME;
var reset = function () {
//get canvas and set height and width
canvas = document.getElementById('canvas');
canvas.setAttribute('width', windowx / 2);
canvas.setAttribute('height', windowy / 2);
ctx = canvas.getContext("2d");
drawObjects = [];
keyState = {};
quadTree = new Quadtree(quadTreeBounds);
//make the friendly square
player = new Rectangle(20, 20, 40, 40, 0, 0, XPhysicsBehaviorNormal, YPhysicsBehaviorNormal, XBoundaryBehaviorInCanvas, YBoundaryBehaviorInCanvas, playerObjectType, '#580000', null);
drawObjects.push(player);
drawObjects.push(new Rectangle(40, 100, canvas.width + (distanceOutsideCanvasBeforeDie / 2), canvas.clientHeight - 100, defaultEnemyRectangleVelocity, 0, null, YPhysicsBehaviorNormal, null, YBoundaryBehaviorInCanvas, enemyObjectType, null, OutOfCanvasDieBehavior));
backgroundMusicAudio.play();
//define main loop
mainloop = function () {
buildQuadTree();
updateGame();
drawGame();
};
//define the windowanimationframeobject
animFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
null;
if (animFrame !== null) {
var recursiveAnim = function () {
mainloop();
animFrame(recursiveAnim, canvas);
};
// start the mainloop
animFrame(recursiveAnim, canvas);
} else {
// fallback to setInterval if the browser doesn't support requestAnimationFrame
ONE_FRAME_TIME = 1000.0 / 60.0;
setInterval(mainloop, ONE_FRAME_TIME);
}
}
$(function () {
//get window width and height;
windowx = window.innerWidth;
windowy = window.innerHeight;
reset();
$(document).on('change', '#sound-enabled-toggle', function() {
var isChecked = $(this).is(':checked');
$('#sound-enabled-toggle').blur();
if (isChecked) {
backgroundMusicAudio.play();
playerJumpAudio = playerJumpMusicAudioSetup();
playerBlinkAudio = playerBlinkMusicAudioSetup();
} else {
backgroundMusicAudio.pause();
playerJumpAudio = new Audio('');
playerBlinkAudio = new Audio('');
}
});
});
//left the function here in case I need to do anything else but for now it's just clearing.
function buildQuadTree() {
quadTree.clear();
}
function updateGame() {
//determine if there are any keys pushed at the current point
keyPressActions();
//loop for calculating and updating all objects positions/values.
for (var i = 0; i < drawObjects.length; i++) {
var object = drawObjects[i];
quadTree.insert(new SimpleRectangle(object.x, object.y, object.width || (object.radius * 2), object.height || (object.radius * 2), object.name));
object.update();
//roundFloatingPoints Numbers to 2 decimal places
roundObjectVelocitiesAndPoints(object);
}
PlayerDeathTrigger(player);
}
function drawGame() {
//clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = "20px Verdana";
ctx.fillText("100,000", (canvas.width * .8), (canvas.clientHeight * .1));
ctx.font = "15px Verdana";
ctx.fillText("Temp Score", (canvas.width * .8), (canvas.clientHeight * .05));
//draw all objects in drawObjects
for (var i = 0; i < drawObjects.length; i++) {
var object = drawObjects[i];
object.draw();
}
}
总的来说,我建议重构这段代码,这样您的重置函数就不会重新创建那么多对象。基本上重置功能只是重新创建大量的游戏逻辑。
您发现的具体问题似乎是由于您在每次重置时调用 setInterval 而没有清除之前的间隔。请参阅下面的代码,并进行最少的更改以防止出现此问题。
var windowx,
windowy,
canvas,
player,
quadTree,
ctx,
gameLoop;
var drawObjects;
var keyState;
var mainloop;
var animFrame;
var ONE_FRAME_TIME;
var reset = function() {
// Remove our old game loop
clearInterval(gameLoop);
//get canvas and set height and width
canvas = document.getElementById('canvas');
canvas.setAttribute('width', windowx / 2);
canvas.setAttribute('height', windowy / 2);
ctx = canvas.getContext("2d");
drawObjects = [];
keyState = {};
quadTree = new Quadtree(quadTreeBounds);
//make the friendly square
player = new Rectangle(20, 20, 40, 40, 0, 0, XPhysicsBehaviorNormal, YPhysicsBehaviorNormal, XBoundaryBehaviorInCanvas, YBoundaryBehaviorInCanvas, playerObjectType, '#580000', null);
drawObjects.push(player);
drawObjects.push(new Rectangle(40, 100, canvas.width + (distanceOutsideCanvasBeforeDie / 2), canvas.clientHeight - 100, defaultEnemyRectangleVelocity, 0, null, YPhysicsBehaviorNormal, null, YBoundaryBehaviorInCanvas, enemyObjectType, null, OutOfCanvasDieBehavior));
backgroundMusicAudio.play();
//define main loop
mainloop = function() {
buildQuadTree();
updateGame();
drawGame();
};
//define the windowanimationframeobject
animFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
null;
if (animFrame !== null) {
var recursiveAnim = function() {
mainloop();
animFrame(recursiveAnim, canvas);
};
// start the mainloop
animFrame(recursiveAnim, canvas);
} else {
// fallback to setInterval if the browser doesn't support requestAnimationFrame
ONE_FRAME_TIME = 1000.0 / 60.0;
gameLoop = setInterval(mainloop, ONE_FRAME_TIME);
}
}
$(function() {
//get window width and height;
windowx = window.innerWidth;
windowy = window.innerHeight;
reset();
$(document).on('change', '#sound-enabled-toggle', function() {
var isChecked = $(this).is(':checked');
$('#sound-enabled-toggle').blur();
if (isChecked) {
backgroundMusicAudio.play();
playerJumpAudio = playerJumpMusicAudioSetup();
playerBlinkAudio = playerBlinkMusicAudioSetup();
} else {
backgroundMusicAudio.pause();
playerJumpAudio = new Audio('');
playerBlinkAudio = new Audio('');
}
});
});
//left the function here in case I need to do anything else but for now it's just clearing.
function buildQuadTree() {
quadTree.clear();
}
function updateGame() {
//determine if there are any keys pushed at the current point
keyPressActions();
//loop for calculating and updating all objects positions/values.
for (var i = 0; i < drawObjects.length; i++) {
var object = drawObjects[i];
quadTree.insert(new SimpleRectangle(object.x, object.y, object.width || (object.radius * 2), object.height || (object.radius * 2), object.name));
object.update();
//roundFloatingPoints Numbers to 2 decimal places
roundObjectVelocitiesAndPoints(object);
}
PlayerDeathTrigger(player);
}
function drawGame() {
//clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = "20px Verdana";
ctx.fillText("100,000", (canvas.width * .8), (canvas.clientHeight * .1));
ctx.font = "15px Verdana";
ctx.fillText("Temp Score", (canvas.width * .8), (canvas.clientHeight * .05));
//draw all objects in drawObjects
for (var i = 0; i < drawObjects.length; i++) {
var object = drawObjects[i];
object.draw();
}
}
我正在尝试使用 HTML5 的 canvas 和 javascript 制作游戏。我相信我一直在做所有事情 "okay" 直到我需要在死亡时重置游戏。我不太确定是什么导致了意外行为,但我有想法。
差不多,游戏以 'x' 速度运行,然后当它重置时一切都移动得更快。我没有改变任何速度的任何变量,在调试和检查我的代码时,新创建的对象的速度与游戏第一次启动时的速度相同,但它们移动得更快。如果您再次死亡,它会再次重置并运行得更快。死亡、冲洗、重复,它一直在加速,直到页面可能达到 "not responding" 状态。
我不确定我做错了什么导致速度差异或至少是速度差异的错觉。我有一个想法,它与我的游戏循环有关 运行 每次重置时都会多次进入永远,但我不明白 how/why 它会那样做。感谢任何反馈。
此外,如果您需要的代码比我在下面发布的更多,您可以访问我的测试页面查看所有代码:game test playground
var windowx,
windowy,
canvas,
player,
quadTree,
ctx;
var drawObjects;
var keyState;
var mainloop;
var animFrame;
var ONE_FRAME_TIME;
var reset = function () {
//get canvas and set height and width
canvas = document.getElementById('canvas');
canvas.setAttribute('width', windowx / 2);
canvas.setAttribute('height', windowy / 2);
ctx = canvas.getContext("2d");
drawObjects = [];
keyState = {};
quadTree = new Quadtree(quadTreeBounds);
//make the friendly square
player = new Rectangle(20, 20, 40, 40, 0, 0, XPhysicsBehaviorNormal, YPhysicsBehaviorNormal, XBoundaryBehaviorInCanvas, YBoundaryBehaviorInCanvas, playerObjectType, '#580000', null);
drawObjects.push(player);
drawObjects.push(new Rectangle(40, 100, canvas.width + (distanceOutsideCanvasBeforeDie / 2), canvas.clientHeight - 100, defaultEnemyRectangleVelocity, 0, null, YPhysicsBehaviorNormal, null, YBoundaryBehaviorInCanvas, enemyObjectType, null, OutOfCanvasDieBehavior));
backgroundMusicAudio.play();
//define main loop
mainloop = function () {
buildQuadTree();
updateGame();
drawGame();
};
//define the windowanimationframeobject
animFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
null;
if (animFrame !== null) {
var recursiveAnim = function () {
mainloop();
animFrame(recursiveAnim, canvas);
};
// start the mainloop
animFrame(recursiveAnim, canvas);
} else {
// fallback to setInterval if the browser doesn't support requestAnimationFrame
ONE_FRAME_TIME = 1000.0 / 60.0;
setInterval(mainloop, ONE_FRAME_TIME);
}
}
$(function () {
//get window width and height;
windowx = window.innerWidth;
windowy = window.innerHeight;
reset();
$(document).on('change', '#sound-enabled-toggle', function() {
var isChecked = $(this).is(':checked');
$('#sound-enabled-toggle').blur();
if (isChecked) {
backgroundMusicAudio.play();
playerJumpAudio = playerJumpMusicAudioSetup();
playerBlinkAudio = playerBlinkMusicAudioSetup();
} else {
backgroundMusicAudio.pause();
playerJumpAudio = new Audio('');
playerBlinkAudio = new Audio('');
}
});
});
//left the function here in case I need to do anything else but for now it's just clearing.
function buildQuadTree() {
quadTree.clear();
}
function updateGame() {
//determine if there are any keys pushed at the current point
keyPressActions();
//loop for calculating and updating all objects positions/values.
for (var i = 0; i < drawObjects.length; i++) {
var object = drawObjects[i];
quadTree.insert(new SimpleRectangle(object.x, object.y, object.width || (object.radius * 2), object.height || (object.radius * 2), object.name));
object.update();
//roundFloatingPoints Numbers to 2 decimal places
roundObjectVelocitiesAndPoints(object);
}
PlayerDeathTrigger(player);
}
function drawGame() {
//clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = "20px Verdana";
ctx.fillText("100,000", (canvas.width * .8), (canvas.clientHeight * .1));
ctx.font = "15px Verdana";
ctx.fillText("Temp Score", (canvas.width * .8), (canvas.clientHeight * .05));
//draw all objects in drawObjects
for (var i = 0; i < drawObjects.length; i++) {
var object = drawObjects[i];
object.draw();
}
}
总的来说,我建议重构这段代码,这样您的重置函数就不会重新创建那么多对象。基本上重置功能只是重新创建大量的游戏逻辑。
您发现的具体问题似乎是由于您在每次重置时调用 setInterval 而没有清除之前的间隔。请参阅下面的代码,并进行最少的更改以防止出现此问题。
var windowx,
windowy,
canvas,
player,
quadTree,
ctx,
gameLoop;
var drawObjects;
var keyState;
var mainloop;
var animFrame;
var ONE_FRAME_TIME;
var reset = function() {
// Remove our old game loop
clearInterval(gameLoop);
//get canvas and set height and width
canvas = document.getElementById('canvas');
canvas.setAttribute('width', windowx / 2);
canvas.setAttribute('height', windowy / 2);
ctx = canvas.getContext("2d");
drawObjects = [];
keyState = {};
quadTree = new Quadtree(quadTreeBounds);
//make the friendly square
player = new Rectangle(20, 20, 40, 40, 0, 0, XPhysicsBehaviorNormal, YPhysicsBehaviorNormal, XBoundaryBehaviorInCanvas, YBoundaryBehaviorInCanvas, playerObjectType, '#580000', null);
drawObjects.push(player);
drawObjects.push(new Rectangle(40, 100, canvas.width + (distanceOutsideCanvasBeforeDie / 2), canvas.clientHeight - 100, defaultEnemyRectangleVelocity, 0, null, YPhysicsBehaviorNormal, null, YBoundaryBehaviorInCanvas, enemyObjectType, null, OutOfCanvasDieBehavior));
backgroundMusicAudio.play();
//define main loop
mainloop = function() {
buildQuadTree();
updateGame();
drawGame();
};
//define the windowanimationframeobject
animFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
null;
if (animFrame !== null) {
var recursiveAnim = function() {
mainloop();
animFrame(recursiveAnim, canvas);
};
// start the mainloop
animFrame(recursiveAnim, canvas);
} else {
// fallback to setInterval if the browser doesn't support requestAnimationFrame
ONE_FRAME_TIME = 1000.0 / 60.0;
gameLoop = setInterval(mainloop, ONE_FRAME_TIME);
}
}
$(function() {
//get window width and height;
windowx = window.innerWidth;
windowy = window.innerHeight;
reset();
$(document).on('change', '#sound-enabled-toggle', function() {
var isChecked = $(this).is(':checked');
$('#sound-enabled-toggle').blur();
if (isChecked) {
backgroundMusicAudio.play();
playerJumpAudio = playerJumpMusicAudioSetup();
playerBlinkAudio = playerBlinkMusicAudioSetup();
} else {
backgroundMusicAudio.pause();
playerJumpAudio = new Audio('');
playerBlinkAudio = new Audio('');
}
});
});
//left the function here in case I need to do anything else but for now it's just clearing.
function buildQuadTree() {
quadTree.clear();
}
function updateGame() {
//determine if there are any keys pushed at the current point
keyPressActions();
//loop for calculating and updating all objects positions/values.
for (var i = 0; i < drawObjects.length; i++) {
var object = drawObjects[i];
quadTree.insert(new SimpleRectangle(object.x, object.y, object.width || (object.radius * 2), object.height || (object.radius * 2), object.name));
object.update();
//roundFloatingPoints Numbers to 2 decimal places
roundObjectVelocitiesAndPoints(object);
}
PlayerDeathTrigger(player);
}
function drawGame() {
//clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = "20px Verdana";
ctx.fillText("100,000", (canvas.width * .8), (canvas.clientHeight * .1));
ctx.font = "15px Verdana";
ctx.fillText("Temp Score", (canvas.width * .8), (canvas.clientHeight * .05));
//draw all objects in drawObjects
for (var i = 0; i < drawObjects.length; i++) {
var object = drawObjects[i];
object.draw();
}
}