Camera: NullPointerException?

Hi all,



I just wanted to use the example from “JME 3 Tutorial (8) - Hello Picking” for a programme. However, for the line Ray ray = new Ray(cam.getLocation(), cam.getDirection());, a NullPointerException is thrown and I don’t know why. I don’t get an exception if I use the object cam in another method.

mhh I don’t have any exception…could you post the stackTrace please?

sure:



21.05.2011 15:40:17 com.jme3.app.Application handleError

SCHWERWIEGEND: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.NullPointerException

at base.software.Game$1.onAction(Game.java:105)

at com.jme3.input.InputManager.invokeActions(InputManager.java:143)

at com.jme3.input.InputManager.onMouseButtonEventQueued(InputManager.java:363)

at com.jme3.input.InputManager.processQueue(InputManager.java:565)

at com.jme3.input.InputManager.update(InputManager.java:600)

at com.jme3.app.Application.update(Application.java:453)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:223)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:146)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:203)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:208)

at java.lang.Thread.run(Thread.java:619)

and here is my action listener so far if it helps you:



[java]ActionListener actionListener = new ActionListener()

{

public void onAction(String name, boolean keyPressed, float tpf)

{

if (name.equals("Pause") && !keyPressed) {

setPause();

if( paused == true )

System.out.println( "Game paused" );

else

System.out.println( "Game unpaused" );

}

if( paused == false )

{

if( name.equals("Shoot") && !keyPressed ) {



}

}



if( paused == false )

{

if( name.equals( "Shoot" ) ) {

System.out.println( "shoot" );

// 1. Reset results list.

CollisionResults results = new CollisionResults();

// 2. Aim the ray from cam loc to cam direction.

Ray ray = new Ray(cam.getLocation(), cam.getDirection());

// 3. Collect intersections between Ray and Shootables in results list.

rootNode.collideWith(ray, results);

// 4. Print the results.

System.out.println("


Collisions? " + results.size() + "
");
for (int i = 0; i < results.size(); i++) {
// For each hit, we know distance, impact point, name of geometry.
float dist = results.getCollision(i).getDistance();
Vector3f pt = results.getCollision(i).getContactPoint();
String hit = results.getCollision(i).getGeometry().getName();
System.out.println("* Collision #" + i);
System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away.");
}
// 5. Use the results (we mark the hit object)
if (results.size() > 0){
// The closest collision point is what was truly hit:
CollisionResult closest = results.getClosestCollision();
// Let's interact - we mark the hit with a red dot.
mark.setLocalTranslation(closest.getContactPoint());
rootNode.attachChild(mark);
} else {
// No hits? Then remove the red mark.
rootNode.detachChild(mark);
}
}
}
}
};[/java]

Is this code used in a simpleApplication class?

If it’s not how do you initialize your ‘cam’ object?

Which one is:

at base.software.Game$1.onAction(Game.java:105)



NPE’s are the single easiest exception to debug… but we have to know the line at 105. :slight_smile:

My class Game extends the class SimpleApplication. Line 105 is [java]Ray ray = new Ray(cam.getLocation(), cam.getDirection());[/java] and I always get a NullPointerException if I want to use [java]cam[/java]. However, if I use [java]cam[/java] in the method [java]simpleInitApp()[/java] for example, everything works fine.

cam is null. That much is certain.



simpleInitApp() has access to all of SimpleApplication’s fields… like cam.



We’d have to know where your ActionListener is instantiated to know why it doesn’t also have access to them.

My main class is a manager, that connects all components of the game and that includes main() to start the game:



[java]public class CManager

{

// Interfaces

public static A a;

public static G g;



CManager()

{

a = new KeyMappings();

g = new Game();

}



public static void main( String[] args )

{

new CManager();



Game game = new Game();

game.start();

}

}[/java]



my class KeyMappings is the following:



[java]public class KeyMappings implements A

{

private Map<String, Integer> keys;

private String[] actions;



public KeyMappings()

{

actions = new String[12];

actions[0] = "Pause";

actions[9] = "Shoot";



keys = new HashMap<String, Integer>();

keys.put( actions[9] , MouseInput.BUTTON_LEFT );

}



@Override

public void setKeyMapping( Game game )

{

// Tastaturbelegung

game.getInputManager().addMapping( actions[0] , new KeyTrigger( keys.get( actions[0] )));

game.getInputManager().addMapping( actions[9] , new MouseButtonTrigger( keys.get( actions[9] )));



game.getInputManager().addListener( CManager.g.getActionListener(), new String[]{ actions[0], actions[9] } );

}

}[/java]



in the method simpleInitApp() of my class Game, I call the function CManager.a.setKeyMapping( this );

The question is : Is your cam object initialized?

According to the error, it’s not, so you’ll have to look this way.

maybe try to run in debug mode and see what happen to your cam object

Well, I just did the key mapping inside my Game class now and it works well. Thanks for your help

You have to do stuff inside the update loop. You cant just access cam from anywhere and expect it to be initialized. Your own code logic should start in simpleInitApp() and then only execute when the update loop is calling it. The thread that starts your application is a different one than the update loop thread.