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

p5.js中dist()函数无法计算近距离的问题排查

p5.js dist()函数计算距离异常问题排查与修复

问题描述

使用p5.js的dist()函数计算角色与可收集道具的距离时,出现以下异常:

  • 角色完全覆盖道具时,距离始终不低于130;替换角色坐标为mouseX/mouseY后,距离最低仅为90,无法趋近于0。
  • 调整判断阈值(如120、140)也无法触发collectable.isFound = true,新增道具后问题依旧。

相关代码片段:

distance = dist(
    collectable.x_pos,
    collectable.y_pos,
    gameChar_x,
    gameChar_y
);
  
if (distance < 130) {
    collectable.isFound = true;
}

问题根源

核心问题是道具的绘制坐标与距离计算坐标不匹配:

  • 定义道具时,collectable.y_pos = 310,但绘制道具时使用的是collectable.y_pos + 100(实际绘制y坐标为410)。
  • 计算距离时仍使用原始的collectable.y_pos,导致实际距离计算的是到310的位置,而非道具实际显示的410位置,自然无法趋近于0,也达不到collectable.size(40)的阈值。

修复方案

方案1:统一距离计算与绘制的坐标

将距离计算中的道具y坐标改为绘制时的实际坐标:

distance = dist(collectable.x_pos, collectable.y_pos + 100, mouseX, mouseY);

方案2:修正道具的初始坐标

直接将道具的y_pos设为绘制时的实际位置,避免偏移:

collectable = {
    x_pos: 400,
    y_pos: 410, // 原310 + 100
    size: 40,
    isFound: false,
};

同时修改绘制代码中的y坐标为collectable.y_pos:

ellipse(collectable.x_pos, collectable.y_pos, collectable.size);
ellipse(collectable.x_pos, collectable.y_pos, collectable.size - 10);
text("£", collectable.x_pos - 5, collectable.y_pos + 7);

额外优化:碰撞判断更精准

为了让视觉上的碰撞与逻辑判断一致,建议将判断阈值设为道具半径与角色(鼠标椭圆)半径之和:

  • 道具半径:collectable.size / 2(20)
  • 鼠标椭圆半径:10(绘制的是ellipse(mouseX, mouseY, 20, 20))
  • 阈值应为:20 + 10 = 30

修改判断条件:

if (distance < (collectable.size / 2) + 10) {
    collectable.isFound = true;
}

完整修正代码(采用方案2+优化)

var gameChar_x;
var gameChar_y;
var floorPos_y;
var isLeft;
var isRight;
var isFalling;
var isPlummeting;
var distance;
var collectable;

function setup() {
  createCanvas(1024, 576);
  floorPos_y = (height * 3) / 4;
  gameChar_x = width / 2;
  gameChar_y = floorPos_y;

  isLeft = false;
  isRight = false;
  isFalling = false;
  isPlummeting = false;

  // 修正道具y_pos为实际绘制位置
  collectable = {
    x_pos: 400,
    y_pos: 410, // 原310 + 100
    size: 40,
    isFound: false,
  };

  canyon = {
    x_pos: 200,
    width: 100,
  };
}

function draw() {
  background(100, 155, 255); //fill the sky blue

  noStroke();
  fill(0, 155, 0);
  rect(0, floorPos_y, width, height - floorPos_y); //draw some green ground

  //draw the canyon
  fill(175, 238, 238);
  rect(canyon.x_pos + 20, 432, canyon.width, 300);
  fill(100, 155, 255);
  rect(canyon.x_pos + 20, 432, canyon.width, 100);
  fill(210, 105, 30);
  rect(canyon.x_pos + 20, 432, canyon.width - 90, 300);
  fill(240, 128, 128);
  rect(canyon.x_pos + 110, 432, canyon.width - 90, 300);

  if (gameChar_x > canyon.x_pos + 20 && gameChar_x < canyon.x_pos + 100) {
    isPlummeting = true;
  } else {
    isPlummeting = false;
  }

  if (
    (isPlummeting == true && gameChar_y >= floorPos_y) ||
    gameChar_y > floorPos_y
  ) {
    gameChar_y += 5;
  }

  //COLLECTIBLE
  if (collectable.isFound == false) {
    fill(255, 215, 0);
    ellipse(collectable.x_pos, collectable.y_pos, collectable.size);
    fill(218, 165, 32);
    ellipse(collectable.x_pos, collectable.y_pos, collectable.size - 10);
    fill(255, 215, 0);
    text("£", collectable.x_pos - 5, collectable.y_pos + 7);
    textSize(collectable.size - 20);
  }

  // 修正距离计算与碰撞判断
  ellipse(mouseX, mouseY, 20, 20);
  distance = dist(collectable.x_pos, collectable.y_pos, mouseX, mouseY);
  // 用半径之和作为阈值,判断更精准
  if (distance < (collectable.size / 2) + 10) {
    collectable.isFound = true;
  }

  console.log(distance);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:37:03