вызов метода рендеринга из другого класса - PullRequest
0 голосов
/ 04 ноября 2018

Поэтому я пытаюсь сгенерировать сетку 5x5 с 2d массивом, но когда я пытаюсь вызвать метод рендеринга, который отвечает за размер, он не работает. Кроме того, я использовал прямоугольники в качестве моих изображений в сетке. Они делают очень маленькие.

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

    }
}

По сути, я новичок и не знаю, как использовать метод рендеринга, чтобы увеличить атласы в сетке. Извините за плохой английский.

1 Ответ

0 голосов
/ 05 ноября 2018

Если я правильно вас понимаю, вы предоставите Сетка плиток.
Я думаю, что это проблема с камерой, как говорит Сквидди.
Вы сказали, что вы новичок в libgdx, поэтому я дам вам несколько советов о том, как лучше визуализировать игровой мир и, надеюсь, решить проблему с камерой.


Во-первых, вы должны использовать видовой экран. Если вы поняли область просмотра, она очень полезна, прежде чем она станет очень запутанной.

По сути, вы создаете область просмотра, чтобы определить, сколько вы увидите своего мира и как он влияет на содержимое вашего мира, когда у вас разные размеры экрана.

Он предоставляет различные типы видового экрана: StretchViewport, FitViewport, FillViewport, ScreenViewport и ExtendViewport. Подробнее о видовых экранах: https://github.com/libgdx/libgdx/wiki/Viewports

Создание видового экрана очень просто:

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

WORLD_WIDHT и WORLD_HEIGHT говорят, сколько "единиц" мы можем видеть в нашем мире, camera - это OrthographicCamera.

В методе update() мы должны сообщить окну просмотра, что размер экрана был изменен.

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

Теперь Viewport позаботится о размере контента, чтобы вы всегда видели большую часть мира, который вы определили в конструкторе Viewport. Более подробное описание работы Viewport: Мировые единицы Libgdx


Теперь к Screen. По сути, вы можете иметь только один активный экран одновременно, поэтому неправильно реализовывать Screen в классе Tile. LibGdx вызывает метод рендеринга активного экрана в вашем случае метод render() в PlayScreen. Но Tile - это не Screen, а всего лишь Box, который можно визуализировать. Поэтому Tile не нужно реализовывать Screen.


Класс Sprite содержит не только Texture или TextureRegion, но и то, где и как будет отображаться спрайт. Поэтому, когда у вас есть 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();
Важно, что вы вызываете batch.begin(); только один раз в методе рендеринга. В вашем примере кода вы вызываете batch.begin примерно 26 раз, потому что вы также вызываете batch.begin в классе Tile, что, вероятно, происходит в исключении. В конце вашего метода рендеринга вы должны вызвать один раз batch.end();


Я надеюсь, что вся эта информация поможет решить вашу проблему, которая является проблемой камеры, как 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);
    }
}
...