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.
Related
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.
On my 854 x 480 LG Leon it renders fine, but on a larger screen resolution (2560 x 1440) this happens: http://imgur.com/a/rcbJK.
The code for processing the text is: http://imgur.com/a/c316e.
I've tried expanding the bounds of the Label because I thought that it might be constricting the text, but it still won't display properly.
What could be causing this?
The different mobile phone has the different aspect ratio in their screen size . that is the reason it shows different different screen. to avoid this problem you must use the viewPort. So you will be able to handle the different screen size. for more details, you must read the libgdx documentation. here I'm posting a sample code which can help you to handle the different screen size. there are three kinds of viewports mainly using
1) fillviewport
2) fitviewPort
3)stretchviewport
here is the documentation in detail.
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/viewport/FillViewport.html
public class myGame extends ApplicationAdapter {
public OrthographicCamera camera;
public Viewport viewPort;
private SpriteBatch batch;
public myGame() {
}
#Override
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
camera.setToOrtho(false, 1280, 800);
viewPort = new FillViewport(1280, 800, camera);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
float deltaTime = Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(sprie,0,0)
batch.end();
}
#Override
public void resize(int width, int height) {
viewPort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
// don't copy paste it . just try to understand and implement it.
You should use Scene2D and ViewPort.
Also , be careful to use coordinates (i.e : x: 64 , y:32 changes in every different screen size)
This is the common issue when your running your game in multiple devices. Because your game is running in different aspect ratios in different screens . it's generally called the multi screen issue. To solve this problem the libgdx is providing it's on class called the viewPort. Mainly you can see three viewpors.
1)Fill viewPort.
2)Fit viewPort.
3)stretch viewport.
For more details you can go through the libgdx documentation. Here im posting some example code which can solve your multi screen issues.
public class myGame extends ApplicationAdapter {
public OrthographicCamera camera;
public Viewport viewPort;
private SpriteBatch batch;
private BitmapFont myScoreFont;
//General screen resolution
public int APP_WIDTH=1280;
public int APP_HEIGHT=800;
public int fontPositionIn_X=600;
public int fontPositionIn_Y=400;
public myGame() {
}
#Override
public void create() {
myScoreFont = new BitmapFont(Gdx.files.internal(Constants.PATH_TO_MY_SCORE_FONT), true);
batch = new SpriteBatch();
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
camera.setToOrtho(false, APP_WIDTH, APP_HEIGHT);
viewPort = new fillViewPort(1280, 800, camera);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
float deltaTime = Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
myScoreFont.draw(batch,"any texts", fontPositionIn_X, fontPositionIn_Y)
batch.end();
}
#Override
public void resize(int width, int height) {
viewPort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
so by using the viewPort you can be able to play your game in all the different screens.
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().
The problem
I cannot seem to be able to get Tiled maps to render properly. I am using LibGDX as a library for loading the map (Release 1.6.0).
Video demonstration
I have created a video to show you the actual problem and make things easier by skipping the whole process of explaining it. Here is a link to it.
The code I've used
protected Level level;
protected OrthogonalTiledMapRenderer mapRenderer;
protected OrthographicCamera camera;
protected TiledMap map;
protected MainGameLoop game;
protected SpriteBatch batch;
private BitmapFont font;
private int w, h;
public Level1(MainGameLoop game) {
this.game = game;
}
#Override
public void show() {
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
int CAMERA_WIDTH = 800;
int CAMERA_HEIGHT = 450 * (w / h);
camera = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
camera.setToOrtho(false);
camera.update();
map = new TmxMapLoader().load("maps/map1.tmx");
mapRenderer = new OrthogonalTiledMapRenderer(map);
Gdx.input.setInputProcessor(this);
font = new BitmapFont();
font.setColor(Color.BLUE);
batch = new SpriteBatch();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
mapRenderer.setView(camera);
mapRenderer.render();
batch.begin();
font.draw(batch, "Camera zoom: " + camera.zoom, 40, 40);
batch.end();
}
#Override
public void resize(int width, int height) {
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
}
#Override
public void dispose() {
mapRenderer.dispose();
map.dispose();
background.dispose();
Gdx.input.setInputProcessor(null);
}
#Override
public boolean scrolled(int amount) {
camera.zoom += amount;
camera.update();
return true;
}
// Here go the rest of the methods, such as pause, resume, hide, keyDown, keyUp, keyTyped, touchDown, touchUp, touchDragged & mouseMoved.
Solutions I've tried
I have tried using different numbers for the camera's x and y with no luck. I have also tried tranlating the camera to the proper position (hardcoded it), as well as using another map (different tilemap and dimensions) but that did not work either.
Conclusion
I can't seem to find a way to fix this problem. Any help is much appreciated. Thank you very much.
Quick introduction
Ok after a good while, I managed to solve this matter by hardcoding some stuff. But it works properly, so I am happy with it.
What I did to solve the problem
First of all, I found out the exact number I had to use to scale up my Tiled map, which is this number: 3.125f .
Then, instead of using pixels for the camera, I used my own units (something I should have done from the the first moment).
After doing those two things, I noticed that the map was zoomed in a lot. So, by using the scrolled method from the InputProcessor, I managed to find the exact number the map had to be "unzoomed".
I also found out that if I call the setToOrtho(false) method from the OrthographicCamera object, it zooms the map in 19 times for some weird reason. If that method does not get called, the map is zoomed in only 1 time
The code I am currently using
TiledMap tiledMap;
OrthographicCamera camera;
TiledMapRenderer tiledMapRenderer;
final float WIDTH = 8000;
final float HEIGHT = 4500;
final float num = 3.125f;
#Override
public void show() {
tiledMap = MapLoader.realm1_level1;
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap, num);
camera = new OrthographicCamera(WIDTH, HEIGHT);
Gdx.input.setInputProcessor(this);
camera.zoom += 1f;
camera.update();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
tiledMapRenderer.setView(camera);
tiledMapRenderer.render();
}
// This method was just used for testing to see where
// the map was or should have been placed.
#Override
public boolean keyDown(int keycode) {
if (keycode == Input.Keys.LEFT)
camera.translate(-32, 0);
if (keycode == Input.Keys.RIGHT)
camera.translate(32, 0);
if (keycode == Input.Keys.UP)
camera.translate(0, 32);
if (keycode == Input.Keys.DOWN)
camera.translate(0, -32);
if (keycode == Input.Keys.NUM_1)
tiledMap.getLayers().get(0).setVisible(!tiledMap.getLayers().get(0).isVisible());
return true;
}
#Override
public void resize(int width, int height) {
camera.position.set(WIDTH, HEIGHT, 0);
camera.update();
}
#Override
public boolean scrolled(int amount) {
camera.zoom += amount;
camera.update();
return true;
}
#Override
public void dispose() {
tiledMap.dispose();
}
// And here go the rest of the methods that come from the
//Screen and the InputProcessor interfaces.
Notes
The numbers I used for the WIDTH and the HEIGHT variables work properly, strictly with tiled maps that their width is 80 tiles, and their height is 45 tiles.
If you are facing the same problem, you'll have to find the appropriate number to scale your map up/down, depending on the unit numbers you're using. Trial and error is your only guide. If we ignore StackOverflow of course.
I am creating an Android Game using LibGdx. It is a platformer and the map is tiled based. To test the movements of the player I used Key inputs and the desktop version of the game works fine. I created some buttons in scene2d and added them as an actor to the scene so that the game has movement buttons when played on Android devices. The buttons work as "System.out.print" shows. Problem is: the buttons and the player are each created in a different class. I can't seem to modify the velocity (and so the movement) of the Player from the class that holds the buttons. For that I need to change the velocity and speed etc. to static, which gives me strange errors on an Android device (Player won't show, or disappears after a frame). I am not sure how to fix this and what is the actual cause of this error. Here is some of the code of the different Classes:
Main Class (MyGdxGame) only included one button as an example.
public class MyGdxGame extends Game implements ApplicationListener {
private Skin skin;
private Stage stage;
#Override
public void create() {
setScreen(new Play());
skin = new Skin(Gdx.files.internal("ui/defaultskin.json"));
stage = new Stage();
Gdx.input.setInputProcessor(stage);
//Button Right
TextButton buttonRight = new TextButton("Right", skin, "default");
buttonRight.setWidth(50f);
buttonRight.setHeight(50f);
buttonRight.setPosition(Gdx.graphics.getWidth() /2 - 250f, Gdx.graphics.getHeight()/2 - 200f);
buttonRight.addListener(new ClickListener(){
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
System.out.println("Hold");
return true;
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
System.out.print("Released");
}
});
stage.addActor(buttonRight);
}
Play Class
public class Play implements Screen {
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private OrthographicCamera camera;
private Player player;
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.position.set(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, 0);
camera.update();
renderer.setView(camera);
renderer.render();
renderer.getSpriteBatch().begin();
player.draw(renderer.getSpriteBatch());
renderer.getSpriteBatch().end();
}
#Override
public void resize(int width, int height) {
camera.viewportWidth = width;
camera.viewportHeight = height;
}
#Override
public void show() {
map = new TmxMapLoader().load("maps/map.tmx");
renderer = new OrthogonalTiledMapRenderer(map);
camera = new OrthographicCamera();
player = new Player(new Sprite(new Texture("data/jack2.png")), (TiledMapTileLayer) map.getLayers().get(0));
player.setPosition(2 * player.getCollisionLayer().getTileWidth(), 10 * player.getCollisionLayer().getTileHeight());
}
Player Class
public class Player extends Sprite implements InputProcessor{
// the movement velocity //
public Vector2 velocity = new Vector2();
public float speed = 60 * 2, gravity = 60 * 1.8f;
private boolean canJump;
private TiledMapTileLayer collisionLayer;
private String blockedKey = "blocked";
public Player(Sprite sprite, TiledMapTileLayer collisionLayer){
super(sprite);
this.collisionLayer = collisionLayer;
}
#Override
public void draw(SpriteBatch spriteBatch) {
update(Gdx.graphics.getDeltaTime());
super.draw(spriteBatch);
}
So the button has a working ClickListener, but I don't know how it can modify the players velocity. Any help is welcome.
You just need to have some way to access that player instance from the class containing the button. In my games I make a static World class which can be accessed from anywhere in the program. Through the world class I can access the player instance. That's just how I do it, you may find another way. You say your program has errors on android device when making certain parameters static? Do you mean it compiles but it just doesn't work the way you expect? If that's the case, there is probably just a bug in how you're modifying the position or velocity of the player.