无法绘制小球运动轨迹:重力模拟中background(0)导致轨迹丢失
解决重力模拟中小球轨迹保留问题
要保留小球的运动轨迹,核心问题是background(0)会完全清除画布,导致上一帧的轨迹被抹除。这里提供两种实用的解决思路:
方法一:半透明叠加实现渐隐拖尾
不用直接清除整个画布,而是每次用低透明度的黑色矩形覆盖,让旧轨迹逐渐淡化,同时新轨迹得以保留。这种方法性能开销小,适合做自然的拖尾效果。
修改后的完整代码:
float x = 10; float y = 50; float speedX = 2; float speedY = 6; float gravity = 0.98; float red = 255; float green = 0; float blue = 0; // 记录上一帧的位置,用于绘制轨迹线 float prevX = 10; float prevY = 50; void setup() { size(640, 360); } void draw() { // 用半透明黑色覆盖画布,替代background(0) fill(0, 15); // 透明度值越小,轨迹保留时间越长 noStroke(); rect(0, 0, width, height); fill(red, green, blue); if (mousePressed == false) { // 更新位置前先保存当前坐标为上一位置 prevX = x; prevY = y; // 运动逻辑 speedY += gravity; x += speedX; y += speedY; } // 边界碰撞检测 if (x >= width || x <= 0) { speedX = -speedX; } if (y >= height || y <= 0) { speedY = -speedY; } // 绘制运动轨迹线(连接上一帧和当前帧的位置) stroke(255, 0, 0); line(prevX, prevY, x, y); // 绘制小球 noStroke(); circle(x, y, 50); }
方法二:记录历史坐标绘制完整轨迹
如果需要保留完整的运动轨迹不淡化,可以用数组存储小球走过的所有坐标点,每次重绘时遍历数组画出整条轨迹。注意控制轨迹点的最大数量,避免内存占用过高。
修改后的完整代码:
float x = 10; float y = 50; float speedX = 2; float speedY = 6; float gravity = 0.98; float red = 255; float green = 0; float blue = 0; // 存储轨迹坐标的数组 ArrayList<PVector> trajectory = new ArrayList<PVector>(); // 限制最大轨迹点数量 int maxTrajectoryPoints = 200; void setup() { size(640, 360); } void draw() { background(0); // 可以保留全清屏,因为会重绘所有轨迹点 fill(red, green, blue); if (mousePressed == false) { // 将当前位置加入轨迹数组 trajectory.add(new PVector(x, y)); // 超过最大数量时移除最早的点 if (trajectory.size() > maxTrajectoryPoints) { trajectory.remove(0); } // 运动逻辑 speedY += gravity; x += speedX; y += speedY; } // 边界碰撞检测 if (x >= width || x <= 0) { speedX = -speedX; } if (y >= height || y <= 0) { speedY = -speedY; } // 绘制完整轨迹 stroke(255, 0, 0); noFill(); beginShape(); for (PVector point : trajectory) { vertex(point.x, point.y); } endShape(); // 绘制小球 noStroke(); circle(x, y, 50); }
两种方法各有适用场景:方法一适合制作自然的渐隐拖尾,代码简单且性能好;方法二适合需要完整记录运动路径的场景,可通过调整maxTrajectoryPoints控制轨迹长度。
内容的提问来源于stack exchange,提问作者IllTime00qw
相关产品推荐
相关产品推荐

