我是一名新程序员,正在制作我的第一个非教学类游戏,而敌人在游戏中遇到了问题。这是脚本:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Square</title>
<style>
* { padding: 0; margin: 0; }
canvas { background: #000; display: block; margin: 0 auto; }
</style>
</head>
<body bgcolor="#000111">
<canvas id="myCanvas" width="480" height="320"></canvas>
<div id="nocursor"><!-- some stuff --></div>
<form name="Show">
<input type="text" name="MouseX" value="0" size="4"> X<br>
<input type="text" name="MouseY" value="0" size="4"> Y<br>
</form>
<script language="JavaScript1.2">
document.getElementById('nocursor').style.cursor = 'none';
var canvas=document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var x=canvas.width/2;
var y=canvas.height-30;
var playerHeight = 100;
var playerWidth = 20;
var enemyHeight = 10;
var enemyWidth = 10;
var IE = document.all?true:false
var enemyXPos = 470;
var rand = Math.random();
var left = 0;
var right = 0;
var up = 0;
var down = 0;
var lefta = 0;
var rightd = 0;
var upw = 0;
var downs = 0;
var space = false;
var playerColor="#ffffff";
var score = 0;
function click() {
document.addEventListener("click", startEnemy);
}
//Check for keydown arrows
document.onkeydown = function(event) {
if (!event)
event = window.event;
var code = event.keyCode;
if (event.charCode && code == 0)
code = event.charCode;
switch(code) {
case 37:
left-=20;
break;
case 38:
up+=20;
break;
case 39:
right+=20;
break;
case 40:
down-=20;
break;
case 65:
lefta-=10;
break;
case 87:
upw+=10;
break;
case 68:
rightd+=10;
break;
case 83:
downs-=10;
break;
case 32:
space=true;
break;
}
event.preventDefault();
};
document.onkeydown = function(event) {
if (!event)
event = window.event;
var code = event.keyCode;
if (event.charCode && code == 0)
code = event.charCode;
switch(code) {
case 37:
left+=20;
break;
case 38:
up+=20;
break;
case 39:
right+=20;
break;
case 40:
down+=20;
break;
case 65:
lefta+=10;
break;
case 87:
upw+=10;
break;
case 68:
rightd+=10;
break;
case 83:
downs+=10;
break;
}
event.preventDefault();
};
if (!IE) document.captureEvents(Event.MOUSEMOVE)
document.onmousemove = getMouseXY;
var tempX = 0
var tempY = 0
// Main function to retrieve mouse x-y pos.s
function getMouseXY(e) {
if (IE) {
tempX = event.clientX + document.body.scrollLeft
tempY = event.clientY + document.body.scrollTop
} else {
tempX = e.pageX
tempY = e.pageY
}
if (tempX < 0){tempX = 0}
if (tempY < 0){tempY = 0}
document.Show.MouseX.value = tempX
document.Show.MouseY.value = tempY
return true
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "#0095DD";
ctx.fillText("Score: "+score, 410, 20);
}
function collision() {
if (enemyXPos<=20 && downs-upw >= down-up && downs-upw <= down-up+playerHeight && enemyXPos >= 0) {
playerColor="#FF0000";
setTimeout(gameOver, 100);
}
}
function gameOver() {
console.log("COLLISION");
alert("GAME OVER, YOUR SCORE WAS: " + score + "!");
document.location.reload();
}
function checkSpace() {
if (space=true) {
startEnemy();
space=false;
}
}
function drawPlayer() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.rect(0, down-up, playerWidth, playerHeight);
ctx.fillStyle=playerColor;
ctx.fill();
ctx.closePath();
}
function drawEnemy() {
ctx.beginPath();
ctx.rect(enemyXPos-=1, downs-upw, enemyWidth, enemyHeight);
ctx.fillStyle="#ffffff";
ctx.fill();
ctx.closePath();
if (enemyXPos<0) {
startEnemy();
}
}
function placePlayer() {
drawPlayer();
requestAnimationFrame(placePlayer);
}
function startEnemy() {
console.log("enemy shot");
enemyXPos = 470;
placeEnemy();
score+=1;
}
function placeEnemy() {
drawEnemy();
collision();
drawScore();
requestAnimationFrame(placeEnemy);
}
function draw() {
click();
placePlayer();
}
draw();
</script>
</body>
</html>
在移动敌人的线上,每当敌人重生时,速度就会变快,而我不希望如此。问题出在drawEnemy函数中:
function drawEnemy() {
ctx.beginPath();
ctx.rect(enemyXPos-=1, downs-upw, enemyWidth, enemyHeight);
ctx.fillStyle="#ffffff";
ctx.fill();
ctx.closePath();
if (enemyXPos<0) {
startEnemy();
}
}
最佳答案
函数placeEnemy
形成一个无限循环,每次执行时(通过requestAnimationFrame
)调用自身。startEnemy
每次执行时都会调用placeEnemy
。这意味着每个“重新生成”都会开始一个新的无限循环,而不会取消旧循环。placeEnemy
循环通过每次迭代减去enemyXPos
来修改“敌人”位置(1
)。在同时运行多个循环的情况下,每次触发新的“动画帧”时,都会多次减去1
。
您可以通过不调用placeEnemy
中的startEnemy
来解决此问题:只需重置敌人的位置,然后继续进行相同的动画循环即可!