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
相关产品推荐
相关产品推荐

