将新球添加到 arraylist 会导致所有后续球位置被移动

Adding new ball to arraylist causes all the subsequent ball positions to be shifted

我需要实现弹跳球,可以在按下鼠标的位置添加弹跳球并从墙上弹开。但是现在我可以让第一个球工作,但所有后续球都出现在鼠标位置之外并且具有奇怪的墙壁碰撞检测。

我怀疑这是因为我的 for 循环,因为当我向后遍历列表时,球出现在正确的位置,但是当我添加一个新球时,所有球的位置都会重置。

ArrayList<Ball> balls;

void setup() {
    size (640 , 480, P3D);
    noSmooth();
    // Create an empty ArrayList (will store Ball objects)
    balls = new ArrayList<Ball>();
}

void draw() {
    background(1);

    // Frame
    stroke(255);
    line(0, 0, -500, width, 0, -500);
    line(0, 0, -500, 0, height, -500);
    line(0, height, -500, width, height, -500);
    line(width, height, -500, width, 0, -500);
    line(0, 0, -500, 0, 0, 0);
    line(width, 0, -500, width, 0, 0);
    line(0, height, -500, 0, height, 0);
    line(width, height, -500, width, height, 0);

    //for (int i = balls.size()-1; i >= 0; i--) { 
    for (int i= 0; i<balls.size(); i ++){
        Ball ball = balls.get(i);
        ball.move();
        ball.display();
    }  
}

void mousePressed() {
    // A new ball object is added to the ArrayList (by default to the end)
    balls.add(new Ball(mouseX, mouseY, random(-5.0,5),random(-5.0,5)));
}

// Simple bouncing ball class
class Ball {
    PVector pos;  
    PVector vel; 
    float grav = 0.1;

    Ball(float posX, float posY, float velX, float velY){
        pos = new PVector(posX, posY, 1);
        vel = new PVector(velX, velY, 1);
    }

    void move() {
        // Add gravity to speed
        //vel.y += grav;
        // Add speed to y location
        pos.add(vel);

        if (pos.x>width-50) {
            vel.x*=-1;
        }
        if (pos.y>height-50) {
            vel.y*=-1;
        }
        if (pos.z>500) {
            vel.z*=-1;
        }
        if (pos.x<50) {
            vel.x*=-1;
        }
        if (pos.y<50) {
            vel.y*=-1;
        }  
        if (pos.z<0) {
            vel.z*=-1;
        }
    }

    void display() {
        translate(pos.x,pos.y, -pos.z);
        sphere(50);
        noFill();
    }
}  

我不知道我要做什么来修复它,所以感谢您的帮助。

问题是对 translate() 的调用。该函数不仅定义了一个平移矩阵,它还定义了一个矩阵并将该矩阵连接(相乘)到当前矩阵。这导致第一个球是正确的,但随后的每个球都偏离了预期的位置。
使用 pushMatrix() push (store) the current matrix, before the individual translation matrix for a ball is set. Use popMatrix() 弹出(恢复)当前矩阵,球被绘制后。例如:

class Ball {

    // [...]

    void display() {
        pushMatrix();
        translate(pos.x, pos.y, -pos.z);
        sphere(size);
        noFill();
        popMatrix();
    }
}