从另一个类调用render方法

时间:2018-11-04 01:35:14

标签: android libgdx

所以我试图用2d数组生成一个5x5的网格,但是当我尝试调用负责大小的render方法时,它不起作用。此外,我使用矩形框作为网格中的图像。它们渲染得很小。

package ksmd.tiles.Screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;

import ksmd.tiles.Tiles;
import ksmd.tiles.UI.Tile;

public class PlayScreen implements Screen {
    private Tiles game;
    //Texture texture;
    private Tile[][] tile;
    private float boardOffset;
    private OrthographicCamera orthographicCamera;

    public PlayScreen(Tiles game) {
        this.game = game;
        //texture = new Texture("badlogic.jpg");
        tile = new Tile[5][5];
        int tileSize = Tiles.WIDTH / tile[0].length;
        boardOffset = (Tiles.HEIGHT - (tileSize * tile.length)) / 2;
        for (int row = 0; row < tile.length; row++) {
            for (int col = 0; col < tile[0].length; col++) {
                tile[row][col] = new Tile(col * tileSize / 2, row * tileSize + boardOffset + tileSize / 2, tileSize, tileSize);
            }
        }
       // orthographicCamera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    }

    @Override
    public void show() {

    }

    @Override
    public void render(float delta) {
        //game.batch.setProjectionMatrix(orthographicCamera.combined);
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        game.batch.begin();
        for (int row = 0; row < tile.length; row++) {
            for (int col = 0; col < tile[0].length; col++) {

                tile[row][col].render(delta);
            }
        }

        game.batch.end();
    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {

    }
}


package ksmd.tiles.UI;

import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

import ksmd.tiles.Tiles;

public class Tile extends Box implements Screen {
private Tiles game;
private TextureRegion lit;
private TextureRegion dark;
private Sprite sprite;

private boolean selected;

public Tile(float x, float y, float width, float height) {

        this.x = x;
        this.y = y;
        this.height = height -8;
        this.width = width - 8;
        lit = Tiles.res.getAtlas("pack").findRegion("lit");
        dark = Tiles.res.getAtlas("pack").findRegion("dark");
    }


    @Override
    public void show() {
    }

    @Override
    public void render(float delta) {
        game.batch.begin();
        game.batch.draw(lit, x- width/ 2, y- height/ 2, width, height);
        game.batch.end();
    }

    public TextureRegion getTextureRegion(){
        return lit;
    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {

    }
}

基本上我是新手,不知道如何使用render方法使地图集在网格中更大。对不起,英语不好。

1 个答案:

答案 0 :(得分:3)

如果我对您的理解正确,您将渲染一个“瓷砖网格”。
我认为是像Squiddie所说的相机问题。
您说您是libgdx的新手,所以我将向您提供一些提示,告诉您如何更好地渲染游戏世界,并希望比解决相机问题更好。


首先,您应该使用视口。如果您已经了解了视口,那么它会非常有用,然后再将其弄糊涂。

基本上,您创建一个视口来定义当您使用不同的屏幕尺寸时,您对世界的了解程度以及它如何影响您的世界内容。

它提供了不同类型的视口:StretchViewport,FitViewport,FillViewport,ScreenViewport和ExtendViewport有关视口的更多信息:https://github.com/libgdx/libgdx/wiki/Viewports

创建视口是非常基本的:

Viewport viewport = new FitViewport(WORLD_WIDTH, WORLD_HEIGHT, camera);

WORLD_WIDHTWORLD_HEIGHT表示我们可以看到多少个“单位”,cameraOrthographicCamera

update()方法中,我们必须通知视口屏幕已调整大小。

@Override
public void resize(int width, int height) {
    viewport.update(width, height);
}

现在,视口将照顾内容的大小,以便您始终可以看到在视口构造函数中定义的世界。 更详细的说明Viewport的工作方式:Libgdx's World Units


现在进入Screen。基本上,您一次只能激活一个Screen,因此在Tile类中实现Screen是错误的。 LibGdx在您的情况下将活动屏幕的渲染方法称为PlayScreen中的render()方法。但是Tile不是屏幕,它只是可以渲染的Box。因此Tile不需要实现Screen。


Sprite类不仅包含Texture或TextureRegion,还包含在何处以及如何渲染精灵。因此,当您拥有Sprite时,无需为x,y,宽度,高度和旋转设置变量。如果您使用精灵,则可以简化Tile:

private Sprite texture;
public Tile(float x, float y, int widht, int height, Texture tex) {
    texture = new Sprite(tex);
    texture.setBounds(x, y, widht, height);
}

您还可以轻松绘制精灵:

public void render(Batch batch, float delta){
    texture.draw(batch);
}

要正确在屏幕上绘制精灵,您必须告诉SpriteBatch使用相机的矩阵。为此,在致电batch.begin()之前,您必须致电:

batch.setProjectionMatrix(viewport.getCamera().combined);

现在,在开始绘制精灵之前,您需要调用batch.begin();
现在重要的是,您只能在render方法中调用batch.begin();一次。在您的代码示例中,您调用batch.begin约26次,因为您还调用了Tile类中的batch.begin,这可能发生在Exception中。在渲染方法的最后,您必须调用一次batch.end();


我希望所有这些信息都可以解决您的问题,这是已经提到的评论中的Squiddie之类的Camera问题。

这也是渲染网格的一个运行示例,也许它可以帮助您了解每个组件以及如何实现:

public class PlayScreen implements Screen {

    private Tile[][] tiles;
    private Viewport viewport;
    private OrthographicCamera camera;

    private SpriteBatch batch;
    private Texture tex;

    private final float WORLD_WIDTH = 50, WORLD_HEIGHT = 50; //to see 50 x 50 units of the world
    private final int TILE_SIZE = 10; //on tile is 10 units big

    @Override
    public void show() {
        camera = new OrthographicCamera(WORLD_WIDTH, WORLD_HEIGHT);
        camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0); // center the camera
        viewport = new FitViewport(WORLD_WIDTH, WORLD_HEIGHT, camera); // create a viewport which sees 50 x 50 units of the game world

        batch = new SpriteBatch();

        tex = new Texture(Gdx.files.internal("badlogic.jpg"));

        tiles = new Tile[5][5];

        //Create the tiles
        for(int row = 0; row < tiles.length; row++){
            for(int col = 0; col < tiles[0].length; col++){
                tiles[row][col] = new Tile(col * TILE_SIZE, row * TILE_SIZE,TILE_SIZE, TILE_SIZE, tex);
            }
        }
    }

    //render the Tiles
    @Override
    public void render(float delta) {
        batch.setProjectionMatrix(viewport.getCamera().combined);

        batch.begin(); //call batch.begin() (this is the only call of batch.begin() !!! )
        for(int row = 0; row < tiles.length; row++){
            for(int col = 0; col < tiles[0].length; col++){
                tiles[row][col].render(batch, delta); // call the render method of each tile
            }
        }
        batch.end();//call batch.end() (this is the only call of batch.end() !!! )
    }

    @Override
    public void resize(int width, int height) {
        viewport.update(width, height); // update the viewport when the screen has been resized
    }

    @Override
    public void dispose() {
        //dispose disposable objects
        batch.dispose();
        tex.dispose();
    }

    @Override
    public void pause() { }
    @Override
    public void resume() { }
    @Override
    public void hide() { }
}

public class Tile {

    private Sprite texture;

    public Tile(float x, float y, int widht, int height, Texture tex) {
        texture = new Sprite(tex);
        texture.setBounds(x, y, widht, height); // set bounds of Sprite
    }

    public void render(Batch batch, float delta){
        //draw the sprite, but not call batch.begin() !!! because batch.begin() is already called!
        texture.draw(batch);
    }
}