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

p5.js实现小球弹跳时小球不反弹反而沉入地面该如何修复

问题原因
  • 碰撞检测后没有修正小球位置,小球穿入地面下方后,后续每一帧都会触发this.y + this.radius > height的判定,反复反转速度,最终速度持续向下导致沉底
  • 重力叠加逻辑错误,当前只有小球未接触上下边界时才会叠加重力,碰撞时重力失效,不符合物理规则,也会放大穿模问题
修复方案

直接替换newCircle类中的bounce方法即可,修改点如下:

  1. 每帧优先叠加重力,再做位移和碰撞判定,保证重力始终生效
  2. 碰撞到边界时,先把小球位置重置到刚好接触边界的位置,再反转速度,避免反复触发碰撞
  3. 启用你预先定义的gravity变量作为重力参数,方便后续调整
    注:p5.js中ellipse方法的第三参数默认是圆形直径,如果你代码中传入的radius实际是半径,需要将绘制语句改为ellipse(this.x, this.y, this.radius * 2),碰撞判定保持原有逻辑即可,当前修改保持和你原有参数逻辑一致。

修改后的完整运行代码:

var gravity = 2; // 原9.8数值太大动画会过快,可自行调整参数
var circleOne;

function setup() {
  createCanvas(400, 400);
  circleOne = new newCircle(200, 50, 50, "black");
}

function draw() {
  background("white");
  circleOne.display();
  circleOne.bounce();
}


class newCircle {
  constructor(x,y,radius,color) {
    this.x = x
    this.y = y
    this.radius = radius
    this.color = color
    this.velocity = 1;
  }
  
  display() {
    fill(this.color)
    ellipse(this.x,this.y,this.radius);
  }
  
  bounce() {
    // 每帧统一叠加重力
    this.velocity += gravity;
    this.y += this.velocity;

    // 底部碰撞判定
    if (this.y + this.radius > height) {
      // 先修正位置到刚好接触地面
      this.y = height - this.radius;
      // 再反转速度
      this.velocity = -this.velocity * 0.5
    }
    // 顶部碰撞判定
    if (this.y < 0) {
      this.y = 0;
      this.velocity = -this.velocity * 0.5
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:54:04