I'm starting with open GL and have a little problem, I'm trying to paint the screen with a solid (and random) color, but it shown a high refresh with the color. I inserted a sleep in the method onDrawFrame for seeing whats happening and the result is: black screen - colored screen - black screen - colored screen ... refreshing every second. What am I doing wrong? Thats my code:
package com.example.opengltest;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity implements Renderer {
GLSurfaceView glView;
GL10 gl;
Object stateChanged = new Object();
Random rand = new Random();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glView = new GLSurfaceView(this);
glView.setRenderer(this);
setContentView(glView);
}
private void paint() {
Log.i("OPENGL","paint");
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glClearColor(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(),
1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 320, 0, 480, 1, -1);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(3 * 2 * 4);
byteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer vertices = byteBuffer.asFloatBuffer();
vertices.put(new float[] { 0.0f, 0.0f,
319.0f, 0.0f,
160.0f, 479.0f });
vertices.flip();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
protected void onPause() {
super.onPause();
glView.onPause();
}
#Override
protected void onResume() {
super.onResume();
glView.onResume();
}
public void onDrawFrame(GL10 gl) {
Log.i("OPENGL","onDrawFrame");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
Log.i("OPENGL","onSurfaceChanged");
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
this.gl = gl;
Log.i("OPENGL","onSurfaceCreated");paint();
}
}
You are calling your paint() method in onSurfaceChanged whereas you should call some of its contents in onDrawFrame(), and never use the sleep function inside a GL thread, it will only cause black screens flickering all over.
In particular, try moving
gl.glClear(GL10.GL_COLOR_BUFFER_BIT); // Clear the color buffer
gl.glClearColor(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), 1); // Clear it with a random color
to the onDrawFrame function, and I don't know exactly why you're calling glClear() twice in paint(), but that's a mistake, you're clearing what you just painted with a random color! So delete that second call to onClear() and I think you should be fine. Actually, I don't even think you need the first glClear() call, because you're already clearing it with glClearColor, although if you do introduce some alpha transparency then you're better off having both (or else they will sum up).
Let us know if that helped!
Related
I've been learning about libgdx recently. In the process of following the instructions on their libgdx wiki I ran into some problems.
Specifically in the GameScreen class at the 99th line I changed the code inside so that it goes back to the previous screen (MainMenuScreen class) and yes you see when the mouse is pressed it worked (I mean go back to the screen before ) but a very very short time after, the screen AUTOMATICALLY switches to the GameScreen class (like I click the mouse once but it makes me 1 more redundant task). I guess when I click on the GameScreen screen it did the code in the if statement on line 99 to go to MainMenuScreen screen. In that screen at line 32 I guess it was true after I got to this screen because when I change the key is listened then it works fine (only converts once). I was intending to try implementing InputProcessor on each screen class but now I'm avoiding it for some reason. Can someone give me some advice recommend.Thank you
Here is the source code for the MainMenuScreen class.
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.utils.ScreenUtils;
//import com.mygdx.game.Drop;
public class MainMenuScreen implements Screen {
final Drop game;
OrthographicCamera camera;
public MainMenuScreen(final Drop gam) {
game = gam;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
}
#Override
public void render(float delta) {
ScreenUtils.clear(0, 0, 0.2f, 1);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.font.draw(game.batch, "Welcome to Drop!!! ", 100, 150);
game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
game.batch.end();
if (Gdx.input.isTouched()) { //I guess right after switching to this screen this conditional sentence was true before
game.setScreen(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() {
}
}
Here is source code for the GameScreen class
package com.mygdx.game;
import java.util.Iterator;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.TimeUtils;
public class GameScreen implements Screen {
final Drop game;
Texture dropImage;
Texture bucketImage;
//Sound dropSound;
//Music rainMusic;
OrthographicCamera camera;
Rectangle bucket;
Array<Rectangle> raindrops;
long lastDropTime;
int dropsGathered;
public GameScreen(final Drop gam) {
this.game = gam;
// load the images for the droplet and the bucket, 64x64 pixels each
dropImage = new Texture(Gdx.files.internal("drop.png"));
bucketImage = new Texture(Gdx.files.internal("bucket.png"));
// load the drop sound effect and the rain background "music"
//dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
//rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
//rainMusic.setLooping(true);
// create the camera and the SpriteBatch
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
// create a Rectangle to logically represent the bucket
bucket = new Rectangle();
bucket.x = 800 / 2 - 64 / 2; // center the bucket horizontally
bucket.y = 20; // bottom left corner of the bucket is 20 pixels above
// the bottom screen edge
bucket.width = 64;
bucket.height = 64;
// create the raindrops array and spawn the first raindrop
raindrops = new Array<Rectangle>();
spawnRaindrop();
}
private void spawnRaindrop() {
Rectangle raindrop = new Rectangle();
raindrop.x = MathUtils.random(0, 800 - 64);
raindrop.y = 480;
raindrop.width = 64;
raindrop.height = 64;
raindrops.add(raindrop);
lastDropTime = TimeUtils.nanoTime();
}
#Override
public void render(float delta) {
// clear the screen with a dark blue color. The
// arguments to clear are the red, green
// blue and alpha component in the range [0,1]
// of the color to be used to clear the screen.
ScreenUtils.clear(0, 0, 0.2f, 1);
// tell the camera to update its matrices.
camera.update();
// tell the SpriteBatch to render in the
// coordinate system specified by the camera.
game.batch.setProjectionMatrix(camera.combined);
// begin a new batch and draw the bucket and
// all drops
game.batch.begin();
game.font.draw(game.batch, "Drops Collected: " + dropsGathered, 0, 480);
game.batch.draw(bucketImage, bucket.x, bucket.y);
for (Rectangle raindrop : raindrops) {
game.batch.draw(dropImage, raindrop.x, raindrop.y);
}
game.batch.end();
// process user input
if (Gdx.input.justTouched()) { //This conditional works fine
/* Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
bucket.x = touchPos.x - 64 / 2;
*/
game.setScreen(new MainMenuSceen(game)); //Screen switch
}
if (Gdx.input.isKeyPressed(Keys.LEFT))
bucket.x -= 200 * Gdx.graphics.getDeltaTime();
if (Gdx.input.isKeyPressed(Keys.RIGHT))
bucket.x += 200 * Gdx.graphics.getDeltaTime();
// make sure the bucket stays within the screen bounds
if (bucket.x < 0)
bucket.x = 0;
if (bucket.x > 800 - 64)
bucket.x = 800 - 64;
// check if we need to create a new raindrop
if (TimeUtils.nanoTime() - lastDropTime > 1000000000)
spawnRaindrop();
// move the raindrops, remove any that are beneath the bottom edge of
// the screen or that hit the bucket. In the later case we play back
// a sound effect as well.
Iterator<Rectangle> iter = raindrops.iterator();
while (iter.hasNext()) {
Rectangle raindrop = iter.next();
raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
if (raindrop.y + 64 < 0)
iter.remove();
if (raindrop.overlaps(bucket)) {
dropsGathered++;
//dropSound.play();
iter.remove();
}
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
// start the playback of the background music
// when the screen is shown
//rainMusic.play();
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
dropImage.dispose();
bucketImage.dispose();
//dropSound.dispose();
//rainMusic.dispose();
}
}
Here is source for Drop class
package com.mygdx.game;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class Drop extends Game {
SpriteBatch batch;
BitmapFont font;
public void create() {
batch = new SpriteBatch();
// Use LibGDX's default Arial font.
font = new BitmapFont();
this.setScreen(new MainMenuScreen(this));
}
public void render() {
super.render(); // important!
}
public void dispose() {
batch.dispose();
font.dispose();
}
}
Your analysis of the problem seems correct to me. The method Gdx.input.isTouched() will immediately return true, if the screen is still being touched after you changed to the main menu.
Also you the solution that you already tried seems correct:
I was intending to try implementing InputProcessor on each screen class
When using an InputProcessor you will get one event (the method call to touchDown or touchUp) when the screen is touched, and don't need to pull the touch event using the isTouched method.
A problem when implementing InputProcessor with both classes probably is, that you can only set one to be the input processor of the game using the method Gdx.input.setInputProcessor. (When setting the second input processor, the first one is removed).
A solution to this problem is the InputMultiplexer. You can add this multiplexer as the input processor of the game (using Gdx.input.setInputProcessor(multiplexer)) and then add your input processors (the main menu and game objects) to this multiplexer: multiplexer.addProcessor(mainMenu) or ((InputMultiplexer) Gdx.input.getInputProcessor()).addProcessor(game).
This way you can handle touch events instead of pulling the touched state in both of your classes.
I am creating a game and trying to set up a splash screen.
Whenever I render the sprite that i want to tween to by using the sprite.draw method which looks like this:
#Override
public void render(float delta)
{
Gdx.gl20.glClearColor(0.2F, 0.5F, 1F, 1F);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
tm.update(delta);
cam.update();
sb.setProjectionMatrix(cam.combined);
sb.begin();
Assets.splash_spr_bg.draw(sb);
sb.end();
}
The tweening works great except i can only see 1/4 of the picture on my screen, it is completely out of position.
And whenever I try to use this code in order to render the sprite by using the spritebatch to draw it, which looks like this:
#Override
public void render(float delta)
{
Gdx.gl20.glClearColor(0.2F, 0.5F, 1F, 1F);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
tm.update(delta);
cam.update();
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(Assets.splash_spr_bg, 0, 0);
sb.end();
}
I can see the background great, great quality, correct size and position and all that. However, the tweening doesn't work at all; nothing happens.
Why does this not work? How can I fix it?
Here is some other code.
Initializion of the TweenHandler class:
package com.heavenapps.jumpdodge.handlers;
import com.badlogic.gdx.graphics.g2d.Sprite;
import aurelienribon.tweenengine.TweenAccessor;
public class TweenHandler implements TweenAccessor<Sprite>
{
public static final int ALPHA = 1;
#Override
public int getValues(Sprite target, int tweenType, float[] returnValues)
{
switch(tweenType)
{
case ALPHA:
returnValues[0] = target.getColor().a;
return 1;
default:
return 0;
}
}
#Override
public void setValues(Sprite target, int tweenType, float[] newValues)
{
switch(tweenType)
{
case ALPHA:
target.setColor(1, 1, 1, newValues[0]);
break;
}
}
}
Initializion of the sprite/texture:
package com.heavenapps.jumpdodge.handlers;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
public class Assets
{
public static Texture splash_tex_bg;
public static Sprite splash_spr_bg;
public static void init()
{
// Splash Screen
splash_tex_bg = new Texture(Gdx.files.internal("Splash Screen/Background.png"));
splash_tex_bg.setFilter(TextureFilter.Linear, TextureFilter.Linear);
splash_spr_bg = new Sprite(splash_tex_bg);
splash_spr_bg.setOrigin(splash_spr_bg.getWidth() / 2, splash_spr_bg.getHeight() / 2);
splash_spr_bg.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
splash_spr_bg.setColor(1, 1, 1, 0);
}
}
Usage of the tweening:
public void fadeSplashScreen()
{
Tween.to(Assets.splash_spr_bg, TweenHandler.ALPHA, 2F).target(1).ease(TweenEquations.easeInBounce).start(tm);
}
You need to set the sprite's position if you want to draw it using your first method. (sprite.draw(spriteBatch)). And you need to use your first method if you want to use the sprite's color, which is being controlled by the tween.
It looks like you did give the background sprite an initial position, but you put it off screen. So change
splash_spr_bg.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
to
splash_spr_bg.setPosition(0, 0);
The reason the second method you showed (spriteBatch.draw(sprite, x, y)) draws it in the correct position is that this method of drawing ignores the fact that it's a sprite and just draws the texture region owned by the sprite in whatever position you give it. And this method doesn't fade the sprite because it's ignoring the fact that it is a sprite (which has a color).
I am having a hard time drawing text in LibGDX. Every time I run it, i get a black window. I want the text to be white, but I dont see anything. I have tried finding numerous tutorials and vieos, and still cannot get it to work. I do have a vaild fnt and png file in my assets folder / fonts.
package org.alexwebber.frc.stalk;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class Main extends ApplicationAdapter
{
public class HelloWorld implements ApplicationListener
{
private SpriteBatch batch;
private BitmapFont font;
#Override
public void create()
{
batch = new SpriteBatch();
font = new BitmapFont(Gdx.files.internal("fonts/main.fnt"),
Gdx.files.internal("fonts/main.png"), false);
}
#Override
public void dispose()
{
batch.dispose();
font.dispose();
}
#Override
public void render()
{
batch.begin();
font.setColor(255.0f, 255.0f, 255.0f, 255.0f);
font.draw(batch, "Hello World", 25, 160);
batch.end();
}
#Override
public void resize(int width, int height)
{
}
#Override
public void pause()
{
}
#Override
public void resume()
{
}
}
}
Something that might be impacting you is the removal of the screen clearing:
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
font.setColor(Color.WHITE);
font.draw(batch, "Hello world", 25, 160);
batch.end();
}
You can also try passing Color.WHITE as above. If the Android device you're using has an extreme screen resolution you may not be seeing the line of text.
Testing via a Desktop application may be a good idea as well, as you can tweak the screen resolution so the text is a larger size.
I have this issue in my LibGDX project, I essentially can't load up my gamescreen, I am following a YouTube tutorial (link to particular tutorial I'm on: https://www.youtube.com/watch?v=LSblkR4K1LU), and I have found that my sprite that is supposed to go on my screen, just it won't load up at all, it just opens, closes then pops this up: http://puu.sh/coxUv/d877d08a83.png, I will admit the only thing I have changed from the video was this:
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
I changed GL10.GL_COLOR_BUFFER_BIT (that was in the video), to GL20.GL_COLOR_BUFFER_BIT, because it gave me an error: GL10 cannot be resolved to a variable, does anyone have an idea why, tell me if there is any needed information.
Thanks in advance.
EDIT:
Gamescreen Class:
package com.edac.unforgivingunderground;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class GameScreen implements Screen{
UnforgivingUnderground game;
OrthographicCamera camera;
SpriteBatch batch;
public GameScreen(UnforgivingUnderground game){
this.game = game;
camera = new OrthographicCamera();
camera.setToOrtho(false,1920,1080);
batch = new SpriteBatch();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void show() {
// 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
}
Assets Class:
package com.edac.unforgivingunderground;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
public class Assets {
public static Texture texture_back;
public static Sprite sprite_back;
public static void load(){
texture_back = new Texture(Gdx.files.internal("logo"));
texture_back.setFilter(TextureFilter.Linear, TextureFilter.Linear);
sprite_back = new Sprite(texture_back);
sprite_back.flip(false, true);
}
}
Desktop Launcher:
package com.edac.unforgivingunderground.desktop;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.edac.unforgivingunderground.UnforgivingUnderground;
public class DesktopLauncher {
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
new LwjglApplication(new UnforgivingUnderground(), config);
}
}
Main Class:
package com.edac.unforgivingunderground;
import com.badlogic.gdx.Game;
public class UnforgivingUnderground extends Game{
public GameScreen game_screen;
#Override
public void create() {
Assets.load();
game_screen = new GameScreen(this);
setScreen(game_screen);
}
Not sure why it crashed (you should post the stack dump) but possibly it's because this line: Gdx.files.internal("logo"). Maybe you mean logo.png or logo.jpg. Also make sure that the image file does really exist on your assets folder.
Also, I belive your render method is missing one line.:
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
Assets.sprite_back.draw(batch);
}
That way you'll render your sprite to the screen through the SpriteBatch. In your code you can see that you're not using it.
Started making a game.
Here's some of my code.
package games.tribe.screens;
import games.tribe.model.World;
import games.tribe.view.WorldRenderer;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL10;
public class GameScreen implements Screen {
private World world;
private WorldRenderer renderer;
/** This was the bit I'd missed --------------------------------------**/
#Override
public void show() {
world = new World();
renderer = new WorldRenderer(world);
}
/**------------------------------------------------------------------**/
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
renderer.render();
}
#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
}
}
here's the WorldRenderer Class:
package games.tribe.view;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import games.tribe.model.Block;
import games.tribe.model.TribalHunter;
import games.tribe.model.World;
public class WorldRenderer {
private World world;
private OrthographicCamera cam;
/**for debug rendering**/
ShapeRenderer debugRenderer = new ShapeRenderer();
public WorldRenderer(World world) {
this.world = world;
this.cam = new OrthographicCamera(10, 7);
this.cam.position.set(5, 3.5f, 0);
this.cam.update();
}
public void render() {
//render blocks
debugRenderer.setProjectionMatrix(cam.combined);
debugRenderer.begin(ShapeType.Rectangle);
for(Block block : world.getBlocks()) {
Rectangle rect = block.getBounds();
float x1 = block.getPosition().x + rect.x;
float y1 = block.getPosition().y + rect.y;
debugRenderer.setColor(new Color(1, 0, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
}
//render hunter
TribalHunter hunter = world.getHunter();
Rectangle rect = hunter.getBounds();
float x1 = hunter.getPosition().x + rect.x;
float y1 = hunter.getPosition().y + rect.y;
debugRenderer.setColor(new Color(0, 1, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
debugRenderer.end();
}
}
This is the exception I'm getting when I run it as a desktop application:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at games.tribe.screens.GameScreen.render(GameScreen.java:19)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:202)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:131)
AL lib: ReleaseALC: 1 device not closed
Line 46 of gdx.Game.render is this method:
#Override
public void render () {
if (screen != null) screen.render(Gdx.graphics.getDeltaTime());
}
Any help will be appreciated
Thanks in advance
In the GameScreen's render() method, has the renderer been initialized? That could be causing the problem if it hasn't.
Edit: The problem you're having, according to the top two lines of the error, is a NullPointerException on line 19 of the class GameScreen. The NullPointerException only occurs when an object is used for some action when the object itself is null because it likely hasn't been initialized.
Line 19 of the GameScreen is:
renderer.render();
...but the object renderer has not been initialized anywhere, so it is currently null which is the default. To avoid getting this error, you'll need to initialize the renderer object before you run that line of code. Perhaps with something like this:
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
renderer = new WorldRenderer();
renderer.render();
}
I am not familiar with libgdx, so I can't be sure that's exactly how a WorldRenderer is initialized, but you need to do something of the sort. I hope this helps.