Rendering complete Tiled Map on Android with LibGdx - java

I am trying to render a Tiled Map on to an Android device. However, when I test it on my android phone, only the top layer is rendered on to the screen (out of two layers total). Is there a way to fix this? I am using Libgdx as well as Tiled Map Editor.
Below is some of the code for my project which implements the Screen interface. The omitted code is not necessary for the question but can be shown if needed.
public class Play implements Screen {
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.setView(cam);
renderer.render();
/*code ommited*/
renderer.getSpriteBatch().begin();
animateAgent(time);
sr.setProjectionMatrix(cam.combined);
try {
animateBullets(sr);
} catch(IndexOutOfBoundsException e) {}
renderer.getSpriteBatch().end();
}
public void show() {
cam = new OrthographicCamera();
cam.setToOrtho(false);
cam.position.set(0,0,0);
cam.zoom = 8.0f;
cam.update();
map = new TmxMapLoader().load("data/batMap.tmx");
blocked = (TiledMapTileLayer) map.getLayers().get(1);
renderer = new OrthogonalTiledMapRenderer(map);
atlas = new TextureAtlas("data/specOps.txt");
agent = atlas.createSprites("agent");
/* code ommitted */
player = new Player(agent,blocked,bullets);
Gdx.input.setInputProcessor(player);
}
}
Here's how it currently looks:
and here's how it should look:

You are only getting one layer at
blocked = (TiledMapTileLayer) map.getLayers().get(1);
or are you getting the other layer elsewhere?

Try:
map.getLayers().get(0).setVisible(true);
map.getLayers().get(1).setVisible(true);

Related

Libgdx Software Design

