In libgdx, how would I remove/delete an object from the screen when collision happens?

Viewed 26

So in the game I am making I have collision detection for when the ball hits a brick(block) but I can't seem to figure out how to remove/delete the brick that was hit by the ball. The bricks are stored in an ArrayList. Then in my Collision Detection class I tried to remove the brick when it gets contacted by the ball but it doesn't seem to work. The ball bounces off the the bricks, but the brick just stays there.

Main Game Class:

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.ScreenAdapter;
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.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.World;
import com.pongbreaker.helper.Constants;
import com.pongbreaker.objects.*;

import java.util.ArrayList;

public class GameScreen extends ScreenAdapter {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private World world;
    private Box2DDebugRenderer box2DDebugRenderer;

    //Game Objects
    private Player player, player2;
    private AI playerAI, playerAI2;
    private Ball ball;
    private Arena arenaTop, arenaBottom;
    ArrayList<Brick> brickArrayList = new ArrayList<Brick>();
    private Brick brick, brick2, brick3, brick4, brick5, brick6,
            brick7,brick8, brick9, brick10, brick11, brick12, brick13, brick14,
            brick36,brick37, brick38, brick39, brick40, brick41, brick42;

    private GameContactListener gameContactListener;
    private TextureRegion[] numbers;

    public GameScreen(OrthographicCamera camera) {
        this.camera = camera;
        this.camera.position.set(new Vector3(Main.INSTANCE.getScreenWidth() / 2, Main.INSTANCE.getScreenHeight() / 2, 0));
        this.batch = new SpriteBatch();
        this.world = new World(new Vector2(0, 0), false);
        this.box2DDebugRenderer = new Box2DDebugRenderer();
        this.gameContactListener = new GameContactListener(this);
        this.world.setContactListener(this.gameContactListener);

        this.player = new Player(316, Main.INSTANCE.getScreenHeight() / 2, this);
        this.player2 = new Player(1260, Main.INSTANCE.getScreenHeight() / 2, this);
        this.playerAI = new AI(1260, Main.INSTANCE.getScreenHeight() / 2, this);
        //this.playerAI2 = new AI(316, Main.INSTANCE.getScreenHeight() / 2, this);
        this.ball = new Ball(this);
        this.arenaTop = new Arena(32, this);
        this.arenaBottom = new Arena(Main.INSTANCE.getScreenHeight() - 32, this);

        brick = new Brick(33, 104, this);
        brick2 = new Brick(33, 176, this);
        brick3 = new Brick(33, 248, this);
        brick4 = new Brick(33, 320, this);
        brick5 = new Brick(33, 392, this);
        brick6 = new Brick(33, 464, this);
        brick7 = new Brick(33, 536, this);
        brick8 = new Brick(91.4f, 104, this);
        brick9 = new Brick(91.4f, 176, this);
        brick10 = new Brick(91.4f, 248, this);
        brick11 = new Brick(91.4f, 320, this);
        brick12 = new Brick(91.4f, 392, this);
        brick13 = new Brick(91.4f, 464, this);
        brick14 = new Brick(91.4f, 536, this);
        brick36 = new Brick(1523, 104, this);
        brick37 = new Brick(1523, 176, this);
        brick38 = new Brick(1523, 248, this);
        brick39 = new Brick(1523, 320, this);
        brick40 = new Brick(1523, 392, this);
        brick41 = new Brick(1523, 464, this);
        brick42 = new Brick(1523, 536, this);

        brickArrayList.add(brick);
        brickArrayList.add(brick2);
        brickArrayList.add(brick3);
        brickArrayList.add(brick4);
        brickArrayList.add(brick5);
        brickArrayList.add(brick6);
        brickArrayList.add(brick7);
        brickArrayList.add(brick8);
        brickArrayList.add(brick9);
        brickArrayList.add(brick10);
        brickArrayList.add(brick11);
        brickArrayList.add(brick12);
        brickArrayList.add(brick13);
        brickArrayList.add(brick14);
        brickArrayList.add(brick36);
        brickArrayList.add(brick37);
        brickArrayList.add(brick38);
        brickArrayList.add(brick39);
        brickArrayList.add(brick40);
        brickArrayList.add(brick41);
        brickArrayList.add(brick42);

        this.numbers = loadTextureSprite("core/src/com/pongbreaker/recources/numbers.png", 10);
    }


