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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:54:01