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

p5js躲避球游戏如何实现物体碰撞后停止游戏并显示黑背景

问题根源

你的失败逻辑不生效是多个语法错误和逻辑位置错误共同导致的:

  • 碰撞检测写在了setup()函数中:这个函数仅在页面加载时执行1次,游戏运行过程中不会重复检测碰撞,自然无法触发失败
  • 语法错误:碰撞判断的if语句末尾多写了1个分号,导致判断条件和后面的loseScreen()调用完全脱钩,哪怕条件满足也会出现执行异常
  • 没有游戏终止逻辑:就算触发了失败函数,draw()循环仍会每帧重绘灰色背景、玩家和红球,刚绘制的黑色失败屏会立刻被覆盖
  • 逻辑位置错误:红球边界反弹、到达终点通关的判断写在了draw()函数外部,属于全局作用域代码,仅会在脚本加载时执行1次,游戏运行中完全不生效
  • 碰撞阈值错误:玩家圆直径40、红球直径50,两圆碰撞的判定距离应为两个半径之和45,你之前写的20阈值过小,哪怕两个圆视觉上碰到了也不会触发判定
  • 变量冲突:自定义了全局width/height变量,会覆盖p5.js内置的画布宽高属性,容易引发未知异常
  • 按键逻辑冗余:keyPressed()本身是按键按下时自动触发的事件函数,不需要在draw()里每帧手动调用,也不需要额外加keyIsPressed判断
修复后完整代码

你可以直接替换原有代码,已经实现碰撞后游戏停止、显示黑色失败屏的需求,同时修复了通关、红球反弹的原有逻辑问题:

let c;
let cspeed = 4;
let x = 25;
let y = 25;
let level = 0;
let gameOver = false; // 游戏结束状态标记

function setup() {
  createCanvas(800, 800);
  c = 0;
}

function draw() {
  // 游戏结束时只绘制失败屏,不更新游戏逻辑
  if (gameOver) {
    loseScreen();
    return;
  }

  background(220);
  fill(50);
  textSize(30);
  text(level, 770, 30);

  // 绘制起点、终点
  fill('green');
  square(0, 0, 50);
  fill('purple');
  square(750, 750, 50);

  // 绘制玩家
  fill('yellow');
  ellipse(x, y, 40);

  // 更新、绘制红球
  c += cspeed;
  fill('red');
  noStroke();   
  ellipse(c, height / 4, 50, 50);
  ellipse(c, height / 2, 50, 50);
  ellipse(c, height / 9, 50, 50);
  ellipse(height / 4, c, 50, 50);
  ellipse(height / 2, c, 50, 50);
  ellipse(height / 9, c, 50, 50);

  // 红球边界反弹
  if (c > width || c < 0) {
    cspeed *= -1;
  }

  // 每帧检测碰撞
  let isHit = false;
  // 检测3个水平移动红球
  if (dist(x, y, c, height/4) < 45) isHit = true;
  if (dist(x, y, c, height/2) < 45) isHit = true;
  if (dist(x, y, c, height/9) < 45) isHit = true;
  // 检测3个垂直移动红球
  if (dist(x, y, height/4, c) < 45) isHit = true;
  if (dist(x, y, height/2, c) < 45) isHit = true;
  if (dist(x, y, height/9, c) < 45) isHit = true;

  if (isHit) gameOver = true;

  // 通关判定
  if (x > 770 && y > 770) {
    x = 25;
    y = 25;
    cspeed *= 1.5;
    level++;
  }
}

function loseScreen(){
  background(0);
  fill(255);
  textSize(50);
  textAlign(CENTER, CENTER);
  text("游戏结束", width/2, height/2);
}

function keyPressed() {
  // 游戏结束后禁用移动
  if (gameOver) return;
  if (keyCode == LEFT_ARROW) {
    x = max(20, x - 5);
  } else if (keyCode == RIGHT_ARROW) {
    x = min(780, x + 5);
  } else if(keyCode == DOWN_ARROW){
    y = min(780, y + 5);
  }else if(keyCode == UP_ARROW){
    y = max(20, y - 5);
  }
}

内容的提问来源于stack exchange,提问作者rose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:06:33