如何实现静止物体逼近视觉效果?解决小球落在移动平台的问题
跳球游戏问题解决方案
一、让小球落在移动平台上的解决方案
你的碰撞检测逻辑存在两个核心问题:
- 碰撞边界计算错误:平台使用了
rectMode(CENTER),但碰撞条件直接用plat.y(矩形中心坐标)判断,未考虑矩形实际边界范围。 - 未同步平台移动速度:平台持续加速移动,小球碰撞后仅重置垂直速度,未跟随平台移动,导致平台离开后小球立刻掉落。
修改后的代码示例
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_
相关产品推荐
相关产品推荐

