跟随教程开发JS游戏,失败判定if语句未触发求助
问题:失败判定代码无输出
我是HTML和JS新手,跟着教程学到1小时27分13秒处,教程中的失败判定代码能正常输出控制台日志,但我的代码里该语句既不输出也不报错。我修改了部分代码,不确定是否因此出错,以下是我的完整index.js代码:
const canvas = document.getElementById("canvas"); const ctx = canvas.getContext('2d'); //adjust canvas width/height to take full screen canvas.width= 1680; canvas.height= 945; //img function to easily import images function img(file){ const image = new Image(); image.src = 'sprites/' +file; return image; } //declaring images const platformImg = img('platform.png'); const bg1 = img('bg1.png'); const bg2 = img('bg2.png'); const bg3 = img('bg3.png'); const bg4 = img('bg4.png'); const bg5 = img('bg5.png'); //Declaring variables const gravity = 0.5; //Global Gravity var firstSplash = 1; var lastSplash = 210; var splash = new Image; var timer = setInterval( function(){ if (firstSplash>lastSplash){ clearInterval( timer ); }else{ splash.src = "./sprites/Splash/splash("+( firstSplash++ )+").jpg"; } }, 1000/30 ); //Draw at 30 frames per second class Player { constructor(){ // Player Position/Width/Height this.position = { x: 100, y: 100 } this.velocity = { // Player Gravity x: 0, y: 0 } this.width = 30; this.height = 30; } // Make Player Visible draw(){ ctx.fillStyle = 'red'; ctx.fillRect(this.position.x, this.position.y, this.width, this.height) } update(){ this.draw(); this.position.x += this.velocity.x; this.position.y += this.velocity.y; // Gravity to Player if (this.position.y + this.height + this.velocity.y <= canvas.height) this.velocity.y += gravity; } } class Platform { constructor({x, y, image}) { this.position = { x, y } this.width = 600 this.height = 180 this.image = image } draw() { ctx.drawImage(this.image, this.position.x, this.position.y) } } class Decoration { constructor({x, y, image}) { this.position = { x, y } this.width = 16800 this.height = 945 this.image = image } draw() { ctx.drawImage(this.image, this.position.x, this.position.y) } } //Declaring variables let player = new Player(); let platforms = [new Platform({ x: -1, y: 800, image: platformImg }), new Platform({ x: 600 -1, y: 800, image: platformImg })] let decorations = [ new Decoration({ x:0, y:0, image: bg1 }), bg2Deco = new Decoration({ x:0, y:0, image: bg2 }), bg3Deco = new Decoration({ x:0, y:0, image: bg3 }), bg4Deco = new Decoration({ x:0, y:0, image: bg4 }), bg5Deco = new Decoration({ x:0, y:0, image: bg5 }) ] const keys = { right:{ pressed: false }, left:{ pressed: false } } //Levels let level = 1 let levels = { 1: { init: () => { player = new Player(); platforms = [new Platform({ x: -1, y: 800, image: platformImg }), Platform({ x: 600 -1, y: 800, image: platformImg })] decorations = [ new Decoration({ x:0, y:0, image: bg1 }), bg2Deco = new Decoration({ x:0, y:0, image: bg2 }), bg3Deco = new Decoration({ x:0, y:0, image: bg3 }), bg4Deco = new Decoration({ x:0, y:0, image: bg4 }), bg5Deco = new Decoration({ x:0, y:0, image: bg5 }) ] } } } // function drawSplash(){ // splash.onload = function(){ // ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height ); // ctx.drawImage(splash, 0, 0, ctx.canvas.width, ctx.canvas.height); // }; // } function gameStart(){ ctx.fillStyle = 'black' ctx.fillRect(0,0,canvas.width, canvas.height) document.getElementById("btnStart").remove(); player.draw(); animate(); } function animate(){ // Animate requestAnimationFrame(animate); ctx.fillStyle = 'white'; ctx.fillRect(0,0,canvas.width, canvas.height) decorations.forEach(Decoration =>{ Decoration.draw(); }); platforms.forEach(platform =>{ platform.draw(); }); player.update(); // Hold left/right for moving player if (keys.right.pressed && player.position.x < 400){ player.velocity.x = 5 } else if (keys.left.pressed && player.position.x > 100) { player.velocity.x = -5 } else { player.velocity.x = 0 if (keys.right.pressed){ platforms.forEach(platform =>{ platform.position.x -=5 }); bg2Deco.position.x -= 3; bg3Deco.position.x -= 4; bg4Deco.position.x -= 5; bg5Deco.position.x -= 6; } else if (keys.left.pressed){ platforms.forEach(platform =>{ platform.position.x +=5 }); bg2Deco.position.x += 3; bg3Deco.position.x += 4; bg4Deco.position.x += 5; bg5Deco.position.x += 6; } } // Platform detection for player platforms.forEach(platform =>{ if (player.position.y + player.height <= platform.position.y && player.position.y + player.height + player.velocity.y >= platform.position.y && player.position.x + player.width >= platform.position.x && player.position.x <= platform.position.x + platform.width) { player.velocity.y = 0; } }); } //lose condition if (player.position.y > canvas.width){ console.log("you lose"); }; document.body.addEventListener('keydown', keyDown); document.body.addEventListener('keyup', keyUp); function keyDown(event){ if(event.code == "ArrowUp"){ if(event.repeat){return} else player.velocity.y -= 10; } if(event.code == "ArrowLeft"){ keys.left.pressed = true; } if(event.code == "ArrowRight"){ keys.right.pressed = true; } } function keyUp(event){ if(event.code == "ArrowUp"){ player.velocity.y -= 10; } if(event.code == "ArrowLeft"){ keys.left.pressed = false; } if(event.code == "ArrowRight"){ keys.right.pressed = false; } } player.draw(); animate(); //drawSplash();
问题原因及修复方案
失败判定仅执行一次
你的失败判定代码写在全局作用域中,页面加载时只会运行一次,之后不会再检测玩家位置。游戏的循环逻辑在animate函数里,必须把判定代码移到这个函数内部,才能每帧检查玩家是否掉出屏幕。判定条件错误
你用了canvas.width(画布宽度)作为判定阈值,但玩家是从底部掉出,应该用canvas.height(画布高度)才对。
修改后的animate函数(关键部分)
function animate(){ // Animate requestAnimationFrame(animate); ctx.fillStyle = 'white'; ctx.fillRect(0,0,canvas.width, canvas.height) decorations.forEach(Decoration =>{ Decoration.draw(); }); platforms.forEach(platform =>{ platform.draw(); }); player.update(); // --- 移到这里的失败判定 --- if (player.position.y > canvas.height){ console.log("you lose"); // 可选:在这里添加游戏重置逻辑,比如 levels[level].init() } // 剩余的移动、碰撞检测代码... }
额外修复点
levels[1].init()里创建第二个Platform时缺少new关键字,会导致报错,修改为:
new Platform({ x: 600 -1, y: 800, image: platformImg })
内容的提问来源于stack exchange,提问作者mcYuzu
相关产品推荐
相关产品推荐

