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

如何实现静止物体逼近视觉效果?解决小球落在移动平台的问题

跳球游戏问题解决方案

一、让小球落在移动平台上的解决方案

你的碰撞检测逻辑存在两个核心问题:

  1. 碰撞边界计算错误:平台使用了rectMode(CENTER),但碰撞条件直接用plat.y(矩形中心坐标)判断,未考虑矩形实际边界范围。
  2. 未同步平台移动速度:平台持续加速移动,小球碰撞后仅重置垂直速度,未跟随平台移动,导致平台离开后小球立刻掉落。

修改后的代码示例

let gravity = 1.5;
class Ball{
  constructor(){
    this.x = 0;
    this.y= 200;
    this.d = 30;
    this.xg = 0;
    this.yg = 0;
  }
  
  draw() {
    ellipse(this.x, this.y, this.d);
  }
  
  update() {
    this.draw();
    this.y += this.yg;
    // 修正边界判断:基于小球半径计算实际底部位置
    if (this.y + this.d/2 < windowHeight) {
      this.yg += gravity;
    }
  }
}
class Platform{
  constructor({x,y}){
    this.x = x;
    this.y= y;
    this.w = 30;
    this.h = 30;
    this.s = 1;
  }
  
  draw(){
    push();
    rectMode(CENTER);
    rotateX(1.45);
    rect(this.x,this.y,this.w,this.h);
    pop();
  }
  
  move(){
    this.y += this.s;
    this.s += 0.0001;
  }
}

let ball;
let plat;
function setup(){
  createCanvas(710, 400, WEBGL);
  ball = new Ball();
  plat = [
    new Platform({x:0,y:200}),
    new Platform({x:50,y:100}),
    new Platform({x:0,y:0}),
    new Platform({x:-50,y:-100}),
    new Platform({x:0,y:-200}),
  ];
}

function draw(){
  background(255);
  
  ball.update();
  plat.forEach((plat) => {
    plat.draw();
    plat.move();
  });
  
  plat.forEach((plat) => {
    // 基于rectMode(CENTER)计算碰撞边界
    const ballBottom = ball.y + ball.d/2;
    const platformTop = plat.y - plat.h/2;
    const ballRight = ball.x + ball.d/2;
    const ballLeft = ball.x - ball.d/2;
    const platformRight = plat.x + plat.w/2;
    const platformLeft = plat.x - plat.w/2;
    
    // 修正后的碰撞条件
    if (
      ballBottom <= platformTop &&
      ballBottom + ball.yg >= platformTop &&
      ballRight >= platformLeft &&
      ballLeft <= platformRight
    ) {
      ball.yg = plat.s; // 让小球跟随平台速度移动
      ball.y = platformTop - ball.d/2; // 修正位置避免穿透
    }
  });
}

function keyPressed() {
  if (keyCode === UP_ARROW) {
    ball.yg -= 20;
  }
}

关键修改点

  • 基于rectMode(CENTER)重新计算小球和平台的碰撞边界,确保判断逻辑准确。
  • 碰撞后让小球垂直速度等于平台移动速度plat.s,实现同步移动。
  • 调整小球边界判断逻辑,用半径替代直径,避免位置计算错误。

二、让静止物体看起来向玩家靠近的方法

在p5.js WEBGL中,有两种常用实现方式:

1. 移动相机(推荐)

使用camera()函数动态调整相机位置,让相机跟随小球移动,视觉上营造物体靠近的效果:

function draw(){
  background(255);
  
  // 让相机跟随小球,保持小球在屏幕中心附近
  camera(0, ball.y - 200, 300, 0, ball.y - 200, 0, 0, 1, 0);
  
  ball.update();
  plat.forEach((plat) => {
    plat.draw();
    plat.move();
  });
  
  // ... 碰撞检测代码
}

2. 反向移动所有物体

保持相机位置不变,当小球移动时反向移动场景内所有物体,模拟相机移动效果:

let cameraOffset = 0;

function draw(){
  background(255);
  
  // 当小球偏离中心时,更新偏移量
  if (ball.y < windowHeight/2) {
    cameraOffset += (windowHeight/2 - ball.y) * 0.1;
  }
  
  push();
  translate(0, cameraOffset); // 反向移动所有物体
  
  ball.update();
  plat.forEach((plat) => {
    plat.draw();
    plat.move();
  });
  
  // ... 碰撞检测代码
  
  pop();
}

两种方式都能实现目标效果,移动相机的方式更贴合3D场景逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:55:33