libgdx viewport fit different screens - libgdx

I'm having a problem with fitting my game on different screens.
I declared a viewport width and height in my stage class.
public static final int VIEWPORT_WIDTH = 20;
public static final int VIEWPORT_HEIGHT = 30;
And i set up the camera
camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
camera.position.set(camera.viewportWidth/2, camera.viewportHeight/2, 0f);
And i set the screen width and height in desktop app to this
public static final int APP_WIDTH = 800;
public static final int APP_HEIGHT = 900;
On desktop everything looks fine but on my android device it looks stretched upwards. I read the documentation about viewports but how can I implement it here using these variables? I know similar questions have been asked but I would like to know viewports can be implemented using these specific variables, that way I might understand it better.

You probably want to use an ExtendViewport. This extends the world 1 way to fill the entire screen.
your code would look something like this:
private Viewport viewport;
private Camera camera;
public void create() {
camera = new OrthographicCamera();
viewport = new ExtendViewport(VIEWPORT_WIDTH , VIEWPORT_HEIGHT, camera);
}
public void resize(int width, int height) {
viewport.update(width, height);
}
Read more here: https://github.com/libgdx/libgdx/wiki/Viewports#extendviewport

Related

Tile map (.tmx) rendering in the corner of the screen in LibGDX

I'm currently developing a game with my team on LibGDX and we're using a .tmx tile map. We're trying to get it to render, and it does render, but oddly in the corner of the screen instead of in the middle of the screen. As in, the bottom left corner of the map appears in the middle of the screen. I believe that at some point, we convince the program that the middle of the screen is x=0, y=0, because we set the initial position of our character (entity) to x=0, y=0, and it appears at the bottom left corner of the map (middle of the screen). I've worked on this problem for hours and I'm at a loss for what to do, especially since this is my first time using LibGDX.
Here's some of our code:
public class MyGame extends Game {
public static MyGame INSTANCE;
private OrthographicCamera cam;
public Viewport viewport;
public MyGame(){
INSTANCE = this;
}
#Override
public void create () {
cam = new OrthographicCamera();
cam.setToOrtho(false, 1130, 1130);
cam.update();
viewport = new Viewport(cam);
setScreen(viewport);
}
That's the MyGame class.
public class Viewport extends ScreenAdapter{
private OrthographicCamera camera;
private OrthogonalTiledMapRenderer orthogonalTiledMapRenderer;
private TileMapHelper tileMapHelper;
public Viewport(OrthographicCamera cameraIn){
camera = cameraIn;
tileMapHelper = new TileMapHelper(this);
orthogonalTiledMapRenderer = tileMapHelper.setupMap();
}
private void update(){
world.step(1 / 60f, 6, 2);
camera.update();
batch.setProjectionMatrix(camera.combined);
}
#Override
public void render (float delta) {
this.update();
orthogonalTiledMapRenderer.setView(camera);
orthogonalTiledMapRenderer.render();
batch.begin();
// render objects
batch.draw(img, player.getXLocation(), player.getYLocation());
batch.end();
camera.position.set(new Vector3(0, 0, 0));
}
That's the Viewport class. There's obviously more in those classes than that but I just included the things that have (or might have) something to do with the tile map.
Lastly, here's part of the TileMapHelper class.
public OrthogonalTiledMapRenderer setupMap(){
tiledMap = new TmxMapLoader().load("dungeon.tmx");
parseMapObjects(tiledMap.getLayers().get("Wall").getObjects());
return new OrthogonalTiledMapRenderer(tiledMap);
}
Before you ask about the parseMapObjects function, commenting it out changes nothing about how the code executes.
So basically, what's supposed to happen is the TileMapHelper loads the .tmx in its function setupMap(), the Viewport class calls setupMap (which returns an OrthogonalTiledMapEditor object) to initialize the OrthogonalTiledMapEditor, Viewport then sets the view and renders it, and MyGame is the one that initializes the camera and gives it to Viewport. Somewhere in that process something is going wrong and both the character and map are appearing in the middle/top corner of the screen like I explained earlier. Also, the reason I put the values 1130 in the setToOrtho function is because that was the only way to get the whole map to appear on the screen, but it's still in the corner.
Any help would be greatly appreciated.

Lwjgl3Application drawing perf degrades from 1.9.10 to 1.9.11

Hi I have a game that was using Lwjgl3Application with 1.9.10, after updating to 1.10.0 the drawing is noticeably worse on my 2014 macbook pro. You can tell the difference even when drawing a single texture. When texture are drawn, it looks like they are drawn in horizontal chunks, giving the illusion that drawing is lagging. The framerate via Gdx.graphics.getFramesPerSecond() is still ~60. On larger scenes, the weirdness in drawing is very apparent as large horizontal bands of artifacts going across the screen.
I used the project generator tool to make a scratch project to try and narrow it down, it looks like the degradation happens between 1.9.10 and 1.9.11.
In comparison, using LwjglApplication works just as well as before.
Below is the code, if running on a mac make sure to add the -XstartOnFirstThread VM arg to the desktop launcher otherwise it won't start.
public class DesktopLauncher {
public static void main (String[] arg) {
final Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
new Lwjgl3Application(new MyGdxGame(), config);
}
}
public class MyGdxGame extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
int posX, posY;
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(img, posX, posY);
batch.end();
// make texture move around a bit
posX++;
posY++;
if (posX >= Gdx.graphics.getWidth() - img.getWidth()) {
posX = 0;
posY = 0;
}
}
#Override
public void dispose () {
batch.dispose();
img.dispose();
}
}
Thanks

