帆布迷宫游戏流畅的动画
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了帆布迷宫游戏流畅的动画相关的知识,希望对你有一定的参考价值。
我正在构建一个基于this教程的迷宫游戏。只要按住箭头键,我就成功地让玩家矩形继续移动。当你第一次开始游戏时,动画真的很好而且很快,但似乎在玩游戏几秒后动画变得越来越慢。任何人都可以帮我弄清楚为什么会这样吗?
我已经创建了一个代码片段,但不幸的是,由于我正在使用的迷宫图像导致的跨源错误,它无法正常工作。
var canvas;
var ctx;
var dx = 2;
var dy = 2;
var WIDTH = 482;
var HEIGHT = 482;
//movement
var x = 200,
y = 5,
staticX = 200,//this should be the same as x (used for resetting the game)
staticY = 5,//this should be the same as y (used for resetting the game)
keys = [];
var img = new Image();
var collision = 0;
var showingWinScreen = false;
var playerSize = 15;
var startTime = null,
lastTime = null,
endTime, // for scale
isRunning = false,
FPS = 1000/60; // ideal frame rate
function rect(x,y,w,h) {
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
ctx.fill();
}
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
function drawMaze() {
ctx.drawImage(img, 0, 0);
}
function drawPlayer() {
doKeyDown();
ctx.fillStyle = "purple";
rect(x, y, 15,15);
}
function draw() {
clear();
if(showingWinScreen) {
isRunning = false;
drawRect(0,0,canvas.width, canvas.height,"black");
ctx.fillStyle = "white";
ctx.font = "20px Arial";
ctx.fillText("You Won! Click to play again", 70,canvas.height/2);
ctx.fillText("Time Elapsed: " + endTime, 70, canvas.height*0.6);
return;
}
isRunning = true;
drawMaze();
drawPlayer();
requestAnimationFrame(loop);
}
function drawRect(leftX, topY, width, height, drawColor) {
ctx.fillStyle = drawColor;
ctx.fillRect(leftX,topY,width, height);
}
//timer
function loop(timeStamp) {
if (!startTime) {
startTime = timeStamp;
}
var timeDiff = lastTime ? timeStamp - lastTime : FPS,
timeElapsed = timeStamp - startTime,
timeScale = timeDiff / FPS; // adjust variations in frame rates
lastTime = timeStamp;
var totalTime = timeElapsed*0.001;
var minutes = Math.floor(totalTime / 60);
var seconds = totalTime % 60;
drawRect(WIDTH,10,70, 30,"black");
ctx.fillStyle = "white";
ctx.font = "14px Arial";
ctx.fillText(minutes + ":" + (seconds).toFixed(2), WIDTH*1.04, 30);
endTime = minutes + ":" + (seconds).toFixed(0);
if (isRunning) requestAnimationFrame(loop);
}
function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
img.src = "https://html5.litten.com/images/maze.gif";
var framesPerSecond = 60;
return setInterval( function() {
draw();
}, 1000/framesPerSecond);
}
function checkcollision() {
var imgd = ctx.getImageData(x, y, playerSize, playerSize);
var pix = imgd.data;
for (var i = 0; n = pix.length, i < n; i += 4) {
if (pix[i] == 0) {
collision = 1;
}
}
}
function checkWin() {
var imageData = ctx.getImageData(x, y, playerSize, playerSize);
var r, g, b, a;
for (var i = 0; i+3 < imageData.data.length; i += 4) {
r = imageData.data[i];
g = imageData.data[i+1];
b = imageData.data[i+2];
a = imageData.data[i+3];
//if red
if ( r === 255 && b === 0 ) {
console.log(' R: ' + r + '<br>G: ' + g + '<br>B: ' + b);
isRunning = false;
showingWinScreen = true;
}
}
}
function handleMouseClick(event) {
if (showingWinScreen) {
showingWinScreen = false;
x = staticX;
y = staticY;
draw();
}
}
//arrow keys
function doKeyDown(){
//left
if (keys[37]) {
if (x - dx > 0){
x -= dx;
checkcollision();
checkWin();
if (collision == 1){
x += dx;
collision = 0;
}
}
}
//right
if (keys[39]) {
if (x + dx < WIDTH){
x += dx;
checkcollision();
checkWin();
if (collision == 1){
x -= dx;
collision = 0;
}
}
}
//down
if (keys[40]) {
if (y + dy < HEIGHT ){
y += dy;
checkcollision();
checkWin();
if (collision == 1){
y -= dy;
collision = 0;
}
}
}
//up
if (keys[38]) {
if (y - dy > 0){
y -= dy;
checkcollision();
checkWin();
if (collision == 1){
y += dy;
collision = 0;
}
}
}
}
init();
window.addEventListener("keydown", function (e) {
keys[e.keyCode] = true;
});
window.addEventListener("keyup", function (e) {
keys[e.keyCode] = false;
});
canvas.addEventListener("mousedown", handleMouseClick);
(function () {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})()
<canvas id="canvas" width="582" height="582">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
答案
最大的问题在这里? 你的计时器。
让我们删除与画布相关的所有内容,然后尝试记录每帧绘制这个小时间计数器的次数:
// If everything was ok, frame_count should never be higher than 1
var frame_count = 0;
var total_count = 0;
function frame_loop() {
frame_log.textContent = frame_count;
total_log.textContent = total_count;
// reset our frame counter
frame_count = 0;
// do it again next loop
requestAnimationFrame(frame_loop);
}
frame_loop();
var startTime = null,
lastTime = null,
endTime, // for scale
isRunning = false,
FPS = 1000/60; // ideal frame rate
function draw() {
isRunning = true;
requestAnimationFrame(loop);
}
//timer
function loop(timeStamp) {
frame_count ++;
total_count ++;
if (!startTime) {
startTime = timeStamp;
}
var timeDiff = lastTime ? timeStamp - lastTime : FPS,
timeElapsed = timeStamp - startTime,
timeScale = timeDiff / FPS; // adjust variations in frame rates
lastTime = timeStamp;
var totalTime = timeElapsed*0.001;
var minutes = Math.floor(totalTime / 60);
var seconds = totalTime % 60;
endTime = minutes + ":" + (seconds).toFixed(0);
if (isRunning) requestAnimationFrame(loop);
}
function init() {
var framesPerSecond = 60;
return setInterval( function() {
draw();
}, 1000/framesPerSecond);
}
init();
<p>number of times loop() has been called <b>during last frame</b>: <span id="frame_log"></span></p>
<p>number of times loop() has been called <b>in total</b>: <span id="total_log"></span></p>
以上是关于帆布迷宫游戏流畅的动画的主要内容,如果未能解决你的问题,请参考以下文章