求助:修复游戏启动立即触发游戏结束逻辑的问题
兄弟,我看了你的游戏代码,一眼就找出为啥一启动就跳Game Over了!问题出在几个关键变量的初始化和逻辑判断的不合理上,咱们一步步来把它修好:
问题1:blockSpeed初始值导致直接触发结束逻辑
你定义blockSpeed的初始值是0,但在updateComponent函数里,只有当blockSpeed == 1的时候才会执行游戏的正常逻辑,否则直接调用clearInterval并弹出Game Over。但游戏刚启动时还没点击任何方向按钮,blockSpeed保持0,所以第一次执行更新循环就直接结束游戏了。
修复方案:把blockSpeed的初始值设为1,让游戏启动后默认进入运行状态,不需要等按钮点击。
问题2:gameArea.createBlockInterval未初始化
你在updateComponent里写了gameArea.createBlockInterval += 50来累计创建新方块的时间,但这个属性在gameArea对象里根本没初始化,第一次执行时会变成NaN,永远满足不了>=3000的条件,新方块也创建不出来。
修复方案:在gameArea对象里添加createBlockInterval: 0的初始化。
问题3:碰撞触发逻辑颠倒
原来的代码里,只有在没有碰撞且blockSpeed ==1的时候才运行游戏,否则结束。但正确的逻辑应该是:发生碰撞时才触发Game Over,而不是因为blockSpeed为0就结束。这样游戏后续还能扩展暂停功能,而不是直接终止。
修复方案:调整updateComponent里的逻辑顺序,先判断碰撞,碰撞就直接结束游戏;没碰撞的情况下再执行正常的游戏更新逻辑。
修改后的关键代码片段
1. 变量初始化部分
let xSpeed = 0, ySpeed = 0, blockSpeed = 1; // 初始设为1,游戏启动即运行
2. Game Area对象初始化
const gameArea = { canvas: document.createElement("canvas"), createBlockInterval: 0, // 新增初始化,用于累计创建方块的时间 start: function() { this.canvas.width = 400; this.canvas.height = 400; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[3]); } };
3. 调整后的updateComponent函数
function updateComponent() { gameArea.context.clearRect(0, 0, gameArea.canvas.width, gameArea.canvas.height); let overlap = false; // Define boundaries for comp1 const myRight = comp1.x + comp1.width, myLeft = comp1.x, myTop = comp1.y, myBottom = comp1.y + comp1.height; // Check for collisions with blocks for (let blocks of blockArray) { const blockLeft = blocks.x, blockRight = blocks.x + blocks.width, blockTop = blocks.y, blockBottom = blocks.y + blocks.height; // Collision detection if (myRight > blockLeft && myLeft < blockRight && myBottom > blockTop && myTop < blockBottom) { overlap = true; break; // Exit loop on collision } } // 发生碰撞时直接触发Game Over if (overlap) { clearInterval(myInterval); prompt("Game Over"); return; // 终止后续逻辑执行 } // 没有碰撞的情况下执行正常游戏逻辑 if (blockSpeed == 1) { gameArea.createBlockInterval += 50; // Create a new block every 3 seconds if (gameArea.createBlockInterval >= 3000) { let newBlock = new Component(gameArea.canvas.width, Math.random() * (gameArea.canvas.height - block.height), 15, 130, block.color); blockArray.push(newBlock); gameArea.createBlockInterval = 0; // Reset interval } // Update position of comp1 comp1.x += xSpeed; comp1.y += ySpeed; // Draw player component gameArea.context.fillStyle = comp1.color; gameArea.context.fillRect(comp1.x, comp1.y, comp1.width, comp1.height); // Draw all blocks in the array for (let block of blockArray) { block.x -= blockSpeed; // Move blocks left gameArea.context.fillStyle = block.color; gameArea.context.fillRect(block.x, block.y, block.width, block.height); } } // 如果blockSpeed不为1,比如后续加暂停功能,这里只会暂停更新,不会结束游戏 }
现在你把这些修改替换到原代码里,游戏启动后就能正常运行了:红色的玩家条可以用方向按钮控制移动,黄色的方块会从右侧不断生成并向左移动,当玩家条和方块碰撞时才会触发Game Over。
备注:内容来源于stack exchange,提问作者Getnet Assefa