Couldn't load tmx

I'm using libgdx in my 2D platformer game project for college task. For now I'm confused with loading tiledmap in libgdx. I have a big tmx map with size of 11400x1500 pixels and 30x30 tile size. Also an image with same pixel size which I load it in image layer. I try to load it but libgdx shows nothing.
My question is how to load single big tmx map or should I divide the map into several segment/section? Because I've tried other small tmx (3000x1500). If the tmx is divided then how to load them as one stage?
public class Layarloh implements Screen{
private JumatUtama game;
private TiledMap map;
private TmxMapLoader mapLoader;
private OrthographicCamera kamera;
private OrthogonalTiledMapRenderer mapRenderer;
private Viewport viewport;
public Layarloh(JumatUtama utama) {
float l=Gdx.graphics.getWidth(),t=Gdx.graphics.getHeight();
this.game = utama;
loadstage();
kamera = new OrthographicCamera();
kamera.setToOrtho(false,l,t);
kamera.update();
viewport = new FitViewport(l/3,t/3,kamera);
}
public void loadstage(){
mapLoader = new TmxMapLoader();
map = mapLoader.load("stage/s11.tmx");
mapRenderer = new OrthogonalTiledMapRenderer(map);
}
public void stik(float dt){
if (Gdx.input.isKeyPressed(Input.Keys.ANY_KEY))
kamera.position.x +=100*dt;
}
#Override
public void render(float delta) {
stik(delta);
kamera.position.set(550,550,0);
kamera.update();
mapRenderer.setView(kamera);
mapRenderer.render();
}
#Override
public void resize(int width, int height) {
kamera.viewportWidth = viewport.getScreenWidth();
kamera.viewportHeight = viewport.getScreenHeight();
kamera.update();
}
Unitscale does nothing, the code above works on smaller size of tmx map.
EDIT
Code above isn't working, and the below is working, notice the maploader is loading different tmx file, above code trying to load 11400x1500 pixel with 30x30 tile size, while code below trying to load 3800x1500 with 30x30 tile size, but I try to use the code below to load bigger tmx, its not working,
public class Layarloh implements Screen{
private JumatUtama game;
private TiledMap map;
private TmxMapLoader mapLoader;
private OrthographicCamera kamera;
private OrthogonalTiledMapRenderer mapRenderer;
public Layarloh(JumatUtama utama) {
float l=Gdx.graphics.getWidth(),t=Gdx.graphics.getHeight();
this.game = utama;
loadstage();
kamera = new OrthographicCamera();
kamera.setToOrtho(false,l,t);
kamera.position.set(550,550,0);
kamera.update();
}
public void loadstage(){
mapLoader = new TmxMapLoader();
map = mapLoader.load("stage/segmen1.tmx");
mapRenderer = new OrthogonalTiledMapRenderer(map);
}
public void stik(float dt){
if (Gdx.input.isKeyPressed(Input.Keys.ANY_KEY))
kamera.position.x +=100*dt;
}
#Override
public void render(float delta) {
stik(delta);
kamera.update();
mapRenderer.setView(kamera);
mapRenderer.render();
}
Try this code and this should fix it.
#Override
public void render(float delta) {
kamera.position.set(x, y, z);
kamera.update();
mapRenderer.setView(kamera);
mapRenderer.render();
}
#Override
public void resize(int width, int height) {
kamera.viewportWidth = width;
kamera.viewportHeight = height;
kamera.update();
}
EDIT
In the original code, OP was missing kamera.update() statement. And also the resize method. That is something which causes trouble when displaying the tiled map properly as you need to update the camera at every iteration of render.

libGDX - FitViewport is stretching the stage

I am creating a game and I do not want my screen to be stretched when I resize my window (of course only if it can fit in the window). I am using a Stage object with a FitViewport but when I resize window, elements on it are being resized too. What am I doing wrong?
This is my Screen class:
public class SplashScreen implements Screen{
private final PuzzleGame app;
private Stage stage;
private Image splashImage;
public SplashScreen(final PuzzleGame app) {
this.app = app;
this.stage = new Stage(new FitViewport(PuzzleGame.V_WIDTH, PuzzleGame.V_HEIGHT, app.camera));
Gdx.input.setInputProcessor(stage);
Texture splashTex = new Texture(Gdx.files.internal("img/splash.png"));
splashImage = new Image(splashTex);
splashImage.setPosition(stage.getWidth() / 2, stage.getHeight() / 2);
stage.addActor(splashImage);
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(.25f, .25f, .25f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
update(delta);
stage.draw();
}
private void update(float delta) {
stage.act(delta);
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, false);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
stage.dispose();
}
}
As Tenfour04 already pointed out, you are looking for ScreenViewport.
You probably want to check out this question and then re-read the Viewports wiki article.
Basically, there are two different kind of viewports, the Camera and the OpenGL viewport.
FitViewport keeps the Camera viewport the same, but scales the OpenGL viewport up or down. The result will be that all sizes will appear to be bigger or smaller, depending on how much bigger or smaller the OpenGL viewport is, compared to the camera viewport.
ScreenViewport on the other hand keeps the camera viewport and the OpenGL viewport at the same size, which will result in elements always having the same size.

Incorrect click event when resize on libGdx

I want to use scene2D, in libGDX, to detect click on object.
I have this simple Game sample :
Stage stage;
#Override
public void create()
{
this.stage = new Stage(1280, 720, true);
MyActor actor = new MyActor();
Gdx.input.setInputProcessor(stage);
actor.setTexture(new TextureRegion(new Texture(Gdx.files.internal("plateau.jpg"))));
actor.setScale(0.1f);
stage.addActor(actor);
actor.addListener(new InputListener()
{
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
{
System.out.println("down"+Math.random());
return true;
}
});
}
#Override
public void render()
{
stage.act();
stage.draw();
}
MyActor is a simple class extending Actor with a rendertexture.
The Event is working fine at start.
But when resizing the frame, while the Actor is streched as wanted, the coordinates of the click are not updated and thus misplaced.
How to make the stage using the new size of the items as base to the event ?
You need to update the viewport of your stage in resize method of your application like this:
public void resize(int width, int height) {
stage.setViewport(stage.getWidth(), stage.getHeight(), false, 0, 0, width, height);
}
What worked for me was similar to what mentioned above but you have to modify it slightly:
public void resize(int width, int height) {
stage.getViewport().update(width, height);
}
You shouldn't use the Gdx.graphics.width and height but really use what resize() is providing to you.
You have to use camera.project() method for this purpose I think.
camera.project(Vector3 worldPoint);
Does this works for you?