I am building a libgdx game, and I am not sure what tools are available right now.I have a folder with actors and I do all the logic inside those actors, but I have to add them manually to the stage, is there any way I can load all those actors at once.
public class ConfigureUI extends Stage {
private RuvikEngine ruvikEngine;
private OrthographicCamera camera;
public ConfigureUI(ScreenViewport viewport, RuvikEngine engine, OrthographicCamera camera) {
super(viewport);
this.ruvikEngine = engine;
this.camera = camera;
configure();
}
private void configure() {
//TODO make a scalable UI class system,so we can load each UI component independently
TextureActor actor = new TextureActor("move.png");
TextureActor reset = new TextureActor("reset.jpg");
Image image = new Image(actor.texture);
Image resetimg = new Image(reset.texture);
image.setPosition(225, 0);
this.addActor(image);
this.addActor(resetimg);
image.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
GameUIState.getInstance().setPAN_MODE(!GameUIState.getInstance().isPAN_MODE());
super.clicked(event, x, y);
}
});
resetimg.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
ruvikEngine.clearBodyArray();
ruvikEngine.addBody(new Body(new Vector2(1920 / 2, 1080 / 2), new Vector2(0, 0), 1000));
camera.position.set(GameUIState.getInstance().width / 2, GameUIState.getInstance().height / 2, 0);
camera.zoom = 0.1f;
camera.update();
super.clicked(event, x, y);
}
});
}
}```
If you are looking for a Visual Editor like unity. Sorry but libgGdx doesn't have one.
But if you want some framework to make your game more easily.
You can take a look to Autumn Mvc a spring like framework you will permit you to make your game menu rapidly.
And who will add Ioc to your stack. Who can simplify your code greatly
I never use it myself because i don't need it but this can be a good solution.

TiledMap not rendering

I am trying to render an OrthogonalTiledMap I created using the map editor Tiled however for some reason nothing is showing up in my game screen; all I get is a black image being shown. I am using the Libgdx framework which has features for exactly these kinds of maps already built in however they won't work for me.
Libdgx also provides an example of rendering OrthogonalTiledMaps however it is outdated but I adjusted it to current Libdgx version but as already stated it doesn't work.
There are no errors nor exceptions being thrown. The .tmx file does also not contain any errors. All the used tileset are present and do not cause any errors.
This is my code:
`
public class My_Game extends ApplicationAdapter {
private TiledMap map;
private TiledMapRenderer renderer;
private OrthographicCamera camera;
private CameraInputController cameraController;
#Override
public void create () {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(true, w/8f, h/8f);
camera.update();
cameraController = new CameraInputController(camera);
Gdx.input.setInputProcessor(cameraController);
map = new TmxMapLoader().load("map.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1f / 8f);
}
#Override
public void render () {
camera.update();
renderer.setView(camera);
renderer.render();
}
#Override
public void dispose () {
map.dispose();
}
}`
Was a while since I did Libgdx so I might be thinking of something else, but don't you have to do some clearing in the render() function?
Try adding:
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
as the first three lines there and let me know if that helps.

Adding rayhandler in LibGDx causes issues in InputListener

I am trying out Libgdx, and I have an actor which performs some action whenever we click on it. So far it is working fine. Now I want to add light to the actor. After doing some research I came across Box2DLights. When I tried adding it to my project onClick Actor which was working fine does not seem to work. I am pretty sure this is due to rayhandler/Box2DLights because that is the only change I am making. here is the minimal change that I made to include Box2DLights.
public class GameScreen implements Screen {
private RayHandler rayHandler;
private World world;
public GameScreen(Game game) {
this.game = game;
world = new World(new Vector2(0, 0), true);
rayHandler = new RayHandler(world);
rayHandler.setAmbientLight(0.1f, 0.1f, 0.1f, 1f);
rayHandler.setBlurNum(3);
}
#Override
public void show() {
viewport = new FitViewport(1080, 720);
stage = new Stage(viewport);
rayHandler.setCombinedMatrix(stage.getCamera().combined);
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
//some custom rendering logic, but nothing related to rayHandler, excluding this for brevity.
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
rayHandler.updateAndRender();
}
Now When I debugged, I realised the the onClick is
working little below the actual actor
, that means somehow the coordinates sifted(I know weird).
Can you please help?
Thanks #Mikhail Churbanov for your response here.
If somebody else stumbles on this again here is the solution which worked.
viewport = new FitViewport(1080, 720);
rayHandler.useCustomViewport(viewport.getScreenX(),
viewport.getScreenY(),
viewport.getScreenWidth(),
viewport.getScreenHeight());
The explaination is box2lights doesn't auto-acquire custom viewports, and restores the 'default one' after the updateAndRender called - your need to set your custom 'fitted' viewport to rayHandler so that it would restore it correctly- using the rayHandler.useCustomViewport(...) method.
All credits to #mikahi churbanov

Libgdx reducing calls and optimize the game

Am trying to reduce number of calls being made everytime a Screen is called on my game in a bid to make my game faster and I noticed I do alot the same calculation on every screen..how can i avoid this?
I do this in practically every screen
public class ****Screen implements Screen {
#Override
public void show() {
float screenWidth = Gdx.graphics.getWidth();
float screenHeight = Gdx.graphics.getHeight();
float gameWidth = 360;
float gameHeight = screenHeight / (screenWidth / gameWidth);
midPointY = (int) (gameHeight / 2);
cam = new OrthographicCamera();
cam.setToOrtho(true, gameWidth, gameHeight);
viewport = new FitViewport(gameWidth, gameHeight, cam);
viewport.apply();
stage = new Stage(viewport);
Gdx.input.setInputProcessor(stage);
yet I have a GameClass..How can I implement the above in my gameclass(below) and only have to call it once?...
public class Start extends Game {
#Override
public void create() {
float screenWidth = Gdx.graphics.getWidth();
float screenHeight = Gdx.graphics.getHeight();
float gameWidth = 360;
float gameHeight = screenHeight / (screenWidth / gameWidth);
assets = new AssetLoader();
assetManager = new AssetManager();
camera = new OrthographicCamera();
camera.setToOrtho(true, gameWidth, gameHeight);
//initialize screens here
mainMenu = new MenuScreen(this);
loadingScreen = new LoadingScreen(this);
gameScreen = new GameScreen(this);
.......
//call assets
AssetLoader.load();
//start mainmenu...
this.setScreen(mainMenu);
}
First i have to tell you actualy this wont speed up your game.
If you change screen every 20 seconds then that means game does calculations 1 frame per 1200 frames.
However i am same like you and really looking for most optimize ways while doing game.
I found a solution for this case.
You can pass objects that you use in all screens, from game class to screen class.
Screen class
public class MainMenuScreen implements Screen {
public MainMenuScreen(OrthographicCamera camera) {
this.camera=camera;
}
//...Rest of class omitted for succinctness.
}
Game class
public class Starts extends Game {
OrthographicCamera camera;
public void create() {
camera=new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
this.setScreen(new MainMenuScreen(camera));// change screen and pass camera to new screen.
}
}
Or you can even pass the whole game class like this.
public class MainMenuScreen implements Screen {
final Starts game;
public MainMenuScreen(final Starts game) {
this.game = game;
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
game.camera.update();
game.batch.setProjectionMatrix(game.camera.combined);
game.batch.begin();
game.font.draw(...);
game.font.draw(...);
game.batch.end();
if (Gdx.input.isTouched()) {
game.setScreen(new AnotherScreen(game));
dispose();
}
}
}
just need to call like this in game class. So you can use stage batches fonts etc. of game in all screens.
this.setScreen(new MainMenuScreen(this));
I assume you mean you want to shorten the little hiccup you get when switching screens. (Your game's frame rate is not affected by this.)
Easy way: move that code from show to the constructor of each screen class.
However, it is wasteful to be creating a new Stage for each Screen without passing it a SpriteBatch, because you are essentially instantiating three separate SpriteBatches, which are heavy objects (they have a big array for the mesh data, a big mesh on the GPU, and have to compile a shader).
You can instantiate shared objects in your Game class and pass them into the constructors of your Screens like this:
public class Start extends Game {
SpriteBatch spriteBatch;
#Override
public void create() {
//...
//initialize screens here
spriteBatch = new SpriteBatch(); //must be disposed in dispose()
mainMenu = new MenuScreen(this, spriteBatch);
loadingScreen = new LoadingScreen(this, spriteBatch);
gameScreen = new GameScreen(this, spriteBatch);
//...
}
}
Update your Screens' constructors accordingly and pass the sprite batch into the stage constructors. Viewports and cameras are lightweight, so I wouldn't bother with moving those up to the Game class unless it helps make your code more maintainable.
By the way, you're kind of abusing FitViewport by pre-calculating the aspect ratio. The point of Viewports is that you don't need to calculate anything when setting up. Use new ExtendViewport(360, 1, cam) to get the same thing you're doing without the calculations. And make sure you're updating it in resize().

LibGDX - how do I make my text centered?

I'm new to LibGDX and I am taking it slowly. I'm still trying to understand most things which is why typically google searches don't help due to the fact that their too complicated. I have a main menu that has text that I want centered no matter what the screen size is. Here is the code that I have for that menu.
public class Menu implements Screen {
SlingshotSteve game;
OrthographicCamera camera;
public Menu(final SlingshotSteve gam) {
this.game = gam;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.font.draw(game.batch, "Welcome to Slingshot Steve!!! ", 100, 150);
game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
game.batch.end();
if (Gdx.input.isTouched()) {
game.setScreen((Screen) new GameScreen(game));
dispose();
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
}
I'm here to save you!
To get width / height from a String drawn with your BitmapFont you can utilize this super nice method:
game.font.getBounds(String string)
And to use it in your case, it would be something like this:
game.font.getBounds("Tap anywhere to begin!").width / 2;
Cheers!
It is possible to do it the way Nine Magics suggested, however one would usually do it via a Stage, which is part of scene2d.
More specifically one would use scene2d.ui which is a bunch of Actors like Button, Image, Label etc. You can attach a ClickListener to a Button for example and react on this event.
Furthermore, for layouting there is one very powerful Actor, namely Table which you can very easily use to center things on the screen.
Some very minimalistic code:
// do this once, in create() or show()
Skin skin = new Skin("uiskin.json"); // get the demo skin from the libgdx test resources
Stage stage = new Stage();
Table table = new Table(skin);
table.add("Welcome to Slingshot Steve!!!");
table.row();
table.add("Tap anywhere to begin!");
stage.addActor(table);
// do this in your render loop
stage.act();
stage.draw();
You can find the "default" skin resources here. You need to get all the uiskin.* files.

Categories