LibGDX Screen Support Sizes in Android - java

I'm trying to create a game with LibGDX. My problem comes when I put the background in the screen that I have. I created a Base Screen (abstract) in order to make easier. In Desktop, the screen fits good, but in Android, trying different devices, the screen doesn't scale to full screen. I solved this situation using the next easy code:
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(texture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.end();
}
That was enough to see my game in full screen on android devices. Now, I want to use Scene2D(which I don't know so much...) So I create a Stage, I'm dealing with the background like an actor. Here's my code.
public class MenuScreen extends BaseScreen {
private FitViewport viewport;
private Stage stage;
private Image imageFondo, imagePrueba;
//private float escala;
public MenuScreen(MissingWords missingwords) {
super(missingwords);
}
#Override
public void show() {
//viewport = new StretchViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
viewport = new FitViewport(800, 480);
stage = new Stage(viewport, missingwords.getSB());
//Gdx.input.setInputProcessor(stage);
/* Crear fondo */
imageFondo = new Image(missingwords.getAM().get("fondo.png", Texture.class));
stage.addActor(imageFondo);
imagePrueba = new Image(missingwords.getAM().get("prueba.png", Texture.class));
imagePrueba.setPosition(50, 50);
stage.addActor(imagePrueba);
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
However, it doesn't work and I don't know if I'm using the Viewports in the correct way. How can I write this line in order to be compatible with Scene 2D and support android devices?
batch.draw(texture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Thanks in advance.

Finally I "solved" it using a ScalingViewport. Like this:
viewport = new ScalingViewport(Scaling.stretch, 800, 480);
Scaling.stretch as javadoc says: the world is scaled to take the whole screen. So, it doesn't keep the aspect ratio but for me is good. Maybe it looks wrong using large screens, but I'm still learning and I don't know if this is the best solution. So, I hope this helps someone.

Related

libGDX: size of object in FitViewport is distorted

My goal is to create a game that is always displayed with an aspect ratio of 9:16 (basically 16:9, but upright) using FitViewport; it should be independet of a target device's resolution. In order to test this setup, I created the following minimal working example. A small green square indicates the origin of the coordinate system:
MyGame.java
public class MyGame extends ApplicationAdapter {
final int WORLD_WIDTH = 900;
final int WORLD_HEIGHT = 1600;
Stage stage;
Viewport vp;
public void create() {
stage = new Stage();
vp = new FitViewport(WORLD_WIDTH, WORLD_HEIGHT, stage.getCamera());
stage.setViewport(vp);
stage.addActor(new MySquare());
}
public void render() {
stage.act();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
}
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
// dispose...
}
MySquare.java
public class MySquare extends Actor {
ShapeRenderer renderer = new ShapeRenderer();
#Override
public void draw(Batch batch, float alpha){
batch.end();
renderer.begin(ShapeRenderer.ShapeType.Filled);
renderer.setColor(Color.GREEN);
renderer.rect(0, 0, 50, 50);
renderer.end();
batch.begin();
}
}
Unfortunately, the result is not as expected: As you can see, the green square is actually not a square. This behavior is the same for both Windows and Android (in landscape mode):
However, when setting the size of the window programmatically and explicitly via LwjglApplicationConfiguration in DesktopLauncher.java to a valid 9:16 resolution, the green square is displayed correctly. Why is that and how can I avoid this workaround (which does not work for Android anyway)?
Your problem is that your shape renderer is ignoring the camera. Update it like this:
public void draw(Batch batch, float alpha){
batch.end();
renderer.setProjectionMatrix(batch.getProjectionMatrix()); // <<<<< Add this
renderer.begin(ShapeRenderer.ShapeType.Filled);
renderer.setColor(Color.GREEN);
renderer.rect(0, 0, 50, 50);
renderer.end();
batch.begin();
}
If you are planning to eventually use sprites, and you're simply wanting rectangle placeholders for your actors, you don't need a custom actor for this. You can use a generic Actor and call setDebug(true) on it, and Stage will automatically draw its outline using an internal ShapeRenderer. Of course, you must first set a size and position on the Actor.

libGDX camera not translating

I have a camera in my GameStage class and am trying to translate the camera when the left or right arrow keys are pressed. When I press either key and print the camera x position it changes, but nothing moves (actors on screen stay in the same position). What am I doing wrong?
Screen Render Method:
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(255, 255, 255, 255);
gameStage.update();
gameStage.draw();
gameStage.act(delta);
}
Stage Code Involving the Camera:
public GameStage() {
super(new ScalingViewport(Scaling.stretch, Lib.WIDTH, Lib.HEIGHT, new OrthographicCamera(Lib.WIDTH, Lib.HEIGHT)));
initCamera();
Gdx.input.setInputProcessor(this);
}
public void initCamera() {
camera = new OrthographicCamera(Lib.WIDTH, Lib.HEIGHT);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0f);
camera.update();
}
public void updateCamera() {
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
camera.translate(-5, 0);
} else if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
camera.translate(5, 0);
}
camera.update();
}
public void update() {
updateCamera();
}
Thanks :)
From you visible code I would say that the problem is you have two cameras.
One is created when you are calling super constructor. And one created manually. Even if you are translating the camera you created, for rendering batch will use stages camera.
Remove the camera you created and work only with stages camera.

