Question:
Making a simple toy. The logic is that there is an object at the left edge of the screen, let's call it a person for convenience. At the right edge, other objects will spawn in a chaotic manner, for convenience, let's call them zombies. A person kills them with a constantly shooting machine gun, the "bullets" of which, when crossing with "zombies", must remove the "zombies" from the screen.
The problem is that these "bullets" just fly past the "zombies". That is, I cannot track the intersection of the "bullet" and "zombie" renders.
As I understand it, the problem is in the numerous declarations of Rectangle
"zombies" and "bullets", which leads to confusion in the code and the problem that I have, in particular. Is it possible to declare it only once and then use it everywhere? If so, how?
By the way, just declare it at the class level, as the same human Rectangle
does not work, because a NullPointerException
, with a reference to spawncrowd
and spavbullet
. Thanks in advance_)
import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.math.Rectangle; import java.util.Iterator;
public class MyGdxGame extends ApplicationAdapter { OrthographicCamera camera; SpriteBatch batch;
Texture manImage, bulletImage, CrowdImage; Rectangle manRect; Vector3 touchPos; Array<Rectangle> bulletsArray, CrowdElemArray;
long lastbultime, lastcrowdeltime;
int counter_miss;
@Override
public void create () {
camera = new OrthographicCamera();
camera.setToOrtho(false, 960, 540);
touchPos = new Vector3();
batch = new SpriteBatch();
manImage = new Texture("man.jpg");
bulletImage = new Texture("bullet.jpg");
CrowdImage = new Texture("Crowd.jpg");
manRect = new Rectangle();
manRect.x = 0;
manRect.y = 540/2;
manRect.height = 256;
manRect.width = 256;
CrowdElemArray = new Array<Rectangle>();
spawncrowdel();
bulletsArray = new Array<Rectangle>();
spawnbullet();
}
public void spawncrowdel() {
Rectangle CrowdelementRect = new Rectangle();
CrowdelementRect.y = MathUtils.random(0, 540-256);
CrowdelementRect.x = 960;
CrowdelementRect.height = 256;
CrowdelementRect.width = 64;
CrowdElemArray.add(CrowdelementRect);
lastcrowdeltime = TimeUtils.nanoTime();
}
public void spawnbullet() {
Rectangle bulletRect = new Rectangle();
bulletRect.y = manRect.getY() + manRect.height/2;
bulletRect.x = manRect.getX();
bulletRect.height = 256;
bulletRect.width = 64;
bulletsArray.add(bulletRect);
lastbultime = TimeUtils.nanoTime();
}
@Override
public void render () {
Gdx.gl.glClearColor(0, 1, 0.5f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(manImage, manRect.x, manRect.y);
for (Rectangle CrowdelementRect: CrowdElemArray) batch.draw(CrowdImage, CrowdelementRect.x, CrowdelementRect.y);
for (Rectangle bulletRect: bulletsArray) batch.draw(bulletImage, bulletRect.x, bulletRect.y);
batch.end();
// Сенсорное урправление
if (Gdx.input.isTouched()){
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
manRect.y = (int) (touchPos.y - 128/2);
}
if (Gdx.input.isKeyPressed(Input.Keys.UP)) manRect.y += 200 * Gdx.graphics.getDeltaTime();
if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) manRect.y -= 200 * Gdx.graphics.getDeltaTime();
if (manRect.y < 0) manRect.y = 0;
if (manRect.y > 540-256) manRect.y = 540-256;
//TODO Спавнинг зомби
if (TimeUtils.nanoTime() - lastcrowdeltime > 2000000000) spawncrowdel();
//TODO Спавнинг пули
if (TimeUtils.nanoTime() - lastbultime > 800000000) spawnbullet();
//TODO Движение зомби
Iterator<Rectangle> move = CrowdElemArray.iterator();
while (move.hasNext()){
Rectangle CrowdelementRect = new Rectangle();
CrowdelementRect = move.next();
CrowdelementRect.x -= 100 * Gdx.graphics.getDeltaTime();
if (CrowdelementRect.x <= 10) {
counter_miss += 1;
move.remove();
}
if (CrowdelementRect.overlaps(manRect)) move.remove();
}
//TODO Движение пули
Iterator<Rectangle> movebul = bulletsArray.iterator();
Rectangle CrowdelementRect = new Rectangle();
while (movebul.hasNext()){
Rectangle bulletRect = movebul.next();
bulletRect.x += 100 * Gdx.graphics.getDeltaTime();
if (bulletRect.x > 960) {
movebul.remove();
}
if (bulletRect.overlaps(CrowdelementRect)) movebul.remove();
}
}
@Override
public void dispose() {
super.dispose();
CrowdImage.dispose();
manImage.dispose();
bulletImage.dispose();
batch.dispose();
}
} `
PS
I did everything according to the template from the "startandroid".
Answer:
The solution is taken from here . A person solves a similar problem through the following code:
private void testCollision() {
Iterator<Bullet> b = ball.iterator();
while(b.hasNext()) {
Bullet balls = b.next();
Iterator<Enemy> i = enemy.iterator();
while(i.hasNext()) {
Enemy enemies = i.next();
if ((Math.abs(balls.x - enemies.x) <= (balls.width + enemies.width) / 2f)
&& (Math.abs(balls.y - enemies.y) <= (balls.height + enemies.height) / 2f)) {
i.remove();
b.remove();
}
}
}
}
once tried it myself – it worked for me.