JS+HTML实现乒乓球游戏报Uncaught ReferenceError:draw未定义求助
核心报错原因(Uncaught Reference Error: draw is not defined)
draw函数被你定义在了loop函数内部,属于loop的局部作用域函数,全局作用域无法直接访问,因此你在全局代码第20行调用draw()时会触发未定义报错。
其余需修正的代码问题
getContext参数错误:应传入"2d"而非"2"- 键盘事件监听错误:
- 事件名应为
keydown和keyup,你两处都错写为kedown - 第二个监听应该绑定
keyup事件,松开按键时将对应键值设为false
- 事件名应为
- 拼写错误:
requestAnimationFrame(drwa)中drwa应为draw - 右侧球拍定位错误:
ctx.fillRect(ca- 20, p2, 10,80)中ca应为ca.width - 出界判定逻辑错误:
if(ball.x < 0 || ball.x > (ca.height - 10))中x轴边界判定应该使用ca.width而非ca.height - 操作逻辑错误:原代码中W/S和上下方向键都控制p2,导致p1无法操作,修正为W/S控制左侧p1、上下方向键控制右侧p2
- 循环逻辑冲突:你同时开启了
setInterval跑loop、又在draw里用requestAnimationFrame调度,调整为在loop末尾调用draw,无需全局单独调用draw
修正后的完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Pong</title> </head> <body> <canvas id="ca" width="720" height="480"></canvas> </body> <script> let ca = document.getElementById('ca'); let ctx = ca.getContext("2d"); let p1 = p2 = 80; let key = {}; let ball = {}; start(); setInterval(loop, 1000/60) document.addEventListener("keydown", e => key[e.keyCode] = true); document.addEventListener("keyup", e => key[e.keyCode] = false); function start(){ ball = { x: ca.width / 2, y: ca.height / 2, speedX: 3, speedY: 0 }; } function loop(){ if(key[38]){ p2 -= 5; } if(key[40]){ p2 += 5; } if(key[87]){ p1 -= 5; } if(key[83]){ p1 += 5; } ball.x += ball.speedX; ball.y += ball.speedY; if(ball.x < 20 || ball.x > (ca.width - 30)) { if(ball.y > p1 && ball.y < p1 + 80 && ball.speedX < 0) { ball.speedX = -ball.speedX; ball.speedY = (ball.y - p1 -40) * 0.1; } if(ball.y > p2 && ball.y < p2 + 80 && ball.speedX > 0) { ball.speedX = -ball.speedX; ball.speedY = (ball.y - p2 -40) * 0.1; } } if(ball.y < 0 || ball.y > (ca.height - 10)) { ball.speedY = -ball.speedY } if(ball.x < 0 || ball.x > (ca.width - 10)) { setTimeout(start, 2000); } draw(); } function draw() { ctx.fillStyle="black"; ctx.fillRect(0,0,ca.width, ca.height); ctx.fillStyle="white"; ctx.fillRect(10, p1, 10,80); ctx.fillRect(ca.width - 20, p2, 10,80); ctx.fillRect(ball.x, ball.y, 10, 10); } </script> </html>
内容的提问来源于stack exchange,提问作者Flaver
相关产品推荐
相关产品推荐