Fit Viewport Black Bars

I'm currently developing a game where you have to avoid Asteroids. To make the Game look same on every device I use the FitViewport. Unfortunately I somehow get White Bars on the top and on the Bottom instead of Black ones. My Game Background is also white, so it looks a bit weird.
GameScreen:
#Override
public void create()
{
float aspectRatio = (float)Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
cam = new OrthographicCamera();
viewport = new FitViewport(MyGdxGame.WIDTH * aspectRatio, MyGdxGame.HEIGHT, cam);
[...]
}
#Override
public void render(SpriteBatch batch)
{
cam.update();
batch.setProjectionMatrix(cam.combined);
batch.begin();
em.render(batch); //render Ship and Asteroids
[...]
}
#Override
public void resize(int width, int height)
{
viewport.update(width, height);
cam.position.set(MyGdxGame.WIDTH / 2, MyGdxGame.HEIGHT /2, 0);
}
I dragged the Ship into the white Bar.
LibGDX provides viewports as a more convenient way of dealing with different aspect ratios. You don't have to multiply MyGdxGame.WIDTH with aspectRatio. Just initialize it with MyGdxGame.WIDTH and MyGdxGame.HEIGHT.
Also, in resize function, you can change the cam position using viewport values (instead of using constants):
cam.position.set(cam.viewportWidth / 2, cam.viewportHeight / 2, 0);
I found some issues in your code. for best practice while handling with the different screen ratio just try with the fill viewPort. Here is simply editing your code with the fill viewport . Just try it once.
#Override
public void create()
{
float aspectRatio = (float)Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
//1280 is the screen width and 800 is screen height
camera.setToOrtho(false, 1280, 800);
viewPort = new FillViewport(1280, 800, camera);
}
#Override
public void render(SpriteBatch batch)
{
batch.setProjectionMatrix(camera.combined);
batch.begin();
em.render(batch); //render Ship and Asteroids
[...]
}
#Override
public void resize(int width, int height)
{
viewPort.update(width, height);
}
just try with the above code . it will definitely work

Libgdx scaling background issue

So i am creating a game where i will draw a background but this background doesen't cover the whole screen, even when i lower the window size it doesen't cover the whole window. Here is the code for drawing the background:
Gdx.gl20.glClearColor(0.2F, 0.6F, 1F, 1F);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.update();
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(Assets.splash_spr_background, 0, 0);
sb.end();
And here is the code for initializing the sprite:
public static Texture splash_tex_background;
public static Sprite splash_spr_background;
public static void init()
{
splash_tex_background = new Texture(Gdx.files.internal("Splash Screen/background.png"));
splash_tex_background.setFilter(TextureFilter.Linear, TextureFilter.Linear);
splash_spr_background = new Sprite(splash_tex_background);
}
And finally here is the code for initializing the camera & spritebatch stuff:
cam = new OrthographicCamera();
cam.setToOrtho(false, 1920, 1080);
sb = new SpriteBatch();
Now here is my question: Why does this not work? What have i done wrong?
Thanks for any help! :)
You don't need 1920x1080 resolution for the game. That's clearly an overkill. Imagine that someone with a lower spec device will play it.
So you can just set the screen to match the background:
cam.setToOrtho(false, 1280, 720);
If you really need the resolution, you can stretch the background like this:
background.setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge);

Texture size with Libgdx

It may be a dumb question but I need a little help / explanations. I can't manage to resize correctly my textures when I resize the window in libgdx. I want to keep the aspect of my textures or have them at least reduced on a lower screen size, like on a mobile device. Here is a sample of my code, my original window size is 600*700 I tried a lot of things but nothing works :\
Can you help me ? Thanks in advance.
public class GameScreen implements Screen {
private World world;
private int ppxX, ppxY;
private SpriteBatch batch;
private OrthographicCamera camera;
private float cameraX, cameraY;
public GameScreen(World world) {
this.world = world;
camera = new OrthographicCamera();
}
public void show() {
batch = new SpriteBatch();
}
#Override
public void render(float delta) {
world.update(delta);
updateCamera();
ppxX = Gdx.graphics.getWidth() / 600;
ppxY = Gdx.graphics.getHeight() / 700;
Gdx.gl.glClearColor(0f, 0f, 0f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(world.getTexture(), 0, 0, ppxX, ppxY);
for (GameElement e : world.getListElements()) {
e.update(delta);
batch.draw(e.getTexture(), e.getPositionX()*ppxX, e.getPositionY()*ppxY, e.getWidth()*ppxX , e.getHeight()*ppxY );
}
batch.end();
}
You are on the right track, but there is couple of things you have to change.
Use ViewPorts
this.camera = new OrthographicCamera();
this.viewport = new FitViewport(WORLD_SIZE_X, WORLD_SIZE_Y, this.camera);
this.batch = new SpriteBatch();
this.batch.setProjectionMatrix(this.camera.combined);
Resize correctly.
#Override
public void resize(int width, int height) {
this.viewport.update(width, height);
}
Update the camera and render using World Units. Do not make the mistake of thinking in Screen Pixels.
public void render(float delta) {
this.camera.update();
this.batch.setProjectionMatrix(this.camera.combined);
this.batch.begin();
// draw using WORLD_SIZE
this.batch.end();
}

Categories

Resources