p5.js如何制作collider碰撞器,与角色碰撞时触发游戏结束
问题核心原因
你遇到的碰撞器错位问题本质是两个原因:
- 你用
createImg()创建的GIF是独立的DOM元素,默认坐标是相对于浏览器窗口的,和p5 canvas内部的坐标基准不统一 - 之前给障碍物设置的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
相关产品推荐
相关产品推荐

