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