1

Whenever I run my program I get this error:

Exception in thread "Thread-2" java.lang.NullPointerException
    at ca.wamlab.game.entities.Player.tick(Player.java:20)
    at ca.wamlab.game.level.Level.tick(Level.java:38)
    at ca.wamlab.game.Game.tick(Game.java:169)
    at ca.wamlab.game.Game.run(Game.java:112)
    at java.lang.Thread.run(Thread.java:744)

Ignore all but the first at because all of them are because of that one.

I get that error in the following code:

package ca.wamlab.game.entities;

import ca.wamlab.game.InputHandler;
import ca.wamlab.game.gfx.Colors;
import ca.wamlab.game.gfx.Screen;
import ca.wamlab.game.level.Level;

public class Player extends Mob{

private InputHandler input;
private int color = Colors.get(-1, 111, 145, 543);

public Player(Level level, int x, int y, InputHandler input) {
    super(level, "Player", x, y, 1);
}

    public void tick() {
        int xa = 0;
        int ya = 0;
        if(input.up.isPressed()){
            ya--;
        }
        if(input.down.isPressed()){
            ya++;
        }
        if(input.right.isPressed()){
            xa++;
        }
        if(input.left.isPressed()){
            xa--;
        }


        if (xa != 0 || ya != 0){
            move(xa, ya);
            isMoving = true;
        }else{
            isMoving = false;
        }
    }

    public void render(Screen screen) {
        int xTile = 0;
        int yTile = 28;

        int modifier =  8*scale;
        int xOffset = x - modifier/2;
        int yOffset = y - modifier /2-4;

        screen.render(xOffset, yOffset, xTile + yTile * 32, color);
        screen.render(xOffset + modifier, yOffset, (xTile + 1) + yTile * 32, color);

        screen.render(xOffset, yOffset + modifier, xTile + (yTile + 1) * 32, color);
        screen.render(xOffset + modifier, yOffset + modifier, (xTile + 1) + (yTile + 1) *      32, color);


    }

    public boolean hasCollided(int xa, int ya) {
        return false;
    }

}

And the input class is:

package ca.wamlab.game;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class InputHandler implements KeyListener{

    public InputHandler(Game game) {
        game.addKeyListener(this);
    }

    public class Key {
        private int numTimesPressed;
        private boolean pressed = false;

        public int getNumTimesPressed(){
            return numTimesPressed;
        }

        public boolean isPressed(){
            return pressed;
        }
        public void toggle(boolean isPressed){
            pressed = isPressed;
            if(isPressed)numTimesPressed++;
        }
    }

    public Key up = new Key();
    public Key down = new Key();
    public Key right = new Key();
    public Key left = new Key();

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        toggleKey(e.getKeyCode(), true);
    }

    public void keyReleased(KeyEvent e) {
        toggleKey(e.getKeyCode(), false);
    }

    public void toggleKey(int keyCode, boolean isPressed){
        if(keyCode == KeyEvent.VK_W  || keyCode == KeyEvent.VK_UP){ up.toggle(isPressed);}
        if(keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN){ down.toggle(isPressed);}
        if(keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT){ right.toggle(isPressed);}
        if(keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT){left.toggle(isPressed);}




    }
}

I know I get this because of the fact that something in the code is set to null (I think it is the ispressed()) but I can't figure out a way to fix it...

14
  • 2
    Where exactly is line 20? Commented Jul 1, 2014 at 23:23
  • I think you are having a thread race. What do you think about that? It would explain the null from anyone of your values that are not declared before the race condition started. Commented Jul 1, 2014 at 23:30
  • 1
    Sorry line 20 is if(input.up.isPressed()){ Commented Jul 1, 2014 at 23:43
  • 1
    @Wamlab isPressed is a method that returns boolean. It can never return null, if that is what you mean by 'isPressed is null'. Commented Jul 2, 2014 at 0:12
  • 1
    @Wamlab - That was not intended to be snarky. It was meant to point out that your approach to debugging is flawed. I didn't just mean "think about" in the sense of "try hard". I meant "think about it" in the sense of "use sound logical deduction". Clearly, stuff like "I think that IsPressed is null ..." is not logical. It is a purely intuitive statement that is not supported by any facts or (sound) logical reasoning / inference. (In fact, it is contradicted by at least two facts that we do know to be true.) Commented Jul 2, 2014 at 0:52

1 Answer 1

2

The instance variables up, down, right, left in InputHandler class are initialized with

public Key up = new Key();
public Key down = new Key();
public Key right = new Key();
public Key left = new Key();

If input is a reference variable of InputHandler and an object of InputHandler is assinged to it, then the up, down, right and left can never be null based on above code. Therefore based on confirming the line 20 is if(input.up.isPressed()){ most possibly input is null.

It will help us help you, if you can provide code where InputHander input is assigned an object if anywhere done so. Where in the code the key listener registered using addKeyListenter() method? And also the provided tick() method belongs to which class?

From stacktrace it is evident that all three Player, Level and Game classes have method with same name tick()

at ca.wamlab.game.entities.Player.tick(Player.java:20)
    at ca.wamlab.game.level.Level.tick(Level.java:38)
    at ca.wamlab.game.Game.tick(Game.java:169)

Many important details are unknown to help with this. More details would be helpful.

Sign up to request clarification or add additional context in comments.

10 Comments

The Game Tick Method Calls to the Level Tick MEthod Which calls to the player tick method where the NPE is occuring
The Main (game) Tick Method public void tick(){ tickCount++; level.tick(); }
@Wamlab then the input is possibly null. Where is the input assigned with InputHandler object?
In the constructor public Player(Level level, int x, int y, InputHandler input) { the input argument is not assigned to the instance variable input. You need to add this.input = input; after super(level, "Player", x, y, 1); inside constructor.
@Wamlab - Do this logically. Read the stacktrace. Read the source code. what is calling what? How does this get the stacktrace you are seeing? Why is that wrong with your code that would cause that? You need to learn to do this yourself ...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.