Libgdx/java Performance crash with box2d light - java
Background Info
Hey guys i am currently working on a little rpg :) and today i tried to implement some easy light ....
Main Question
When i use Point light in my Project the fps will get slower and slower ... i have got a very good pc, so it cant be my gpu or cpu ... So what did i miss?
Heres an Screenshot
You can see in the left bottom corner the fps : 6.
By the way, i disabled vsync and my gpu is an gtx 960 ... so i dont really know why i have so low fps ...
Player class :
package Mobs;
public class Player {
AnimatedSprite animatedSprite;
SpriteBatch batch;
Light licht = new Light(Color.WHITE,500);
public int state = 0;
public int netState = 1;
float speed = 2f;
public Vector2 position = new Vector2(256,256);
public Vector2 networkPosition = new Vector2(0,0);
public Player(){
}
public void update(){
state = 0;
if(Gdx.input.isKeyPressed(Keys.A)){
position.x -= Gdx.graphics.getDeltaTime() * 100f;
state = 1;
//System.out.println(currentState);
}
if(Gdx.input.isKeyPressed(Keys.D)){
position.x += Gdx.graphics.getDeltaTime() * 100f;
state = 2;
//System.out.println(currentState);
}
if(Gdx.input.isKeyPressed(Keys.W)){
position.y += Gdx.graphics.getDeltaTime() * 100f;
state = 3;
//System.out.println(currentState);
}
if(Gdx.input.isKeyPressed(Keys.S)){
position.y -= Gdx.graphics.getDeltaTime() * 100f;
state = 4;
//System.out.println(currentState);
}
}
public void setX(float x){
position.x = x;
}
public void setY(float y){
position.y = y;
}
public void draw(float f, float g, OrthographicCamera camera){
position.x = f;
position.y = g;
//System.out.println("In beforeSetState : "+currentState);
animatedSprite.setState(state);
//System.out.println("In after : "+currentState);
animatedSprite.createAnimation();
camera.position.set(f,g,0);
camera.update();
licht.drawLight(camera, f+25 , g+25);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(animatedSprite.convertAnimationTOframes(),f,g, Gdx.graphics.getWidth()/25,Gdx.graphics.getHeight()/15);
batch.end();
}
public void doSetup(){
batch = new SpriteBatch();
animatedSprite = new AnimatedSprite();
}
public float getX(){
return position.x;
}
public float getY(){
return position.y;
}
}
And my "Light" class :
package Screen;
public class Light {
World world;
RayHandler rayHandler;
PointLight pointLight;
Body player;
Box2DDebugRenderer debugRenderer;
public Light(Color farbe, int radius) {
world = new World(new Vector2(0,0),false);
rayHandler = new RayHandler(world);
pointLight = new PointLight(rayHandler, 500 , farbe , radius, 0, 0);
pointLight.setSoftnessLength(0f);
debugRenderer = new Box2DDebugRenderer();
}
public void drawLight(OrthographicCamera playerCam, float x, float y){
world.step(1 / 60f, 8, 3);
debugRenderer.render(world, playerCam.combined);
pointLight.setPosition(x,y);
rayHandler.setCombinedMatrix(playerCam.combined);
rayHandler.updateAndRender();
}
public void removeLights(){
rayHandler.removeAll();
pointLight.remove();
}
}
Because i still got laggs, heres my MainClass :
public class LauncherScreen implements Screen{
//-----------------------------------------------------------
//-----------------idle Animation----------------------------
//-----------------------------------------------------------
Map duengon;
AnimatedSprite animationForMultiplayer;
SpriteBatch spriteBatch;
Player mySelf;
OrthographicCamera mpPlayerCam;
OrthographicCamera camera;
static Client client = new Client();
Launcher launcher = new Launcher();
int[][] map = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
#Override
public void render(float delta) {
// TODO Auto-generated method stub
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
launcher.update();
//------------------------------------------------------------------------
//------------------------Draws the Map-----------------------------------
//------------------------------------------------------------------------
duengon.ubdate(map, camera);
//------------------------------------------------------------------------
//------------------------Draws the Players-------------------------------
//------------------------------------------------------------------------
for(MPPlayer mpPlayer : launcher.getPlayersValue()){
animationForMultiplayer.setState(mpPlayer.state);
animationForMultiplayer.createAnimation();
camera.position.set(mpPlayer.x,mpPlayer.y,0);
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
spriteBatch.draw(animationForMultiplayer.convertAnimationTOframes(), mpPlayer.x, mpPlayer.y,Gdx.graphics.getWidth()/25,Gdx.graphics.getHeight()/15); // #6
spriteBatch.end();
System.out.println("mpPlayer : "+mpPlayer.x+" "+mpPlayer.y);
}
mySelf.update();
mySelf.draw(launcher.getPlayerX(), launcher.getPlayerY(), camera);
camera.update();
System.out.println(Gdx.graphics.getFramesPerSecond());
System.out.println("player : "+launcher.getPlayerX()+" "+launcher.getPlayerY());
}
#Override
public void show() {
// TODO Auto-generated method stub
animationForMultiplayer = new AnimatedSprite();
spriteBatch = new SpriteBatch();
mySelf = new Player();
mySelf.doSetup();
mpPlayerCam = new OrthographicCamera(0,0);
mpPlayerCam.setToOrtho(false);
camera = new OrthographicCamera(0, 0);
camera.setToOrtho(false);
duengon = new Map();
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
spriteBatch.dispose();
mySelf.doDispose();
animationForMultiplayer.doDispose();
duengon.doDispose();
}
}
The .doDispose() in my mainClass are methods which disposes the resource from the classes is use
Thanks for your help and your time :)
You are not disposing anything, you might want to look into the dispose() function of LibGDX
Here is the link
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/Disposable.html
if thats not the problem please let us know.
Related
libgdx world to screen pos and factors
I want to draw a texture on a body, which is a box. How do I convert the coordinates of the body to screen coordinates? I know that the other way around is with camera.unproject(pos), is it similar to this? I see a lot of people using constants such as WORLD_TO_SCREEN = 32, but I currently don't have that in my game. Is that a problem, and how can I implement it now? Because it seems like people that are using these factors can convert world to screen positions easily. I currently have a camera and an ExtendViewport camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); viewport = new ExtendViewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, camera); camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0f); Viewport width and height are set to this public static final int VIEWPORT_WIDTH = 20; public static final int VIEWPORT_HEIGHT = 22; I don't really know what I'm doing, I read documentation and read some tutorials, but if someone could give some explanation about these variables and the world_to_screen factor that would really help me out. I also set APP_WIDTH=1280, APP_HEIGHT = 720 Do viewport width and height mean that for box2d my screen is 20 meters wide and 22 meters high? (asking it again because I added a lot the question and I would really like to know these things) [EDIT] So I'm trying to draw a ground picture on the ground body float x = stage.getGround().getX(); float y = stage.getGround().getY(); float w = stage.getGround().getWidth(); float h = stage.getGround().getHeight(); stage.act(delta); stage.draw(); stage.updateCamera(); Texture texture = new Texture(Gdx.files.internal("ground.png")); Sprite sprite = new Sprite(texture); sprite.setSize(w, h); sprite.setPosition(x-sprite.getWidth()/2, y-sprite.getHeight()/2); But I don't see it anywhere [EDIT 2] Stage Class public class Mission1Stage extends Stage{ public static final int VIEWPORT_WIDTH = 20; public static final int VIEWPORT_HEIGHT = 22; private World world; private Ground ground; private LeftWall leftWall; private Rocket rocket; private static final float TIME_STEP = 1 / 300f; private float accumulator = 0f; private OrthographicCamera camera; private Box2DDebugRenderer renderer; private Viewport viewport; private SpriteBatch spriteBatch = new SpriteBatch(); private Vector3 touchPoint; private ShapeRenderer shapeRenderer; private Button boostButton; private Skin boostSkin; private Button boostLeftButton; private Skin boostLeftSkin; private Button boostRightButton; private Skin boostRightSkin; private Button resetButton; private Skin resetSkin; private Game game; private boolean isTouched = false; public Mission1Stage(Game game) { setUpWorld(); renderer = new Box2DDebugRenderer(); shapeRenderer = new ShapeRenderer(); setupCamera(); setUpButtons(); addActor(new Background(ground)); } private void setUpWorld() { world = WorldUtils.createWorld(); setUpGround(); setUpRocket(); } private void setUpGround() { ground = new Ground(WorldUtils.createGround(world)); addActor(ground); } private void setUpLeftWall() { leftWall = new LeftWall(WorldUtils.createLeftWall(world)); } private void setUpRocket() { rocket = new Rocket(WorldUtils.createRocket(world)); addActor(rocket); } private void setupCamera() { camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); viewport = new ExtendViewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, camera); camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0f); camera.update(); } private void setUpButtons() { boostSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); boostButton = new Button(boostSkin); boostButton.setSize(80,80); boostButton.setPosition(Gdx.graphics.getWidth()-boostButton.getWidth()*2,0); boostButton.setTransform(true); boostButton.scaleBy(0.5f); Gdx.input.setInputProcessor(this); addActor(boostButton); boostLeftSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); boostLeftButton = new Button(boostLeftSkin); boostLeftButton.setSize(100, 100); boostLeftButton.setPosition(0, 0); addActor(boostLeftButton); boostRightSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); boostRightButton = new Button(boostRightSkin); boostRightButton.setSize(100, 100); boostRightButton.setPosition(boostLeftButton.getWidth(), 0); addActor(boostRightButton); resetSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); resetButton = new Button(resetSkin); resetButton.setSize(100, 100); resetButton.setPosition(Gdx.graphics.getWidth()-100, Gdx.graphics.getHeight()-100); addActor(resetButton); } #Override public void act(float delta) { super.act(delta); handleInput(); accumulator += delta; while(accumulator >= delta) { world.step(TIME_STEP, 6, 2); accumulator -= TIME_STEP; } } #Override public void draw() { super.draw(); renderer.render(world, camera.combined); float x = getGround().getBody().getPosition().x; float y = getGround().getBody().getPosition().y; float w = getGround().getWidth() * 2; float h = getGround().getHeight() * 2; spriteBatch.setProjectionMatrix(getCamera().combined); Texture texture = new Texture(Gdx.files.internal("ground.png")); Sprite sprite = new Sprite(texture); sprite.setSize(w, h); sprite.setPosition(x-sprite.getWidth()/2, y-sprite.getHeight()/2); spriteBatch.begin(); sprite.draw(spriteBatch); spriteBatch.end(); } public void handleInput() { if(boostButton.isPressed()) { rocket.boost(); } if(boostLeftButton.isPressed()) { rocket.turnLeft(); } if(boostRightButton.isPressed()) { rocket.turnRight(); } if(resetButton.isPressed()) { } } public boolean resetScreen() { if(resetButton.isPressed()) return true; return false; } public void updateCamera() { } public Ground getGround() { return ground; } public void resize(int width, int height) { viewport.update(width, height); camera.position.x = VIEWPORT_WIDTH / 2; camera.position.y = VIEWPORT_HEIGHT /2; } private void translateScreenToWorldCoordinates(int x, int y) { getCamera().unproject(touchPoint.set(x, y, 0));getCamera(); } } Screen class public class Mission1Screen implements Screen{ private Game game; private Mission1Stage stage; private SpriteBatch spriteBatch = new SpriteBatch(); private Skin boostSkin; private Button boostButton; public Mission1Screen(Game game) { this.game = game; stage = new Mission1Stage(game); } #Override public void show() { } #Override public void render(float delta) { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); if(stage.resetScreen()) { game.setScreen(new Mission1Screen(game)); } stage.act(delta); stage.draw(); stage.updateCamera(); } #Override public void resize(int width, int height) { stage.resize(width, height); } #Override public void pause() { } #Override public void resume() { } #Override public void hide() { } #Override public void dispose() { } } [EDIT 3] public class Main extends Game { #Override public void create () { this.setScreen(new Mission1Screen(this)); } #Override public void render () { super.render(); } #Override public void dispose () { } }
We mostly use Pixel to meter conversion because box2d best works in meters (0-10) but you can avoid this conversion by using small worldwidth and height of your viewport. I mostly prefer 48 and 80 as viewport width and height. You can use unproject(vector3) method of camera that translate a point given in screen coordinates to world space. I am using this method in touchdown because I get screen coordinate as parameter then I need to convert it into camera world space so that I can generate object at a particular position in world. public class MyGdxTest extends Game implements InputProcessor { private SpriteBatch batch; private ExtendViewport extendViewport; private OrthographicCamera cam; private float w=20; private float h=22; private World world; private Box2DDebugRenderer debugRenderer; private Array<Body> array; private Vector3 vector3; #Override public void create() { cam=new OrthographicCamera(); extendViewport=new ExtendViewport(w,h,cam); batch =new SpriteBatch(); Gdx.input.setInputProcessor(this); world=new World(new Vector2(0,-9.8f),true); array=new Array<Body>(); debugRenderer=new Box2DDebugRenderer(); vector3=new Vector3(); BodyDef bodyDef=new BodyDef(); bodyDef.type= BodyDef.BodyType.StaticBody; bodyDef.position.set(0,0); Body body=world.createBody(bodyDef); ChainShape chainShape=new ChainShape(); chainShape.createChain(new float[]{1,1,55,1}); FixtureDef fixtureDef=new FixtureDef(); fixtureDef.shape=chainShape; fixtureDef.restitution=.5f; body.createFixture(fixtureDef); chainShape.dispose(); } #Override public void render() { super.render(); Gdx.gl.glClearColor(0,1,1,1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); world.step(1/60f,6,2); batch.setProjectionMatrix(cam.combined); batch.begin(); world.getBodies(array); for (Body body:array){ if(body.getUserData()!=null) { Sprite sprite = (Sprite) body.getUserData(); sprite.setPosition(body.getPosition().x-sprite.getWidth()/2, body.getPosition().y-sprite.getHeight()/2); sprite.setRotation(body.getAngle()*MathUtils.radDeg); sprite.draw(batch); } } batch.end(); debugRenderer.render(world,cam.combined); } #Override public void resize(int width, int height) { super.resize(width,height); extendViewport.update(width,height); cam.position.x = w /2; cam.position.y = h/2; cam.update(); } private void createPhysicsObject(float x,float y){ float sizeX=2,sizeY=2; BodyDef bodyDef=new BodyDef(); bodyDef.position.set(x,y); bodyDef.type= BodyDef.BodyType.DynamicBody; Body body=world.createBody(bodyDef); PolygonShape polygonShape=new PolygonShape(); polygonShape.setAsBox(sizeX,sizeY); FixtureDef fixtureDef=new FixtureDef(); fixtureDef.shape=polygonShape; fixtureDef.restitution=.2f; fixtureDef.density=2; body.createFixture(fixtureDef); body.setFixedRotation(false); polygonShape.dispose(); Sprite sprite=new Sprite(new Texture("badlogic.jpg")); sprite.setSize(2*sizeX,2*sizeY); sprite.setPosition(x-sprite.getWidth()/2,y-sprite.getHeight()/2); sprite.setOrigin(sizeX,sizeY); body.setUserData(sprite); } #Override public void dispose() { batch.dispose(); debugRenderer.dispose(); world.dispose(); } #Override public boolean keyDown(int keycode) { return false; } #Override public boolean keyUp(int keycode) { return false; } #Override public boolean keyTyped(char character) { return false; } #Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { vector3.set(screenX,screenY,0); Vector3 position=cam.unproject(vector3); createPhysicsObject(vector3.x,vector3.y); return false; } #Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { return false; } #Override public boolean touchDragged(int screenX, int screenY, int pointer) { return false; } #Override public boolean mouseMoved(int screenX, int screenY) { return false; } #Override public boolean scrolled(int amount) { return false; } }
How to make a sprite move with keyboard in java(libgdx)
i'm making a game for school motives, i have already made the sprite and the background(tiled map) my problem is how i can make the sprite move left, right, back and down using the keyboard, please guys help me as soon as possible here is my code: public class LEVEL1 implements ApplicationListener, Screen { private Music music; private SpriteBatch batch; private Texture Sprite; private Vector2 position; private TiledMap map; private OrthogonalTiledMapRenderer renderer; private OrthographicCamera camera; #Override public void render(float delta) { Gdx.gl.glClearColor(1, 0, 0, 0); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); position.y = position.y - 5; // player Controls if(position.y < 0){ position.y = 0; } //.................................................. // renderer camera and map camera.update(); renderer.setView(camera); renderer.render(); //................................................... //tells the computer when to start drawing textures batch.begin(); batch.draw(Sprite, position.x, position.y, 50, 50); batch.end(); //................................................... camera = new OrthographicCamera(); camera.setToOrtho(true, 2920,950); } #Override public void show() { Sprite = new Texture("Sprite.png"); batch = new SpriteBatch(); position = new Vector2(650, Gdx.graphics.getHeight()); map = new TmxMapLoader().load("map1.tmx"); renderer = new OrthogonalTiledMapRenderer(map); camera = new OrthographicCamera(); music = Gdx.audio.newMusic((Gdx.files.internal("GameSound.mp3"))); music.setLooping(false); music.setVolume(0.5f); music.play(); } #Override public void create() { } #Override public void resize(int width, int height) { camera.viewportWidth = width; camera.viewportHeight = height; camera.position.set(width/2f, height/3f, 0); //by default camera position on (0,0,0) camera.update(); } #Override public void render() { if(Gdx.input.justTouched()) music.play(); } #Override public void dispose() { map.dispose(); renderer.dispose(); music.dispose(); } #Override public void hide() { // TODO Auto-generated method stub } #Override public void pause() { // TODO Auto-generated method stub } #Override public void resume() { // TODO Auto-generated method stub } }
Here i make a little example of moving a sprite using keys (up,down, left,right) you should find more details in libgdx wiki public class Level1 implements ApplicationListener { Sprite sprite; SpriteBatch batch; float spriteXposition; float spriteYposition; #Override public void render() { Gdx.gl.glClearColor(1, 0, 0, 0); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); //tells the computer when to start drawing textures batch.begin(); sprite.setPosition(spriteXposition, spriteYposition); sprite.draw(batch); batch.end(); spriteControl(); } public void spriteControl() { if(Gdx.input.isKeyPressed(Keys.UP)) { spriteYposition++; } if(Gdx.input.isKeyPressed(Keys.DOWN)) { spriteYposition--; } if(Gdx.input.isKeyPressed(Keys.LEFT)) { spriteXposition--; } if(Gdx.input.isKeyPressed(Keys.RIGHT)) { spriteXposition++; } } #Override public void create() { sprite = new Sprite(new Texture(Gdx.files.internal("sprite.png"))); batch = new SpriteBatch(); } }
To react on input events you need to implement InputProcessor. It has the methods keyDown (called when a key is pressed) and keyUp (called when a key is released). Those methods have an argument keyCode, which defines the int code of the pressed/released key. So you need to override this 2 methods and depending on the keyCode you get, you should do something or not. To move the player for example, you might keep a member speed, which you set, depending on the pressed/released key. In the render method you then need to update the position depending on the elapsed time (delta) and the speed. To get the input event, you need to tell libgdx, that your InputProcessor should be the active one. This is done by calling Gdx.input.setInputProcessor(yourInputProcessor). Also make sure to read the Libgdx wiki, many of your questions will be answered there. EDIT: Some code: public class Level implements ApplicationListener, InputProcessor { private int speedX; // Speed in x direction private Vector2 position; // Position private boolean keyDown(int keyCode) { boolean result = false; if (keyCode == Keys.D) { result = true; speed += 5; } else if (keyCode == Keys.A) { result = true; speed -= 5; } return result; } private boolean keyUp(int keyCode) { boolean result = false; if (keyCode == Keys.D) { result = true; speed -= 5; } else if (keyCode == Keys.A) { result = true; speed += 5; } return result; } public void render(float delta) { position.x += speed*delta; // Render here } }
Libgdx NullPointerException when trying to update viewport
I'm trying to update the game's viewport when the game resizes, but when I start the game, I get a java.lang.NullPointerException: Exception in thread "LWJGL Application" java.lang.NullPointerException at com.badlogic.gdx.utils.viewport.Viewport.apply(Viewport.java:49) at com.badlogic.gdx.utils.viewport.ExtendViewport.update(ExtendViewport.java:90) at com.badlogic.gdx.utils.viewport.Viewport.update(Viewport.java:57) at me.chrisjosten.testgame.screens.MainScreen.resize(MainScreen.java:82) at com.badlogic.gdx.Game.setScreen(Game.java:62) at me.chrisjosten.testgame.create(MainScreen.java:13) at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:136) at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114) In the class, that implements Screen, I have in the resize method, the place where the exception occurs, the following code: #Override public void resize(int w, int h) { viewport.update(w, h); } where the viewport is an ExtendViewport created in the constructor of the class. I've tried putting that in the show method to, but then I get the same result. The full code of the class: package me.chrisjosten.testgame.screens; import me.chrisjosten.testgame.MyGame; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Screen; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.viewport.ExtendViewport; import com.badlogic.gdx.utils.viewport.FillViewport; import com.badlogic.gdx.utils.viewport.Viewport; public class MainScreen implements Screen{ private MyGame game; private BitmapFont font; private SpriteBatch batch; private OrthographicCamera camera; private Viewport viewport; private boolean goingUp = false; private float alpha = 1; private int gameWidth = 100; private int gameHeight = 100; private int screenWidth; private int screenHeight; public MainScreen(MyGame g) { game = g; System.out.println("screen created"); } #Override public void show() { System.out.println("show"); font = new BitmapFont(Gdx.files.internal("fonts/monospace.fnt")); font.setColor(1, 1, 1, 1); batch = new SpriteBatch(); camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); camera.translate(gameWidth / 2, gameHeight / 2); viewport = new ExtendViewport(gameWidth, gameHeight, camera); } #Override public void render(float delta) { camera.update(); Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); if (goingUp) { font.setColor(1, 1, 1, alpha); alpha += 0.025; } else { font.setColor(1, 1, 1, alpha); alpha -= 0.025; } if (alpha <= 0) { goingUp = true; alpha = 0; } else if (alpha >= 1) { goingUp = false; alpha = 1; } batch.setProjectionMatrix(camera.combined); batch.begin(); String press = "Press start"; font.draw(batch, press, gameWidth / 2 - font.getBounds(press).width / 2, 1); batch.end(); } #Override public void resize(int w, int h) { viewport.update(w, h); } #Override public void pause() { // TODO Auto-generated method stub } #Override public void resume() { // TODO Auto-generated method stub } #Override public void hide() { // TODO Auto-generated method stub } #Override public void dispose() { // TODO Auto-generated method stub font.dispose(); } } Does anyone know what I have done wrong?
By moving the code from the show method to the constructor, it works.
Libgdx Scrolling TiledMaps
i'm trying to make my libgdx map scroll, but i dont know the code to make map scroll, please guys help me, i would like the map to scroll like flappy bird game, this is my my code which show the map on the screen #Override public void render(float delta) { Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); position.y = position.y - 4; if(Gdx.input.isTouched()){ position.y = position.y +10; } if(position.y < 0){ position.y = 0; } if(position.y > Gdx.graphics.getHeight() -70){ position.y = Gdx.graphics.getHeight() - 70; } renderer.setView(camera); renderer.render(); //tells the computer when to start drawing textures batch.begin(); batch.draw(Green1, position.x, position.y, 50, 50); batch.end(); } #Override public void show() { Green1 = new Texture("img/Green1.png"); batch = new SpriteBatch(); position = new Vector2(20, Gdx.graphics.getHeight()); map = new TmxMapLoader().load("maps/map1.tmx"); renderer = new OrthogonalTiledMapRenderer(map); camera = new OrthographicCamera(); } #Override public void hide() { } #Override public void create() { Green1 = new Texture("img/Green.png"); batch = new SpriteBatch(); position = new Vector2(20, Gdx.graphics.getHeight()); } #Override public void resize(int width, int height) { camera.viewportWidth = width; camera.viewportHeight = height; camera.position.set(width/2f, height/3f, 0); //by default camera position on (0,0,0) camera.update(); } #Override public void render() { } #Override public void pause() { } #Override public void resume() { } #Override public void dispose() { map.dispose(); renderer.dispose(); } }
When I was learning to build 2D games I used star-assault for an example. You can find their github repository here: https://github.com/chrismorales/2d-sidescroller && https://github.com/chrismorales/2d-sidescroller/blob/master/star-assault/src/net/obviam/starassault/view/WorldRenderer.java should be useful to look at.
Black Screen and cleaning the code (LibGDX)
I'm following video tutorials using libGdx and kinda adapting the code to get what I want. I managed to draw the HUD and an animation, but when I tried to add a button following another tutorial I ended with a black screen, here is the code: public class WorldRenderer implements ApplicationListener, Screen { Pixmap pixmap; SpriteBatch batch; private Skin skin; private Stage stage; OrthographicCamera cam; Table table; TextButton buttonShake; BitmapFont white; BitmapFont black; private TextureAtlas atlas; Texture virusTexture; Texture hudTexture; private static final float HUD_WIDTH = 480f; private static final float HUD_HEIGHT = 800f; private static final float WALK_ANIM_WIDTH = 337f; private static final float WALK_ANIM_HEIGHT = 213f; public static final int SCREEN_WIDTH = 480; public static final int SCREEN_HEIGHT = 800; private static final int FRAME_COLS = 2; private static final int FRAME_ROWS = 2; Animation walkAnimation; Texture walkSheet; TextureRegion[] walkFrames; TextureRegion currentFrame; float stateTime; float width, height; Hud hud; public WorldRenderer(World world) { this.world = world; walkSheet = new Texture("data/character.png"); TextureRegion[][] tmp = TextureRegion.split(walkSheet, walkSheet.getWidth() / FRAME_COLS, walkSheet.getHeight() / FRAME_ROWS); walkFrames = new TextureRegion[FRAME_COLS * FRAME_ROWS]; int index = 0; for (int i = 0; i < FRAME_ROWS; i++) { for (int j = 0; j < FRAME_COLS; j++) { walkFrames[index++] = tmp[i][j]; } } walkAnimation = new Animation(0.25f, walkFrames); stateTime = 0f; width = Gdx.graphics.getWidth(); height = Gdx.graphics.getHeight(); cam = new OrthographicCamera(SCREEN_WIDTH, SCREEN_HEIGHT); cam.position.set(SCREEN_WIDTH / 2f, SCREEN_HEIGHT / 2f, 0); batch = new SpriteBatch(); batch.setProjectionMatrix(cam.combined); hudTexture = new Texture("data/hud.png"); hudTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear); } public void render(float delta) { Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); cam.update(); stage.act(delta); stateTime += Gdx.graphics.getDeltaTime(); currentFrame = walkAnimation.getKeyFrame(stateTime, true); hud = world.getHud(); batch.setProjectionMatrix(cam.combined); batch.begin(); batch.draw(hudTexture, SCREEN_WIDTH / 2f - HUD_WIDTH / 2f, SCREEN_HEIGHT / 2f - HUD_HEIGHT / 2f); batch.draw(currentFrame, SCREEN_WIDTH / 2f - WALK_ANIM_WIDTH / 2f, SCREEN_HEIGHT / 2f - WALK_ANIM_HEIGHT / 2f); batch.end(); stage.draw(); } public void dispose() { batch.dispose(); virusTexture.dispose(); hudTexture.dispose(); skin.dispose(); atlas.dispose(); white.dispose(); black.dispose(); stage.dispose(); } #Override public void create() { } #Override public void resize(int width, int height) { } #Override public void pause() { // TODO Auto-generated method stub } #Override public void resume() { // TODO Auto-generated method stub } #Override public void show() { } #Override public void hide() { // TODO Auto-generated method stub } #Override public void render() { // TODO Auto-generated method stub } I'm pretty sure you are also going to find unused lines of code so please point them out for me if you want so I can better organize my code and learn. Thanks!
One possible problem is that you implement an ApplicationListener and a Screen, both have the render method and almost the same methods. You shouldn't implement both. If this is your app entry-point I would go for the applicationListener. However, for the educational purpose you should read some topics about the Game class as your next app entry-point. Consider using separated "screens" that handle the render part and a "brain" that allows them to communicate with each other, this is where the Game class becomes handy. Things can seem a little trickier at the beginning but will definitely make sense to you after a bit of studying ;)