P5.js类开发问题:跟随圆形经过障碍物未触发减速如何解决?
问题定位
- 调用
drawObstacle方法时未传入跟随者的实时坐标与速度属性,导致碰撞判定的输入值为undefined,永远不会触发减速逻辑 - JS中数字类型为值传递,直接修改
drawObstacle的入参enemyS不会修改外部enemy实例的真实速度属性,修改操作完全无效 obstacle类构造函数中接收的enemyX/enemyY/enemyS未挂载到实例属性this上,初始化传入的初始坐标后续也不会跟随跟随者移动更新,没有实际作用- 现有逻辑只针对单个跟随者做判定,无法覆盖两个跟随者的减速需求
修复方案
我们调整逻辑链路:将「障碍物碰撞判定」和「跟随者速度修改」解耦,由跟随者实例主动查询是否碰撞障碍物,再修改自身速度,规避值传递问题。
1. 改造obstacle类,新增碰撞判定方法
移除无用的入参存储逻辑,新增checkCollision方法接收坐标,返回是否碰撞:
class obstacle { constructor(x, y, w, h) { this.x = x; this.y = y; this.w = w; this.h = h; } // 新增碰撞判定方法 checkCollision(targetX, targetY) { return ( this.x - this.w / 2 - 10 < targetX && this.x + this.w / 2 + 10 > targetX && this.y - this.h / 2 - 10 < targetY && this.y + this.h / 2 + 10 > targetY ) } drawObstacle() { fill(255); rectMode(CENTER); rect(this.x, this.y, this.w, this.h); } }
2. 调整setup中obstacle的初始化逻辑,删除无用的跟随者初始参数
// setup中修改obstacle初始化代码 obstacle1 = new obstacle(200, 200, 100, 50); obstacle2 = new obstacle(300, 300, 50, 25); obstacle3 = new obstacle(200, 400, 25, 50);
3. 改造enemy类,在移动前先判定是否碰撞障碍物,修改自身速度
class enemy { constructor(x, y, d, s) { this.x = x; this.y = y; this.d = d; // 存储基础速度,避免每次重置都写死数值 this.baseS = s; this.s = s; } drawEnemy() { fill(255, 0, 0); ellipse(this.x, this.y, this.d); // 新增:遍历所有障碍物,判断是否碰撞 let isOnObstacle = false; [obstacle1, obstacle2, obstacle3].forEach(obs => { if (obs.checkCollision(this.x, this.y)) { isOnObstacle = true; } }) // 根据碰撞结果设置速度 this.s = isOnObstacle ? 0.5 : this.baseS; // 原有移动逻辑不变 if (this.x < character1.x - this.d) { this.x += this.s; } if (this.x > character1.x + this.d) { this.x -= this.s; } if (this.y < character1.y - this.d) { this.y += this.s; } if (this.y > character1.y + this.d) { this.y -= this.s; } } }
4. 可选优化:修改character类的drawCharacter方法,用this代替全局实例名,符合类的封装规范
class character { constructor(x, y, d, s) { this.x = x; this.y = y; this.d = d; this.s = s; } drawCharacter() { fill(255); // 把所有character1替换为this ellipse(this.x, this.y, this.d); if (keyIsDown(UP_ARROW)) { this.y -= this.s; } if (keyIsDown(DOWN_ARROW)) { this.y += this.s; } if (keyIsDown(LEFT_ARROW)) { this.x -= this.s; } if (keyIsDown(RIGHT_ARROW)) { this.x += this.s; } } }
修改后两个跟随者移动到障碍物上时都会正常触发减速效果,逻辑也更符合面向对象的封装原则。
内容的提问来源于stack exchange,提问作者Matt Shade
相关产品推荐
相关产品推荐

