You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

因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();
    }

}

问题分析

核心问题有两个:

  1. playerX未实时更新:playerX仅在程序初始化时赋值了一次mouseX-20,但后续鼠标移动时,player()函数直接用mouseX-20绘制玩家,而碰撞检测仍使用初始的playerX值,导致检测位置与实际玩家位置完全脱节。比如初始鼠标在某个位置,之后移动鼠标,玩家绘制位置变了,但碰撞检测还是用旧位置,一旦旧位置与敌人重叠就会误触发Game Over。
  2. 碰撞检测逻辑可优化:原碰撞条件逻辑本身是对的,但因为playerX的错误导致误判,同时可以调整条件顺序,先判断Y轴是否可能重叠(敌人在玩家附近),再判断X轴,减少无效判断。

修复方案

  1. 在gameScreen()函数开头添加playerX = mouseX - 20;,保证每次绘制前都更新碰撞检测用的玩家X坐标,与实际显示位置一致。
  2. (可选)优化碰撞检测条件,先判断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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:35:26