【问题标题】:calling render method from another class从另一个类调用渲染方法
【发布时间】:2018-11-04 01:35:14
【问题描述】:

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

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

    }
}

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

【问题讨论】:

  • @Squiddie 即使摄像头无法正常工作,也与屏幕无关:(

标签: android libgdx


【解决方案1】:

如果我理解正确,您将渲染一个瓷砖网格。
我认为这是 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 不是一个屏幕,它只是一个可以渲染的盒子。所以 Tile 不需要实现 Screen。


Sprite 类不仅包含 Texture 或 TextureRegion,它还包含 sprite 的渲染位置和方式。所以当你有一个 Sprite 时,你不需要 x、y、宽度、高度和旋转的变量。如果你使用你的精灵,你可以简化你的瓷砖:

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,这可能发生在异常中。在您的渲染方法结束时,您必须调用一次 batch.end();


我希望所有这些信息都可以解决您的问题,这是像 cmets 中的 Squiddie 一样的相机问题。

这里还有一个渲染 Grid 的小运行示例,也许它可以帮助您了解每个组件以及如何做到这一点:

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

【讨论】:

  • 哇,非常感谢老兄,非常感谢您花时间帮助我理解这一点。我会试一试,并会更新你!
  • 你知道点击后我会如何改变图片吗? @Morchul 非常感谢!
  • @Guavaman 按钮的图像还是背景图像?您可以使用 InputProcessor:github.com/libgdx/libgdx/wiki/Event-handling 来捕获点击事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
  • 2011-09-07
  • 2014-02-07
  • 1970-01-01
  • 2011-09-09
相关资源
最近更新 更多