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

p5.js如何制作collider碰撞器,与角色碰撞时触发游戏结束

问题核心原因

你遇到的碰撞器错位问题本质是两个原因:

  1. 你用createImg()创建的GIF是独立的DOM元素,默认坐标是相对于浏览器窗口的,和p5 canvas内部的坐标基准不统一
  2. 之前给障碍物设置的Y轴坐标不对,没有对齐到地面高度,同时你尝试使用的setCollider是p5.play库针对canvas内精灵的方法,直接操作DOM元素当然不生效

具体解决步骤

1. 统一坐标基准(二选一即可)

  • 方案A(推荐):放弃createImg,改用canvas渲染GIF,所有元素坐标都以canvas左上角为基准,完全不会错位。你可以找适配p5的轻量GIF渲染库来实现canvas内播放GIF,或者嫌麻烦也可以先把角色换成静态png调试完碰撞逻辑再替换成GIF
  • 方案B(快速适配现有代码):在setup()末尾添加canvas.position(0, 0),把canvas固定到页面左上角,这样createImg的坐标就和canvas内坐标完全对齐了

2. 手动实现矩形碰撞检测(新手更可控,不需要额外库)

你不需要依赖p5.play的collider方法,自己写碰撞逻辑更灵活,只需要给每个角色保存x、y、宽、高四个属性,判断两个矩形是否重叠即可:

// 先给猫巴士补充宽高属性,写在setup里的catBus定义处
catBus = {
  x: startX,
  y: startY,
  w: 270, // 和你设置的catGif尺寸一致
  h: 100
};

// 补充障碍物的属性,注意Y坐标要对齐到地面
let tinyToto = {
  x: 900,
  y: 730, // 和猫巴士的初始Y轴位置一致,就是地面高度
  w: 75, // 可以根据实际障碍物素材的碰撞范围调整,不用和GIF尺寸完全一致
  h: 75,
  speed: scrollSpeed
};

碰撞检测逻辑写在draw()里,只有游戏运行(mode==1)时才执行:

if(mode == 1){
  // 更新障碍物位置,实现滚动效果
  tinyToto.x -= tinyToto.speed;
  // 障碍物移出屏幕左侧后重置到右侧,实现循环
  if(tinyToto.x < -tinyToto.w){
    tinyToto.x = width;
    // 后续可以在这里加随机逻辑,生成不同类型的障碍物
  }

  // 核心碰撞判断逻辑
  const isCollided = 
    catBus.x < tinyToto.x + tinyToto.w && 
    catBus.x + catBus.w > tinyToto.x && 
    catBus.y < tinyToto.y + tinyToto.h && 
    catBus.y + catBus.h > tinyToto.y;
  
  // 碰撞后切换到游戏结束状态
  if(isCollided){
    mode = 2;
  }
}

// 游戏结束显示逻辑
if(mode == 2){
  fill("red");
  textSize(60);
  textFont(font2);
  text("GAME OVER", width/2 - 160, height/2);
  // 可以在这里加重启逻辑,比如按空格重置所有参数
}

3. 调试小技巧

你调试碰撞器位置的时候,可以在draw()里加一段代码,把碰撞框直观画出来,确认位置没问题后再删掉:

// 调试用:画出碰撞框
noFill();
stroke("red");
strokeWeight(2);
rect(catBus.x, catBus.y, catBus.w, catBus.h);
rect(tinyToto.x, tinyToto.y, tinyToto.w, tinyToto.h);

现有代码优化提示

你现在写了两套背景滚动逻辑,一套用frameCount一套用x1/x2变量,保留一套就行,避免性能浪费。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:15:02