java.lang.NullPointerException when SpriteBatch.end() occurs - java

Update: Solution at the bottom of this post.
I'm having a problem in which when my game is run, the screen is just black and crashed a couple seconds later. I declare a new SpriteBatch in my main Game class:
public SpriteBatch batch;
And I instantiate it in my Create method() and pass the entire Game class to a Screen called Playscreen:
batch = new SpriteBatch();
setScreen(new PlayScreen(this));
In the constructor of PlayScreen, I set the passed Game class to a private field I set up:
this.game = game;
This is my entire render method for PlayScreen:
#Override
public void render(float delta)
{
update(delta);
Gdx.gl.glClearColor(0, 2, 2, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
// Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
game.batch.begin();
for (Tile[] tileArray : tileMatrix.getTileMatrix())
{
for (Tile tile : tileArray)
{
tile.draw(game.batch);
}
}
game.batch.end();
hud.stage.draw();
}
tileArray is a two dimensional array that contains Tiles. In my create() method, every tile in this array is initialized and assigned a different location. Here is the base class:
public abstract class Tile extends Sprite
{
protected Texture texture;
protected String name;
protected int movementPoints;
protected int foodYield;
protected int productionYield;
protected int tradeYield;
public Tile(int mP, int fY, int pY, int tY, String name, Texture texture)
{
this.movementPoints = mP;
this.foodYield = fY;
this.productionYield = pY;
this.tradeYield = tY;
this.name = name;
this.texture = texture;
setBounds(0, 0, 50, 50);
}
When DesktopLauncher.java is run, I get this error:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.badlogic.gdx.graphics.g2d.SpriteBatch.flush(SpriteBatch.java:962)
at com.badlogic.gdx.graphics.g2d.SpriteBatch.end(SpriteBatch.java:183)
at com.marcusorciuch.reciv.screens.PlayScreen.render(PlayScreen.java:108)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.marcusorciuch.reciv.ReCivMain.render(ReCivMain.java:47)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:225)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:126)
#
game.batch.end();
Yeah, I don't know whats going on.
Edit: To those who are having this problem, make sure if you have a class that extends from Sprite, make sure you call super(texture) or else the Sprite parts of your class will not be instantiated.

Related

LibGDX - Camera scaling does not work