    public void update() {
        world.step(1 / 60f, 6, 2);

        this.camera.update();
        this.player.update();
        this.player2.update();
        this.playerAI.update();
        //this.playerAI2.update();
        this.ball.update();
        this.brick.update();
        this.brick2.update();
        this.brick3.update();
        this.brick4.update();
        this.brick5.update();
        this.brick6.update();
        this.brick7.update();
        this.brick8.update();
        this.brick9.update();
        this.brick10.update();
        this.brick11.update();
        this.brick12.update();
        this.brick13.update();
        this.brick14.update();
        this.brick36.update();
        this.brick37.update();
        this.brick38.update();
        this.brick39.update();
        this.brick40.update();
        this.brick41.update();
        this.brick42.update();

        batch.setProjectionMatrix(camera.combined);

        if(Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
            Gdx.app.exit();
        }

        if(Gdx.input.isKeyPressed(Input.Keys.R)) {
            this.ball.reset();
            this.player.setScore(0);
            this.player2.setScore(0);
            this.playerAI.setScore(0);
            this.playerAI2.setScore(0);
        }
    }

    @Override
    public void render (float delta) {
        update();

        Gdx.gl.glClearColor(0,0,0,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();
        this.player.render(batch);
        //this.player2.render(batch);
        this.playerAI.render(batch);
        //this.playerAI2.render(batch);
        this.ball.render(batch);
        this.arenaTop.render(batch);
        this.arenaBottom.render(batch);

        this.brick.render(batch);
        this.brick2.render(batch);
        this.brick3.render(batch);
        this.brick4.render(batch);
        this.brick5.render(batch);
        this.brick6.render(batch);
        this.brick7.render(batch);
        this.brick8.render(batch);
        this.brick9.render(batch);
        this.brick10.render(batch);
        this.brick11.render(batch);
        this.brick12.render(batch);
        this.brick13.render(batch);
        this.brick14.render(batch);
        this.brick36.render(batch);
        this.brick37.render(batch);
        this.brick38.render(batch);
        this.brick39.render(batch);
        this.brick40.render(batch);
        this.brick41.render(batch);
        this.brick42.render(batch);




        drawNumbers(batch,player.getScore(), 64, Main.INSTANCE.getScreenHeight() - 55, 30, 42);
        drawNumbers(batch, player2.getScore(), Main.INSTANCE.getScreenWidth() - 96, Main.INSTANCE.getScreenHeight() -55, 30, 42);

        batch.end();

       // this.box2DDebugRenderer.render(world, camera.combined.scl(Constants.PPM));
    }

    private void drawNumbers(SpriteBatch batch, int number, float x, float y, float width, float height) {
        if(number < 10) {
            batch.draw(numbers[number], x, y, width, height);
        }else{
            batch.draw(numbers[Integer.parseInt(("" + number).substring(0,1))], x, y, width, height);
            batch.draw(numbers[Integer.parseInt(("" + number).substring(1,2))], x + 20, y, width, height);
        }
    }
    private TextureRegion[] loadTextureSprite(String filename, int columns) {
        Texture texture = new Texture(filename);
        return TextureRegion.split(texture, texture.getWidth() / columns, texture.getHeight())[0];
    }

    public World getWorld() {
        return world;
    }

    public Ball getBall() {
        return ball;
    }

    public Player getPlayer() {
        return player;
    }

    public Player getPlayer2() {
        return player2;
    }

    public Brick getBrick() {
        return brick;
    }

    @Override
    public void dispose () {

    }

    public ArrayList<Brick> getBricksArrayList() {
        return brickArrayList;
    }


}

Collision Detection Class:

import com.badlogic.gdx.physics.box2d.*;
import com.badlogic.gdx.utils.Array;
import com.pongbreaker.helper.ContactType;
import com.pongbreaker.objects.Brick;

import java.util.ArrayList;

import static com.pongbreaker.helper.ContactType.BRICKS;

public class GameContactListener implements ContactListener {

    private GameScreen gameScreen;
    public boolean remove = false;



    //private ArrayList<Body> brickDeletionList = new ArrayList<Body>();

    public GameContactListener(GameScreen gameScreen) {
        this.gameScreen = gameScreen;
    }
    @Override
    public void beginContact(Contact contact) {
        Fixture a = contact.getFixtureA();
        Fixture b = contact.getFixtureB();

        if(a == null || b == null) return;
        if(a.getUserData() == null || b.getUserData() == null) return;

        if(a.getUserData() == ContactType.BALL || b.getUserData() == ContactType.BALL) {
            //Ball - Player
            if(a.getUserData() == ContactType.PLAYER || b.getUserData() == ContactType.PLAYER) {
                gameScreen.getBall().reverseVelocityX();
                gameScreen.getBall().increaseSpeed();
            }

            //Ball - Arena
            if(a.getUserData() == ContactType.ARENA || b.getUserData() == ContactType.ARENA) {
                gameScreen.getBall().reverseVelocityY();
            }

            //Ball - Brick
            if(a.getUserData() == ContactType.BRICKS || b.getUserData() == ContactType.BRICKS) {
                gameScreen.getBall().reverseVelocityX();
                gameScreen.getBall().increaseSpeed();
                gameScreen.getBricksArrayList().remove(gameScreen.brickArrayList);
            }
        }
    }

