简体   繁体   English

如何在 libgdx 中显示 map?

[英]How would I display a map in libgdx?

So I am creating a game with libgdx were I combine both pong and breakout.所以我正在用 libgdx 创建一个游戏,我将 pong 和 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.我目前正在为积木使用 map。

The class where it displays everything: class 显示所有内容:

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:和砖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 )现在我正在分别绘制如下所示的砖块:!( 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.).它与您的问题无关,但是您需要在砖块 class 中公开一个dispose()方法来处理纹理,并从 Screen class 的dispose()方法以及所有的 dispose( dispose()方法中调用它您的其他一次性用品(Textures、SpriteBatch、Box2DDebugRenderer 等)。 Otherwise, you are leaking memory.否则,您将泄漏 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.我认为您通过制作一个Brick class 使自己感到困惑,它同时代表单个 Brick 并代表电路板一侧的所有砖块。

Fields that treat your Brick class as if it represents a single Brick:将 Brick class 视为代表单个 Brick 的字段:

body, x, y, width, height

Fields that treat your Brick class as if it represents all bricks:将 Brick class 视为代表所有砖块的字段:

score, row, column, map

You should break this class up into two classes, BrickGroup and Brick.您应该将此 class 分成两个类,BrickGroup 和 Brick。 Your map in the BrickGroup should be a 2D array of individual Bricks, instead of int s. map中的 map 应该是单个砖块的二维数组,而不是int s。 You can add a int status = 1;您可以添加一个int status = 1; field to your Brick class to take the place of what was in the 2D array before.字段到您的 Brick class 以代替之前二维数组中的内容。

Then your BrickGroup render method can simply iterate the map to call each Brick's render method.然后您的 BrickGroup 渲染方法可以简单地迭代map来调用每个 Brick 的渲染方法。 The Brick's render method can use its status, position, and size to draw itself. Brick 的渲染方法可以使用它的状态、position 和大小来绘制自己。

I also recommend renaming row and column to rowCount and columnCount in BrickGroup to make it clear what they represent.我还建议将 BrickGroup 中的rowcolumn重命名为rowCountcolumnCount以明确它们代表的内容。

Make sure you do not move the Texture loading into the Brick class, or you'll be loading many duplicate calls to it.确保不要将纹理加载移动到 Brick class 中,否则您将加载许多重复调用。 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.您可以在 BrickGroup 中加载一次并为 Brick 类的渲染方法创建一个texture参数,因此 BrickGroup 在绘制自身时传递每个 Brick 的引用以借用。

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.最后,我认为先水平然后垂直(x,然后 y)进行 2D 数组查找更自然,因此在初始化 2D 数组大小时应该交换行和列。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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