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");
Related
I want a camera to follow an Actor. I've watched a lot of tutorials on how to do this but I get a weird bug.
The Actor i created called "skeleton" seems to move away from the camera and not on the X axis.
The camera moves over static sprites fine.
I used 3 different types of moving the actor. None of them seem to work.
Sry for the bad code aswell.
Playscreen:
public class PlayScreen implements Screen {
OrthographicCamera camera;
Table table;
Stage stage;
Viewport viewport;
private MyGdxGame game;
skeleton skeleton;
public PlayScreen(MyGdxGame game){
this.game = game;
camera = new OrthographicCamera(1f, (Gdx.graphics.getHeight()/Gdx.graphics.getWidth()));
viewport =new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),camera);
skeleton = new skeleton();
stage = new Stage(new ScreenViewport());
skeleton.setPosition((Gdx.graphics.getWidth()/2)-(skeleton.getWidth()/2),((Gdx.graphics.getHeight()/1.75f)-(skeleton.getHeight()/1.4f)));
stage.addActor(skeleton);
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1,0,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
skeleton.moveRight();
camera.position.x = skeleton.getX() + skeleton.getOriginX();
camera.position.y = skeleton.getY() + skeleton.getOriginY();
camera.update();
game.batch.setProjectionMatrix(camera.combined);
Gdx.input.setInputProcessor(stage);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void resize(int width, int height) {
viewport.update(width,height);
}
Skeleton Actor:
public class skeleton extends Actor {
SpriteBatch batch;
Texture img;
int frame = 0;
int zeile = 0;
TextureRegion[][] regions;
public Sprite sprite;
public skeleton(){
batch = new SpriteBatch();
img = new Texture(Gdx.files.internal("Warrior Skeleton Animations/Walking/walk.png"));
//ANIMATION
regions = TextureRegion.split(img,572,953);
sprite = new Sprite(regions[0][0]);
code to make it an animation...
(works fine don't wont to enlarge the code here any further)
setBounds(sprite.getX(),sprite.getY(),sprite.getWidth(),sprite.getHeight());
}
public void moveRight(){
//First way of moving
MoveByAction mba = new MoveByAction();
mba.setAmount(10f,0f);
mba.setDuration(1/10f);
skeleton.this.addAction(mba);
//Second way of moving
//this.setPosition(this.getX()+10,this.getY());
//setBounds(sprite.getX(),sprite.getY(),sprite.getWidth(),sprite.getHeight());
//Third way of moving
//sprite.translateX(1);
//setBounds(sprite.getX(),sprite.getY(),sprite.getWidth(),sprite.getHeight());
}
#Override
protected void positionChanged() {
sprite.setPosition(getX(),getY());
super.positionChanged();
}
#Override
public void draw(Batch batch, float parentAlpha){
sprite.draw(batch);
}
#Override
public void act(float delta) {
super.act(delta);
}
}
I've tried moving the camera independently from the skeleton actor like this: camera.position.x = camera.position.x + 100; And the actor still moves away from the camera even if the camera moves faster than the actor.
I also tried moving the camera with the coordinates of the sprite itself from the skeleton actor. Same error though.
Thanks in advance.
I found a way to fix it for me.
If i move the camera itself and not the actor, I get the effect of the actor being moved. This proofs that my actor is bound to my Camera.
I would still love to know why that is and how to fix it though.
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.
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.
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());
I have a render method and I can't figure out why it isn't happening. Here's the code I have so far:
public class DevMaze extends Game {
SpriteBatch batch;
BitmapFont font;
public void create() {
...
this.setScreen(new MainMenuScreen(this));
...
}
public void render() {
super.render();
}
...
}
The MainMenuScreen gets set and renders just fine, here's the code:
public class MainMenuScreen implements Screen {
final DevMaze game;
OrthographicCamera camera;
public MainMenuScreen(final DevMaze g) {
this.game = g;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
}
public void render(float delta) {
...
if (Gdx.input.isTouched()) {
game.setScreen(new GameScreen(game)); // This line runs
dispose();
}
}
But when I set the screen to my GameScreen, the Constructor runs just fine, but the render method never fires:
public class GameScreen implements Screen {
final DevMaze game;
OrthographicCamera camera;
...
public GameScreen(final DevMaze g) {
this.game = g;
// Create Camera
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
// Load assets
...
System.out.println("ONE MORE LINE!"); // This prints
}
public void render() {
System.out.println("MADE IT TO GAME SCREEN"); // This does not prints
...
}
I need to know why the render method is not firing.
I really don't know where to go from here. Every other resource I can find tells me to make sure I have super.render() in my game extending class - which I do. I tried to remove the code I thought would be irrelevant and leave the pertinent stuff, but if there is any other information that you would need to figure out what's going on here just let me know.
This is also one of my first projects with LibGDX, so if this is a stupid question sorry in advance!
Thanks.
public void render() needs to be public void render(float deltaTime) in your GameScreen class. I assume that you have another method with the deltaTime in your GameScreen, which gets fired instead, because otherwise it wouldn't compile.