    @Override
    public void endContact(Contact contact) {

    }

    @Override
    public void preSolve(Contact contact, Manifold oldManifold) {
        /*WorldManifold manifold = contact.getWorldManifold();
        for (int j = 0; j < manifold.getNumberOfContactPoints(); j++) {
            if (contact.getFixtureA().getUserData() != null && contact.getFixtureA().getUserData().equals("p"))
                contact.setEnabled(false);
            if (contact.getFixtureB().getUserData() != null && contact.getFixtureB().getUserData().equals("p"))
                contact.setEnabled(false);

        }

         */
    }

    @Override
    public void postSolve(Contact contact, ContactImpulse impulse) {
        /*Body body = null;
        if(contact.getFixtureA() != null && contact.getFixtureA().getUserData() != null && contact.getFixtureA().getUserData().equals("b"))
            body = contact.getFixtureA().getBody();
        if(contact.getFixtureB() != null && contact.getFixtureB().getUserData() != null && contact.getFixtureB().getUserData().equals("b"))
            body = contact.getFixtureB().getBody();
        if(body != null) {
            body.setActive(false);
            world.destroyBody(body);
        }

         */
    }

}

And Brick Class:

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.physics.box2d.Body;
import com.pongbreaker.game.GameScreen;
import com.pongbreaker.helper.BodyHelper;
import com.pongbreaker.helper.Constants;
import com.pongbreaker.helper.ContactType;

import java.util.ArrayList;

public class Brick {
    private Body body;
    private float x, y, width;
    private int height,score, row, column;
    private Texture texture;
    private GameScreen gameScreen;
    private int map [][];


    public Brick(float x, float y, GameScreen gameScreen) {
        this.x = x;
        this.y = y;
        this.gameScreen = gameScreen;
        //this.map = new int[row][column];
        this.width = 50.4f;
        this.height = 64;

        /*for(int i = 0; i < row; i++) {
            for(int j = 0; j < column; j++) {
                map[i][j] = 1;
            }
        }

         */


        this.texture = new Texture("core/src/com/pongbreaker/recources/redTexture.png");
        this.body = BodyHelper.createBody(x, y, width, height, true, 10000, gameScreen.getWorld(), ContactType.BRICKS);
    }

    public void update() {
        x = body.getPosition().x * Constants.PPM - (width / 2);
        y = body.getPosition().y * Constants.PPM - (height / 2);

    }

    public void render(SpriteBatch batch) {
        /*for(int i = 0; i < map.length; i++) {
            for(int j = 0; j < map.length; j++) {
                if(map[i][j] > 0) {
                    batch.draw(texture,x, y,width,height);
                }
            }
        }

         */


        batch.draw(texture, x, y, width, height);



    }

    public boolean collidesWith(Brick brick) {
        return x < this.x + this.width && y < this.y + this.height && x + width > this.x && y + height > this.height;
    }

    public void setBrick(int value, int row, int column) {
        map[row][column] = value;
    }


    public void score() {
        this.score++;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public void dispose () {

    }
}
1 Answers

It's not connected to dispose which just frees ram if you don't need graphics memory.

The object stub for box2D works differently from how you are using and although I wonder why all the bricks aren't removed with this gameScreen.getBricksArrayList().remove(gameScreen.brickArrayList);

, you -cannot- remove a single brick as you have it. For each box2D brick you associate ContactType.BRICKS but that means that you can't look up an individual brick because they all have the same box2D object stub of that enum. You need to have a new Object that is specifically associated with a -single- brick. This leads to a partial rewrite I think so I don't think there is a fix for how you have it now, as you can't identify a single brick to remove anyway.

Anyway so this.body = BodyHelper.createBody(x, y, width, height, true, 10000, gameScreen.getWorld(), ContactType.BRICKS); should be this.body = BodyHelper.createBody(x, y, width, height, true, 10000, gameScreen.getWorld(), this); thereby directly storing that -specific- brick in the object stub. And go from there.

Related