因if语句条件错误导致Processo游戏触发Game Over的问题排查
未碰撞却触发Game Over的Bug修复
问题说明
使用Processo开发类Crossy Road游戏,玩家仅可水平移动,敌方汽车垂直向下移动,移出屏幕后重置到屏幕上方-1000至-100的随机位置。程序初始运行正常,但会出现未与敌方碰撞却直接触发Game Over界面的Bug,推测问题出在gameScreen函数的碰撞检测语句中。
原代码如下:
size (300, 400); double playerX = mouseX-20; double playerY = 320; double playerWidth = 40; double playerHeight = 40; double enemy1X = 10; double enemy1Y = random(-1000, -100); double enemy1Width = 80; double enemy1Height = 80; double enemy2X = 110; double enemy2Y = random(-1000, -100); double enemy2Width = 80; double enemy2Height = 80; double enemy3X = 210; double enemy3Y = random(-1000, -100); double enemy3Width = 80; double enemy3Height = 80; int gamePage = 0; void player() { noStroke(); fill(rgb(0, 255, 0)); rect(mouseX-20, 320, 40, 40); } void enemy1() { fill(rgb(255, 0, 0)); rect(enemy1X, enemy1Y, enemy1Width, enemy1Height); } void enemy2() { rect(enemy2X, enemy2Y, enemy2Width, enemy2Height); } void enemy3() { rect(enemy3X, enemy3Y, enemy3Width, enemy3Height); } void initalScreen() { background(rgb(0, 0, 0)); text("Click to start", width/2, height/2); } void gameScreen() { background(rgb(255, 255, 255)); if(enemy1Y >= 400) { enemy1Y = random(-1000, -100); } else { enemy1Y += 5; } if(enemy2Y >= 400) { enemy2Y = random(-1000, -100); } else { enemy2Y += 5; } if(enemy3Y >= 400) { enemy3Y = random(-1000, -100); } else { enemy3Y += 5; } //collision if (playerX + playerWidth > enemy1X && playerX < enemy1X + enemy1Width && playerY + playerHeight > enemy1Y && playerY < enemy1Y + enemy1Height) { gamePage = 2; } if (playerX + playerWidth > enemy2X && playerX < enemy2X + enemy2Width && playerY + playerHeight > enemy2Y && playerY < enemy2Y + enemy2Height) { gamePage = 2; } if (playerX + playerWidth > enemy3X && playerX < enemy3X + enemy3Width && playerY + playerHeight > enemy3Y && playerY < enemy3Y + enemy3Height) { gamePage = 2; } player(); enemy1(); enemy2(); enemy3(); } void gameOverScreen() { background(rgb(0, 0, 0)); textSize(30); text("Game Over", width/2, height/2); } void startGame() { gamePage = 1; } void mousePressed() { if(gamePage == 0) { startGame(); } } void draw() { background(rgb(226, 225, 225)); if (gamePage == 0) { initalScreen(); } else if (gamePage == 1) { gameScreen(); } else if (gamePage == 2) { gameOverScreen(); } }
问题分析
核心问题有两个:
- playerX未实时更新:
playerX仅在程序初始化时赋值了一次mouseX-20,但后续鼠标移动时,player()函数直接用mouseX-20绘制玩家,而碰撞检测仍使用初始的playerX值,导致检测位置与实际玩家位置完全脱节。比如初始鼠标在某个位置,之后移动鼠标,玩家绘制位置变了,但碰撞检测还是用旧位置,一旦旧位置与敌人重叠就会误触发Game Over。 - 碰撞检测逻辑可优化:原碰撞条件逻辑本身是对的,但因为
playerX的错误导致误判,同时可以调整条件顺序,先判断Y轴是否可能重叠(敌人在玩家附近),再判断X轴,减少无效判断。
修复方案
- 在
gameScreen()函数开头添加playerX = mouseX - 20;,保证每次绘制前都更新碰撞检测用的玩家X坐标,与实际显示位置一致。 - (可选)优化碰撞检测条件,先判断Y轴重叠,再判断X轴,提升逻辑合理性。
修复后完整代码
size (300, 400); double playerX = mouseX-20; double playerY = 320; double playerWidth = 40; double playerHeight = 40; double enemy1X = 10; double enemy1Y = random(-1000, -100); double enemy1Width = 80; double enemy1Height = 80; double enemy2X = 110; double enemy2Y = random(-1000, -100); double enemy2Width = 80; double enemy2Height = 80; double enemy3X = 210; double enemy3Y = random(-1000, -100); double enemy3Width = 80; double enemy3Height = 80; int gamePage = 0; void player() { noStroke(); fill(rgb(0, 255, 0)); rect(mouseX-20, 320, 40, 40); } void enemy1() { fill(rgb(255, 0, 0)); rect(enemy1X, enemy1Y, enemy1Width, enemy1Height); } void enemy2() { rect(enemy2X, enemy2Y, enemy2Width, enemy2Height); } void enemy3() { rect(enemy3X, enemy3Y, enemy3Width, enemy3Height); } void initalScreen() { background(rgb(0, 0, 0)); text("Click to start", width/2, height/2); } void gameScreen() { background(rgb(255, 255, 255)); // 实时更新玩家X坐标,与绘制位置保持一致 playerX = mouseX - 20; if(enemy1Y >= 400) { enemy1Y = random(-1000, -100); } else { enemy1Y += 5; } if(enemy2Y >= 400) { enemy2Y = random(-1000, -100); } else { enemy2Y += 5; } if(enemy3Y >= 400) { enemy3Y = random(-1000, -100); } else { enemy3Y += 5; } //collision - 优化顺序,先判断Y轴是否重叠 if (playerY < enemy1Y + enemy1Height && playerY + playerHeight > enemy1Y && playerX < enemy1X + enemy1Width && playerX + playerWidth > enemy1X) { gamePage = 2; } if (playerY < enemy2Y + enemy2Height && playerY + playerHeight > enemy2Y && playerX < enemy2X + enemy2Width && playerX + playerWidth > enemy2X) { gamePage = 2; } if (playerY < enemy3Y + enemy3Height && playerY + playerHeight > enemy3Y && playerX < enemy3X + enemy3Width && playerX + playerWidth > enemy3X) { gamePage = 2; } player(); enemy1(); enemy2(); enemy3(); } void gameOverScreen() { background(rgb(0, 0, 0)); textSize(30); text("Game Over", width/2, height/2); } void startGame() { gamePage = 1; } void mousePressed() { if(gamePage == 0) { startGame(); } } void draw() { background(rgb(226, 225, 225)); if (gamePage == 0) { initalScreen(); } else if (gamePage == 1) { gameScreen(); } else if (gamePage == 2) { gameOverScreen(); } }
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

