Libgdx Fitting screen - libgdx

My game has 2 black bars on the side on mobile. I have tried to make it fit with FitViewport and it should fit the screen as the game is a platformer and scrolls sideways so should always fit the screen in terms of width so i dont know why there is 2 black bars. I just wanted some help on how to fix this problem and to get it filling the full screen on all general screen sizes. Thanks alex.
public static final float V_WIDTH = 2234;
public static final float V_HEIGHT = 1400;
public PlayScreen(MarioBros game) {
this.game = game;
gameCam = new OrthographicCamera();
gamePort = new FitViewport(MarioBros.V_WIDTH / MarioBros.PPM , MarioBros.V_HEIGHT / MarioBros.PPM , gameCam);

Alex, go with StretchViewport:
public PlayScreen(MarioBros game) {
this.game = game;
gameCam = new OrthographicCamera();
gamePort = new StretchViewport(MarioBros.V_WIDTH / MarioBros.PPM , MarioBros.V_HEIGHT / MarioBros.PPM , gameCam);

Related

Sprite appearing in top right corner of the screen in LIBGDX

I am working on a game using LIBGDX. I am following tutorial from this . Everything works perfectly fine but my output sprite is at the top right corner of the screen. I am trying to center it around but I am not able to ! I even adjusted the camera but I failed.
This is my part of screen code,
public PlayScreen(MyGame game) {
this.game = game;
this.gamecam = new OrthographicCamera();
this.gamePort = new FitViewport(MyX.V_WIDTH / MyXGame.PPM, MyX.V_HEIGHT / MyXGame.PPM, gamecam);
this.hud = new HudClass(game.batch);
loader = new TmxMapLoader();
map = loader.load("tiledmap.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1 / MyJungleGame.PPM);
gamecam.position.set(gamePort.getWorldWidth() / 2, gamePort.getWorldHeight() / 2, 0);
world = new World(new Vector2(0, -10), true);
b2dr = new Box2DDebugRenderer();
creator = new B2WorldCreator(this);
gamehero = new Hero(this);
world.setContactListener(new WorldContactListener());
items = new Array<Item>(); //initializing things
itemsToSpawn = new LinkedBlockingQueue<ItemDef>();
}
My render method,
public void render(float delta) {
this.update(delta);
Gdx.gl.glClearColor(1, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.render();
b2dr.render(world, gamecam.combined);
game.batch.setProjectionMatrix(this.gamecam.combined);
game.batch.begin();
gamehero.draw(game.batch);
for (Goomba enemy : creator.getGoombas())
enemy.draw(game.batch);
for(Item item :items)
item.draw(game.batch);
game.batch.end();
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
}
I have attached the screen shot of the output .
To my knowledge, problem lies in setting up the camera in playscreen. But I don't know how to resolve it. Please help I am new to LIBGDX. Thanks in advance.
https://github.com/libgdx/libgdx/wiki/Orthographic-camera
This is the best help that I can give to you. Hope that it helps. Also, I would encourage you to write and design better you code, it is somehow a little bit hard to read.
Cheers.

Two stages with different viewports, how to remove blackbars between them

I have two stages, one for the background image (using FillViewport to stretch the image)
Another one use Fitviewport to display game objects.
How do I remove the blackbars to display the background of the first stage ?
I tried Extendviewport for second stages but it will show the gap at the right for 1280x720 devices (how could I split the gap to left ?)
public LoginScreen(final MyGame gam) {
game = gam;
stageBG = new Stage(new FillViewport(800, 480));
textureBackground = new Texture(Gdx.files.internal("background.png"));
stageBG.addActor(new Image(textureBackground));
stage = new Stage(new ExtendViewport(640, 480, 1280, 720));
table = new Table();
textureLoginArea = new Texture(Gdx.files.internal("login-area.png"));
textureGirlGreen = new Texture(Gdx.files.internal("girl-green.png"));
Gdx.input.setInputProcessor(stage);
table.setBounds(415, 15, 374, 459);
table.setBackground(new TextureRegionDrawable(new TextureRegion(textureLoginArea)));
stage.addActor(table);
}
#Override
public void render(float v) {
stageBG.act(Gdx.graphics.getDeltaTime());
stageBG.draw();
stage.act(Gdx.graphics.getDeltaTime());
stage.getBatch().begin();
stage.getBatch().draw(textureGirlGreen, 120, 0);
stage.getBatch().end();
stage.draw();
}
#Override
public void resize(int width, int height) {
stageBG.getViewport().update(width, height, true);
stage.getViewport().update(width, height, true);
}
I think you should avoid using two stages with different viewports. You will get into more trouble. If you want a background image with an login overlay you should just use scene2d. Or just use two stages with the same viewport and scale your overlay manually.
However you could use frame buffers with blending to overdraw the black bars.

Libgdx , When to use camera.position.set?

I am really confused with two examples related to viewport and orthagraphic. Although i understand that Viewport is the size of the dimensions we set to view on the screen and camera projects that. I am learning libgdx and cannot finish through orthographic camera and viewport examples which have left me completely confused. the code runs fine for both examples and with proper result on screen.
here's one example in which camera.position.set is used to position the camera.
public class AnimatedSpriteSample extends GdxSample {
private static final float WORLD_TO_SCREEN = 1.0f / 100.0f;
private static final float SCENE_WIDTH = 12.80f;
private static final float SCENE_HEIGHT = 7.20f;
private static final float FRAME_DURATION = 1.0f / 30.0f;
private OrthographicCamera camera;
private Viewport viewport;
private SpriteBatch batch;
private TextureAtlas cavemanAtlas;
private TextureAtlas dinosaurAtlas;
private Texture background;
private Animation dinosaurWalk;
private Animation cavemanWalk;
private float animationTime;
#Override
public void create() {
camera = new OrthographicCamera();
viewport = new FitViewport(SCENE_WIDTH, SCENE_HEIGHT, camera);
batch = new SpriteBatch();
animationTime = 0.0f;
...
...
..
camera.position.set(SCENE_WIDTH * 0.5f, SCENE_HEIGHT * 0.5f, 0.0f);
Here's another example which does not use camera.position.set and still the result is the same.
#Override
public void create() {
camera = new OrthographicCamera();
viewport = new FitViewport(SCENE_WIDTH, SCENE_HEIGHT, camera);
batch = new SpriteBatch();
oldColor = new Color();
cavemanTexture = new Texture(Gdx.files.internal("data/caveman.png"));
cavemanTexture.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
}
#Override
public void dispose() {
batch.dispose();
cavemanTexture.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(BACKGROUND_COLOR.r,
BACKGROUND_COLOR.g,
BACKGROUND_COLOR.b,
BACKGROUND_COLOR.a);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
int width = cavemanTexture.getWidth();
int height = cavemanTexture.getHeight();
float originX = width * 0.5f;
float originY = height * 0.5f;
// flipX, flipY
// Render caveman centered on the screen
batch.draw(cavemanTexture, // Texture itselft
-originX, -originY, // pass in the world space coordinates where we to draw, Considering the camera is centered at (0,0). by default we need to position
// out cavement at -originX, -originY.
originX, originY, // coordinates in pixels of our texture that we consider to be the origin starting from the bottom-left corner.
// in our case, we want the origin to be the center of the texture. then we pass the dimensions of the texture and the scale
// and the scale along both axes (x and Y).
width, height, // width, height
WORLD_TO_SCREEN, WORLD_TO_SCREEN, // scaleX, scaleY
0.0f, // rotation
0, 0, // srcX, srcY
width, height, // srcWidth, srcHeight
false, false); // flipX, flipY
What is really confusing me is why does it not use camera.position.set on the second example to adjust the camera's view and why is it important to use this on the first example.
I really hope this question is legit and makes sense. I have searched the forum here and couldnt find any clues. Hope someone can guide in the right direction.
Many Thanks.
In the first example a 2 dimensional vector has been initialized for the position of the camera the x direction and the y direction. This for the specifically the camera.
camera = new OrthographicCamera();
So, this code creates a camera object from the OrthographicCamera class created by libgdx creators. Check out the documentation for the class here from that class you can see when that it is constructed it accepts both the viewport_height and viewport_width. (in your example you've left it blank, so these are 0 for the time being.)
viewport = new FitViewport(SCENE_WIDTH, SCENE_HEIGHT, camera);
This line of code defines the width, height and which camera should be used for the viewport. check out the documentation for FitViewport class here
So when camera.position.set is called, it sets for the x and y direction based on the viewport's width and height. This whole example defines the viewport dimensions for the overall viewport.
The difference between this and the second example is that the camera is set around the texture that has been loaded onto the screen. So the viewport's x and y direction has been positioned and the width, height, originX, originY of the texture/camera has been defined also:
int width = cavemanTexture.getWidth();
int height = cavemanTexture.getHeight();
float originX = width * 0.5f;
float originY = height * 0.5f;
Libgdx then allows you to draw the texture using the spritebatch class to draw both the texture and the viewport surrounding that texture.
Summary
Example one allows you to define a viewport on it's own, without any textures being drawn. This will allow you to draw multiple textures with the same viewport being set (a normal process of game creation)
But in Example two if you wanted the viewport to say, follow the main character around on the screen. you can define the viewport surrounding the texture to thus follow that texture.
Personally, i'd always pursue the first example as you can define a viewport for any game width or height and then i'd create a second viewport ontop to follow any textures i've drawn on the screen. They both work, just for different reasons.
Hope this helps you clear things up.
Happy coding,
Bradley.

How to make the camera follow the player?

I'm making a game in libgdx which includes the player being able to move vertically beyond the set screen size.
As for my question, if I have the screen size set at a certain width and height, what is required to make the actual game world larger for the camera to follow the player?
This is of course my targeted screen size in the Main game class:
public static final int WIDTH = 480, HEIGHT = 800;
Below that I currently have :
public static final int GameHeight = 3200;
GameHeight is the value I test for whether the player is going out of bounds.
Here is the problem. With this code, the player is centered on the screen, and moves horizontally, rebounding off the screen bounds (As it would without the camera, but neglecting the change in y-position)
public GameScreen(){
cam = new OrthographicCamera();
cam.setToOrtho(false, 480, 800);
}
#Override
public void render(float delta) {
// TODO Auto-generated method stub
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.position.y = player.getPosition().y;
cam.update();
batch.setProjectionMatrix(cam.combined);
player.update();
player.draw(batch);
}
If I remove:
cam.position.y = player.getPosition().y;
The camera is placed at the bottom of the virtual world and the ball starts at the top (y = 3200) and travels downward. When it reaches y = 800, it shows up as it should.
I've found a lot of examples that indicate in writing that setting the cameras position to the players y position should force the camera to follow the player, whether it's moving up or down, but it either freezes y movement or sets the camera at the bottom the virtual world.
Any help is appreciated, thanks!
I would try doing cam.position.set(player.getPosition().x, player.getPosition().y). This will make the camera follow your player and it should not cause any "freezing."
private val worldTransform = Matrix4()
private val cameraPosition = Vector3()
private val objPosition = Vector3()
private var rot = Quaternion()
private var carTranslation = Vector3(0f, 0f, 0f)
fun focus(obj: BulletObject) {
// worldTransform
obj.entity?.motionState?.getWorldTransform(worldTransform)
// objPosition
worldTransform.getTranslation(objPosition)
obj.entity?.modelInstance?.transform?.getTranslation(carTranslation)
// get rotation
worldTransform.getRotation(rot)
println("rot.angle: ${rot.getAngleAround(Vector3.Y)}")
val rad = Math.toRadians(rot.getAngleAround(Vector3.Y).toDouble())
// pointFromCar
val pointFromCar = Vector2(-3f * sin(rad.toFloat()), -3f * cos(rad.toFloat()));
cameraPosition.set(Vector3(objPosition.x + pointFromCar.x, objPosition.y + 1f, objPosition.z + pointFromCar.y))
// camera set position
camera.position.set(cameraPosition)
camera.lookAt(objPosition)
camera.up.set(Vector3.Y)
camera.update()
}

How do I extend the ViewPort and use it to paint a "window" of 3D graphics on the screen

I need to create a 3D perspective camera viewport of 480x480 and display it on the bottom right corner of the screen. The rest of the screen is filled with 2D graphics.
I tried extending Viewport and using viewportX, and viewportY as well as viewportHeight and viewportWidth, but the test 3D object does not draw.
I followed this tutorial to get the basic prototype going.
https://code.google.com/p/libgdx-users/wiki/Decals
How do I properly extend the ViewPort and use it to paint a "window" of 3D graphics on the screen ?
The following could be used to have a Viewport with a fixed size of 480x480 which is placed on the bottom left corner. If you supply a PerspectiveCamera to it, everything will be rendered in this area.
public class CustomViewport extends Viewport {
public CustomViewport (Camera camera) {
this.camera = camera;
}
#Override
public void update (int screenWidth, int screenHeight, boolean centerCamera) {
viewportX = 0;
viewportY = 0;
viewportWidth = 480;
viewportHeight = 480;
worldWidth = 480;
worldHeight = 480;
super.update(screenWidth, screenHeight, false);
}
}
If you want to render somewhere else after that, you have to "reset" the glViewport() via Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Now you are free to render whereever you want, for example in the top and right areas which were left blank.
This test shows another example of how to render in those areas.