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

p5.js实现寻路行为时出现"v1.copy"无法调用为函数错误求助

转向行为寻路代码错误排查与修复

我跟着Daniel Shiffman的转向行为(寻路)教程写代码,创建了Vehicle和Target两个类并加入主sketch,但出现错误:"v1.copy" could not be called as a function,错误还指向不存在的行。VS Code和Chrome里测试都是这个错,但Chrome指向的行不一样。预期功能是让Vehicle对象追踪Target对象。

原代码

主sketch代码

let vehicle;
let target;

function setup() {
  createCanvas(400, 400);
  vehicle = new Vehicle(50, 50);
  target = new Target(mouseX, mouseY);
}

function draw() {
  background(220);

  let steering = vehicle.seek(target);
  vehicle.applyForce(steering);

  vehicle.show();
  vehicle.update();
  
  target.show();
  target.update();
}

Vehicle类代码

class Vehicle {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(0, 0);
    this.acc = createVector(0, 0);
    this.maxSpeed = 4;
    this.maxForce = 1;
    this.r = 16;
  }

  seek(target) {
    let force = p5.Vector.sub(target, this.pos);
    force.setMag(this.maxSpeed);
    force.sub(this.vel);
    force.limit(this.maxForce);
    return force;
  }

  applyForce(force) {
    this.acc.add(force);
  }

  update() {
    this.vel.add(this.acc);
    this.vel.limit(this.maxSpeed);
    this.pos.add(this.vel);
    this.acc.set(0, 0);
  }
  show() {
    noStroke();
    fill(0);
    push();
    translate(this.pos.x, this.pos.y);
    rotate(this.vel.heading());
    triangle(-this.r, -this.r / 2, -this.r, this.r / 2, this.r, 0);
    pop();
  }
}

class Target extends Vehicle {
  constructor(x, y) {
    super(x, y);
  }
  show() {
    noStroke();
    fill(200, 0, 0);
    ellipse(this.pos.x, this.pox.y, this.r);
  }
}

错误原因与修复方案

1. 核心错误:seek方法参数类型不匹配

p5.Vector.sub()需要传入两个p5.Vector对象,但调用vehicle.seek(target)时传的是Target类实例,不是它的位置向量。这会导致p5内部尝试对非向量对象调用copy方法,触发"v1.copy" could not be called as a function错误。
修复:将let steering = vehicle.seek(target);改为let steering = vehicle.seek(target.pos);

2. 笔误拼写错误

Target类的show方法里,this.pox.y是拼写错误,应该是this.pos.y,否则会导致无法正确绘制目标点。

3. Target的update逻辑冗余

Target继承了Vehicle的update方法,但Target不需要速度、加速度的物理更新,应该重写update方法让它直接跟随鼠标位置。

修正后的完整代码

主sketch代码

let vehicle;
let target;

function setup() {
  createCanvas(400, 400);
  vehicle = new Vehicle(50, 50);
  target = new Target(mouseX, mouseY);
}

function draw() {
  background(220);

  // 传入Target的位置向量而非对象本身
  let steering = vehicle.seek(target.pos);
  vehicle.applyForce(steering);

  vehicle.update();
  vehicle.show();
  
  target.update();
  target.show();
}

Vehicle类代码

class Vehicle {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(0, 0);
    this.acc = createVector(0, 0);
    this.maxSpeed = 4;
    this.maxForce = 1;
    this.r = 16;
  }

  seek(target) {
    let force = p5.Vector.sub(target, this.pos);
    force.setMag(this.maxSpeed);
    force.sub(this.vel);
    force.limit(this.maxForce);
    return force;
  }

  applyForce(force) {
    this.acc.add(force);
  }

  update() {
    this.vel.add(this.acc);
    this.vel.limit(this.maxSpeed);
    this.pos.add(this.vel);
    this.acc.set(0, 0);
  }

  show() {
    noStroke();
    fill(0);
    push();
    translate(this.pos.x, this.pos.y);
    rotate(this.vel.heading());
    triangle(-this.r, -this.r / 2, -this.r, this.r / 2, this.r, 0);
    pop();
  }
}

class Target extends Vehicle {
  constructor(x, y) {
    super(x, y);
  }

  // 重写update方法,让目标跟随鼠标
  update() {
    this.pos.set(mouseX, mouseY);
  }

  show() {
    noStroke();
    fill(200, 0, 0);
    // 修正拼写错误
    ellipse(this.pos.x, this.pos.y, this.r);
  }
}

内容的提问来源于stack exchange,提问作者Arsalan Aboomohsenpour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:45:27