I have a problem with LibGDX. I am trying to create an application, and for ease of use I want to draw everything at a fixed resolution (1920x1080).
To do this, I am trying to create a FitViewport and an OrthographicCamera so that the viewport always fits nicely to the screen size, and everything automatically scales.
In my Screen class I create such a viewport and a camera:
AbstractScreen() {
camera = new OrthographicCamera(Constants.VIRTUAL_WIDTH, Constants.VIRTUAL_HEIGHT);
viewport = new FitViewport(Constants.VIRTUAL_WIDTH, Constants.VIRTUAL_HEIGHT, camera);
}
(where VIRTUAL_WIDTH is 1920 and VIRTUAL_HEIGHT is 1080)
Now, when I try to render an image that is 1920x1080px, only one third of that image is drawn!
Here is a screenshot of what should be drawn: screenshot
Here is the image that should be fully drawn: image
public abstract class AbstractScreen implements Screen {
private Viewport viewport;
private OrthographicCamera camera;
protected SpriteBatch spriteBatch;
AbstractScreen() {
camera = new OrthographicCamera(Constants.VIRTUAL_WIDTH, Constants.VIRTUAL_HEIGHT);
viewport = new FitViewport(Constants.VIRTUAL_WIDTH, Constants.VIRTUAL_HEIGHT, camera);
spriteBatch = new SpriteBatch();
}
#Override
public void show() {
viewport.apply();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
spriteBatch.setProjectionMatrix(camera.combined);
}
#Override
public void resize(int width, int height) {
viewport.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
And here is the actual screen implementation:
class LoadingScreen extends AbstractScreen {
private SpriteBatch spriteBatch;
private Texture texture;
#Override
public void show() {
super.show();
spriteBatch = new SpriteBatch();
texture = new Texture("textures/test.png");
}
#Override
public void render(float delta) {
super.render(delta);
spriteBatch.begin();
spriteBatch.draw(texture, 0, 0);
spriteBatch.end();
}
}
Thank you!
Your LoadingScreen is creating its own SpriteBatch named spriteBatch, which hides the spriteBatch in the AbstractScreen superclass.
So your LoadingScreen.render() calls super.render(), which sets up the appropriate projection matrix in AbstractScreen.spriteBatch, but then you are using LoadingScreen.spriteBatch to draw with.
So remove the spriteBatch field in LoadingScreen, and don't instantiate it there. Make the spriteBatch in AbstractScreen protected so you can access it from the subclass.
By the way, SpriteBatches must be disposed in dispose() or you will leak memory. Better yet, don't instantiate SpriteBatch inside your Screen. Instantiate a single SpriteBatch in your Game and pass it to your Screen's constructor so everything can share the same instance, rather that wasting time disposing and instantiating new ones every time you switch screens. SpriteBatch is a heavy object.

Libgdx Switching Screens and Viewports

I am having an issue when switching screens in libgdx. I am building a asteroids game clone. So first my MainMenuScreen class (which uses a Fitviewport) is rendered and then I call setScreen() to GameScreen (GameScreen doesn't use a Fitviewport) and that works except that the second screen renders as if its using a Fitviewport. If I resize the second screen then the whole window is used for rendering. Why is this happening? Here are some pictures:
MainMenuScreen class:
GameScreen class after switching screens, the screen has black bars on the side (I colored the boundary in red for you) which I don't want:
I want the GameScreen to use all the window area for rendering, and not have black bars like the MainMenu. I am not using any Fitviewport in GameScreen also.
Here are relevant parts of my MainMenuScreen class:
public class MainMenuScreen implements Screen
{
private static final String TAG = "MainMenu";
private static final int VIRTUAL_WIDTH = 400;
private static final int VIRTUAL_HEIGHT = 400;
MyGdxGame game;
...
public MainMenuScreen(MyGdxGame game)
{
this.game = game;
viewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
stage = new Stage(viewport);
// Play button listener
btnPlay.addListener( new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log(TAG, "PLAY");
MainMenuScreen.this.game.setScreen(MainMenuScreen.this.game.gameScreen);
};
});
....
}
Here is my GameScreen class:
MyGdxGame game;
OrthographicCamera guiCam;
World world;
WorldRenderer renderer;
public GameScreen(MyGdxGame game, SpriteBatch batch)
{
this.game = game;
guiCam = new OrthographicCamera(400, 400);
guiCam.position.set(400 / 2, 400 / 2, 0);
world = new World();
renderer = new WorldRenderer(game, batch, world);
}
public void draw()
{
GL20 gl = Gdx.gl;
gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.render();
}
#Override
public void show()
{
world.createLevel();
}
#Override
public void render(float delta)
{
draw();
}
#Override
public void resize(int width, int height)
{
}
#Override
public void pause()
{
}
#Override
public void resume()
{
}
#Override
public void hide()
{
}
#Override
public void dispose()
{
}
The problem is this line of code:
public void resize(int width, int height)
{
viewport.update(width, height, true);
}
Whenever you update the viewport, you are also updating the underlying opengl viewport and this causes the black bars to persist to the second screen (https://github.com/libgdx/libgdx/wiki/Viewports). Thus if you want to reset it back to normal you must use the following line of code in your second screen show() method (https://github.com/libgdx/libgdx/wiki/Scene2d):
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

libgdx simple game is stuttering a lot

I just started with libgdx and so I created a simple test application where an image just moves. The problem is that even if its an extremly simple game the image is stuttering a lot while it moves. Here is the code:
public class Game extends ApplicationAdapter {
private Entity e;
private OrthographicCamera camera;
private SpriteBatch batch;
#Override
public void create () {
batch = new SpriteBatch();
e = new Entity(50,50,"badlogic.jpg");
camera = new OrthographicCamera();
camera.setToOrtho(false, 480, 800);
camera.update();
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
e.setX(e.getX()+100 * Gdx.graphics.getDeltaTime());
batch.setProjectionMatrix(camera.combined);
batch.begin();
e.draw(batch);
batch.end();
}
The entity class:
public class Entity {
private Texture texture;
private Rectangle hitbox;
private float x,y;
public Entity(float x,float y,String texture){
this.x=x;
this.y=y;
this.texture=new Texture(Gdx.files.internal(texture));
this.hitbox=new Rectangle(x,y,this.texture.getWidth(),this.texture.getHeight());
}
public void draw(SpriteBatch sb){
sb.draw(texture, x, y);
}
public boolean collidesWith(Entity e){
return this.hitbox.overlaps(e.getHitbox());
}
public Rectangle getHitbox() {
return hitbox;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
Can someone explain me why this is stuttering?
getDeltaTime() is smoothed out over multiple frames so if a average frame takes .016 seconds and suddenly there is a frame taking .030 seconds then getDeltaTime() will just return .016. So in reality the game has progressed .030 seconds but you multiply your movement by .016.
getRawDeltaTime() gives you the real time passed since last frame. Try to use this as you multiplier. Otherwise try to log both and see if there are differences.
The benefit of using the smoothed getDeltaTime() is when frame drops happen the game will be still playable. While with getRawDeltaTime() if there would suddenly a second pass for the next frame then your velocity would get multiplied by 1 instead of .016 and could immediately go of screen or miss collision detection.

Libgdx Screen NullPointerException when switching screens

I started trying to create a TestGame. Currently having an NPE and after spending hours on google and trying everything I could think of I can't seem to understand what I'm overlooking or forgetting. I had everything in one class and all worked perfectly. Though I wanted to create a GUI where I could switch between a MainMenu and PlayScreen. My MainMenu class works fine, though when I hit my neat little "play" button to enter the PlayScreen class I get these errors:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.me.game.PlayScreen.render(PlayScreen.java:90)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.me.game.TestGame.render(TestGame.java:27)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:214)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
Playscreen error:
batch.draw(player.getCurrentFrame(), player.getPosition().x , player.getPosition().y);
Game error:
if (screen != null) screen.render(Gdx.graphics.getDeltaTime());
TestGame error:
super.render();
TestMenu class (Game class)
public class TestGame extends Game {
Game game;
#Override
public void create() {
game = this;
setScreen(new MainMenu(game));
public void render() {
super.render();
}
MainMenu class
public class MainMenu implements Screen{
SpriteBatch batch;
Game game;
Stage stage;
public MainMenu(Game game){
this.game = game;
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
batch.begin();
stage.draw();
batch.end();
}
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
game.setScreen(new PlayScreen(game));
stage.clear();
return true;
PlayScreen
public class PlayScreen implements Screen {
SpriteBatch batch;
Player player;
Game game;
Texture playerTexture;
public PlayScreen(Game game){
this.game = game;
}
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(player.getCurrentFrame(), player.getPosition().x , player.getPosition().y);
}
player.update();
batch.end();
}
public void show() {
batch = new SpriteBatch();
Player class
public class Player {
Texture playerTexture ;
Vector2 position;
String textureLoc;
public Player(Vector2 position, String textureLoc){
this.position = position;
movement = "";
playerTexture = new Texture(Gdx.files.internal("Character.png"));
public String getTextureLoc() {
return textureLoc;
}
public void setTextureLoc(String textureLoc) {
this.textureLoc = textureLoc;
}
The most helpful was Libgdx Screen NullPointerException when referencing another class where the problem also seems to be that I didn't initialize player in the PlayerScreen class at the show method. Though when I do fill player = new Player(position, textureLoc); in under the show method
public void show() {
batch = new SpriteBatch();
player = new Player(position, textureLoc);
I get other errors
at com.me.game.Player.<init>(Player.java:50)
at com.me.game.PlayScreen.show(PlayScreen.java:90)
at com.badlogic.gdx.Game.setScreen(Game.java:61)
at com.me.game.MainMenu$1.touchDown(MainMenu.java:90)
Which point to:
bounds = new Rectangle(position.x, position.y, currentFrame.getRegionWidth(), currentFrame.getRegionHeight());
player = new Player(position, textureLoc);
game.setScreen(new PlayScreen(game));
Though I assume it has something to do with the player not being initialized correctly? Anyhow for some reason I just can't seem to solve this. Any ideas would be greatly appreciated.
The problem is right here
player = new Player(position, textureLoc);
position and textureLoc are placeholders, these parameters you created are as follows
Vector2 position, String textureLoc
This means you need to create a new Vector2 and place it where position is and a String and place it where textureLoc is.
Try the following code instead, which will place your player approximately in the middle of the screen.
player = new Player(new Vector2(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2), "I am not sure why you put this parameter here");

NullPointer Exception When Trying to Update Sprite

Hello I am currently programming a LibGDX game based on physics with a ball that must stay on a platform, I have set up the physics components for the ball, but when I try updating the sprite for the ball based on the physic body's position it is giving me a null pointer exception.
I have spent 1 whole day trying to fix the problem through researching and looking at other peoples' code but cannot find my error. Thank you for your time and any input that you can give. Below I have typed the code from my Render class, Ball GameObject class, Asset class, and Exception.
Ball GameObject Class:
public class Ball {
public static World physicsWorld;
public static BodyDef ballBodyDef;
public static Body ballBody;
public static CircleShape ballShape;
public static FixtureDef ballFixtureDef;
public static Fixture ballFixture;
public Ball() {
physicsWorld = new World(new Vector2(0, -9.8f), true);
ballBodyDef = new BodyDef();
ballBodyDef.position.set(Assets.ballSprite.getX(),
Assets.ballSprite.getY());
ballBodyDef.type = BodyDef.BodyType.DynamicBody;
ballBody = physicsWorld.createBody(ballBodyDef);
ballShape = new CircleShape();
ballShape.setRadius(6f);
ballFixtureDef = new FixtureDef();
ballFixtureDef.density = 1.0f;
ballFixtureDef.friction = 0.2f;
ballFixtureDef.restitution = 0.4f;
ballFixture = ballBody.createFixture(ballFixtureDef);
}
public void dispose() {
physicsWorld.dispose();
ballShape.dispose();
}
public BodyDef getBallBodyDef() {
return ballBodyDef;
}
public void setBallBodyDef(BodyDef ballBodyDef) {
this.ballBodyDef = ballBodyDef;
}
public Body getBallBody() {
return ballBody;
}
public void setBallBody(Body ballBody) {
this.ballBody = ballBody;
}
public CircleShape getBallShape() {
return ballShape;
}
public void setBallShape(CircleShape ballShape) {
this.ballShape = ballShape;
}
public FixtureDef getBallFixtureDef() {
return ballFixtureDef;
}
public void setBallFixtureDef(FixtureDef ballFixtureDef) {
this.ballFixtureDef = ballFixtureDef;
}
public Fixture getBallFixture() {
return ballFixture;
}
public void setBallFixture(Fixture ballFixture) {
this.ballFixture = ballFixture;
}
}
Render Class:
public class GameRenderer {
private GameWorld myWorld;
private OrthographicCamera cam;
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
private SpriteBatch batch;
public GameRenderer(GameWorld world, int gameHeight, int midPointY) {
myWorld = world;
cam = new OrthographicCamera();
cam.setToOrtho(true, width, height);
batch = new SpriteBatch();
batch.setProjectionMatrix(cam.combined);
}
public void render(float delta) {
Gdx.app.log("GameRenderer", "render");
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Ball.physicsWorld.step(Gdx.graphics.getDeltaTime(), 6, 2);
Assets.ballSprite.setPosition(Ball.ballBody.getPosition().x,
Ball.ballBody.getPosition().y);
batch.begin();
batch.draw(Assets.skySprite, 0, 0, 1920, 1080);
batch.draw(Assets.ballSprite, Assets.ballSprite.getX(),
Assets.ballSprite.getY());
batch.draw(Assets.platformSprite, Assets.platformSprite.getX(),
Assets.platformSprite.getY());
batch.end();
}
}
Lastly my Assets Class:
public class Assets {
public static Texture skyTexture;
public static Sprite skySprite;
public static Texture ballTexture;
public static Sprite ballSprite;
public static Texture platformTexture;
public static Sprite platformSprite;
public static Button rightTiltButton;
public static TextureAtlas rightButtonAtlas;
public static TextButtonStyle rightButtonStyle;
public static Skin rightButtonSkin;
public static void Load() {
skyTexture = new Texture(Gdx.files.internal("Assets/skybackground.png"));
skyTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
skySprite = new Sprite(skyTexture);
skySprite.flip(false, true);
ballTexture = new Texture(
Gdx.files.internal("Assets/ballcharacter.png"));
ballTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
ballSprite = new Sprite(ballTexture);
ballSprite.flip(false, true);
ballSprite.setPosition(
Gdx.graphics.getWidth() / 2 - ballSprite.getWidth()/2,
Gdx.graphics.getHeight() / 2 - ballSprite.getHeight()-4);
platformTexture = new Texture(Gdx.files.internal("Assets/platform.png"));
platformTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
platformSprite = new Sprite(platformTexture);
platformSprite.flip(false, true);
platformSprite.setPosition(
Gdx.graphics.getWidth() / 2 - platformSprite.getWidth()/2,
Gdx.graphics.getHeight() / 2 - platformSprite.getHeight()/2);
rightButtonSkin = new Skin();
rightButtonAtlas = new TextureAtlas(
Gdx.files.internal("Assets/right_tilt_button.pack"));
rightButtonSkin.addRegions(rightButtonAtlas);
rightButtonStyle = new TextButtonStyle();
rightButtonStyle.up = rightButtonSkin.getDrawable("right_tilt_button");
rightButtonStyle.up = rightButtonSkin
.getDrawable("right_tilt_button_pressed");
rightButtonStyle.up = rightButtonSkin.getDrawable("right_tilt_button");
rightButtonStyle.over = rightButtonSkin
.getDrawable("right_tilt_button_pressed");
rightButtonStyle.down = rightButtonSkin
.getDrawable("right_tilt_button_pressed");
rightTiltButton = new Button(rightButtonStyle);
}
public static void dispose() {
skyTexture.dispose();
rightButtonAtlas.dispose();
rightButtonSkin.dispose();
ballTexture.dispose();
}
}
NullPointerException:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.manumade.tiltr.tiltrhelpers.GameRenderer.render (GameRenderer.java:36)
at com.manumade.tiltr.screens.GameScreen.render(GameScreen.java:39)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:208)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
Looking at your code and stack trace there seems to be a problem on one of this lines:
batch.draw(Assets.skySprite, 0, 0, 1920, 1080);
batch.draw(Assets.ballSprite, Assets.ballSprite.getX(),
Assets.ballSprite.getY());
batch.draw(Assets.platformSprite, Assets.platformSprite.getX(),
Assets.platformSprite.getY());
From the stack trace that you provided we can see that the error is happening on line 36:
at com.manumade.tiltr.tiltrhelpers.GameRenderer.render (GameRenderer.java:36)
Look at your GameRenderer class and see what object gets called on that line. When you receive a NullPointerException it means that you are trying to call a method or acess a variable on a object that does not point to anything (The object might never be created.)
I would assume that either:
The SpriteBatch is NULL
Assets.skySprite is NULL
Assets.ballSprite is NULL
Assets.platformerSprite is NULL
So look at the way those object get instantiated. Also make sure that you are actually initializing them before performing anything on those objects. Your render() method might be called before you actually initialize the Sprite objects in your Assets class.
It looks like a problem with drawing one of your sprites (based on the exception line number). Try replacing the sprites you have used with other ones (obviously it will look silly), and see if any of them work.
Once you know which sprites work and which ones don't, you can try and narrow down what might be different about them. I have had similar problems caused by using non-power of two textures, for example.
I see that you call:
Assets.ballSprite.setPosition(Ball.ballBody.getPosition().x,
Ball.ballBody.getPosition().y);
batch.begin();
batch.draw(Assets.skySprite, 0, 0, 1920, 1080);
batch.draw(Assets.ballSprite,
Assets.ballSprite.getX(),
Assets.ballSprite.getY());
batch.draw(Assets.platformSprite,
Assets.platformSprite.getX(),
Assets.platformSprite.getY());
batch.end();
Assets.skySprite,
Assets.ballSprite,
Assets.platformSprite
but I can not see that you call Assets.load ();
before using the above why is null, because they are not initialized only declared or I think that's the error.
try calling Assets.Load (); before that used in render method, for example inside of the your public GameRenderer(...); method.
could try to read about it AssetsManager :
https://github.com/libgdx/libgdx/wiki/Managing-your-assets
and create a loading of assets before entering the playing area.(but it's just an idea).
could look at, www some tutorial about it AssetManager.
P.S: which is the line: (GameRenderer.java:36),
sure that the staticas variables used for example in Ball, are initialized before being used in render.

Categories

Resources