Добавить метод к классу Bullet
, который проверяет, находится ли пуля вне окна:
class Bullet extends PVector {
// [...]
boolean outOfBounds() {
return this.x<0 || this.x>width || this.y<0 || this.y>height;
}
}
Добавить проверку столкновения со строкой в класс Bullet
.Чтобы проверить, попадает ли пуля в селезенку, необходимо рассчитать ближайшую точку на линии и проверить, меньше ли расстояние до линии, чем скорость пули, и не попадает ли пуля в линию по бокам..
Если у вас есть линия, заданная точкой (O
) и направлением (D
), то ближайшая точка на линии к точке p может быть рассчитана следующим образом
X = O + D * dot(P-O, D);
Точечное произведение двух векторов равно косинусу угла между двумя векторами, умноженному на величину (длину) обоих векторов.
dot( A, B ) == | A | * | B | * cos( alpha )
Точечное произведение V
и D
равно косинусу угла между линией (O
,D
) и вектор V = P - O
, умноженный на сумму (длину) V
, поскольку D
представляет собой единичный вектор (длина D
равна 1,0),
Применение этого к вашему коду приводит к следующему методу:
class Bullet extends PVector {
// [...]
boolean collideline(float x1, float y1, float x2, float y2) {
PVector O = new PVector(x1, y1);
PVector L2 = new PVector(x2, y2);
float len = O.dist(L2);
PVector D = L2.sub(O).normalize();
PVector P = this;
PVector X = add(O, mult(D, sub(P, O).dot(D)));
// distance to the line has to be less than velocity
float distX = X.dist(P);
if (distX > this.vel.mag())
return false;
// very if bullet doesn't "miss" the line
PVector VX = X.sub(O);
float distO = VX.dot(D);
return distO > -5 && distO < len+5;
}
}
Удалить маркер из списка по егоиндекс (в обратном порядке), если они выходят за границы или сталкиваются с линией:
void draw() {
// [...]
for (int j = bullets.size()-1; j >= 0; j--) {
if (bullets.get(j).outOfBounds() || bullets.get(j).collideline(20, 200, 400, 200))
bullets.remove(j);
}
}