вызов метода рендеринга из другого класса

1

Поэтому я пытаюсь сгенерировать сетку 5x5 с 2d массивом, но когда я пытаюсь вызвать метод 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() {

    }
}

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

Теги:
libgdx

1 ответ

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_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);
    }
}
  • 0
    Вау, спасибо большое, чувак, очень ценю, что ты нашел время, чтобы помочь мне понять это. Я дам это выстрел и обновлю вас!
  • 0
    Вы знаете, как я мог бы изменить изображение при нажатии? @ Морчул, спасибо большое!
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню