试图制作游戏 Tank Trouble 的副本,但我不知道如何对子弹和墙壁/玩家进行碰撞检测。按下鼠标时会生成子弹,但我不知道如何让它们在击中物体后消失。
试图让它们在接触时融入背景,但游戏开始严重滞后。还尝试了人们用来从 arrayLists 中删除项目的向后循环,但无济于事。
PVector player = new PVector (300, 400);
ArrayList <Bullet> bullets = new ArrayList <Bullet> ();
float maxSpeed = 3; //speed of bullets
void setup() {
size(800, 600);
fill(0);
}
void draw() {
background(255);
line(20, 200, 400, 200);
rect(300, 400, 50, 50);
//creates an aiming tool for the players
PVector mouse = new PVector(mouseX, mouseY);
fill(255);
ellipse(mouse.x, mouse.y, 8, 8);
if (frameCount%5==0 && mousePressed) {
PVector dir = PVector.sub(mouse, player);
dir.normalize();
dir.mult(maxSpeed*3);
Bullet b = new Bullet(player, dir);
bullets.add(b);
}
for (Bullet b : bullets) {
b.update();
b.display();
}
}
class Bullet extends PVector {
PVector vel;
Bullet(PVector loc, PVector vel) {
super(loc.x, loc.y);
this.vel = vel.get();
}
void update() {
add(vel);
}
void display() {
fill(0);
ellipse(x, y, 5, 5);
}
float bulletX() {
return x;
}
}
基本上希望子弹在最后一次触摸消失之前弹跳 3-4 次。如果它在任何时候接触到玩家,他们都应该消失。
最佳答案
在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);
2 个 vector 的点积等于 2 个 vector 之间夹角的余弦乘以两个 vector 的大小(长度)。
dot( A, B ) == | A | * | B | * cos( alpha )
V
和 D
的点积等于直线 (O
, D
) 和 vector V = P - O
,乘以 V
的数量(长度),因为 D
是 unit vector (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);
}
}
关于java - 如何在碰撞时从 arrayList 中删除一个项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56536825/