简体   繁体   中英

How would I display a map in libgdx?

So I am creating a game with libgdx were I combine both pong and breakout. I am having trouble trying to figure out how to display the "bricks" from the game breakout. I am currently using a map for the bricks.

The class where it displays everything:

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;
    private Brick brick, brick2;

    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);
        this.brick = new Brick(5, 96, 8, 5, this);
        this.brick2 = new Brick(5, 166, 8, 5, this);
        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();

        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);
        }
    }

    @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);

        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 () {

    }
}

And the brick class:

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

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

        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) {
        batch.draw(texture, x, y, width, height);
    }

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

    public void draw(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();
                }
            }
        }
    }

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

    public int getScore() {
        return score;
    }

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

Right now I am drawing in the bricks separately which looks like this: !( https://imgur.com/a/Fs4D8pg )

First thing's first. It's not related to your question, but you need to expose a dispose() method in your brick class to dispose of the Texture, and call it from the dispose() method of your Screen class, along with the dispose() methods of all your other Disposables (Textures, SpriteBatch, Box2DDebugRenderer, etc.). Otherwise, you are leaking memory.

I think you've confused yourself by making a Brick class that simultaneously sort of represents a single Brick and sort of represents all the bricks on one side of the board.

Fields that treat your Brick class as if it represents a single Brick:

body, x, y, width, height

Fields that treat your Brick class as if it represents all bricks:

score, row, column, map

You should break this class up into two classes, BrickGroup and Brick. Your map in the BrickGroup should be a 2D array of individual Bricks, instead of int s. You can add a int status = 1; field to your Brick class to take the place of what was in the 2D array before.

Then your BrickGroup render method can simply iterate the map to call each Brick's render method. The Brick's render method can use its status, position, and size to draw itself.

I also recommend renaming row and column to rowCount and columnCount in BrickGroup to make it clear what they represent.

Make sure you do not move the Texture loading into the Brick class, or you'll be loading many duplicate calls to it. You can load it once in BrickGroup and make a texture parameter for the Brick class's render method, so the BrickGroup passes the reference for each Brick to borrow while its drawing itself.

Finally, I think it's more natural to make your 2D array lookup with horizontal first and then vertical (x, then y), so you should swap rows and columns when initializing the 2D array size.

Example:

public class Brick {
    private Body body;
    private float x, y;
    private int width, height, status;

    public Brick(GameScreen gameScreen, float x, float y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.body = BodyHelper.createBody(x, y, width, height, true, 10000, gameScreen.getWorld(), ContactType.BRICKS);
        this.status = 1;
    }

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

    public void render(SpriteBatch batch, Texture texture) {
        if (status > 0) {
            batch.draw(texture, x, y, width, height);
        }
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }
}
public class BrickGroup implements Disposable {
    private int score;
    private Texture texture;
    private GameScreen gameScreen;
    private Brick[][] map;

    public BrickGroup(float x, float y, int rowCount, int columnCount, GameScreen gameScreen) {
        this.gameScreen = gameScreen;
        this.map = new Brick[columnCount][rowCount];

        int brickWidth = 300 / column;
        int brickHeight = 512 / row;

        for(int i = 0; i < row; i++) {
            for(int j = 0; j < column; j++) {
                map[i][j] = new Brick(gameScreen, x + i * brickWidth, y + j * brickHeight, brickWidth, brickHeight);
            }
        }

        this.texture = new Texture("core/src/com/pongbreaker/recources/redTexture.png");
    }

    public void update() {
        for(Brick[] col : map) {
            for(Brick brick : col) {
                brick.update();
            }
        }
    }

    public void render(SpriteBatch batch) {
        for(Brick[] col : map) {
            for(Brick brick : col) {
                brick.render(batch, texture);
            }
        }
    }

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

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

    public int getScore() {
        return score;
    }

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

    @Override
    public void dispose() {
        texture.dispose();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM