2D Geometry Wars Help

Been following an awesome tutorial for making a version of geometry wars and I’ve run into a problem.
I’m realitvy new to this and can’t figure a way to allow the blastermain class to access the player object from the main class. Tried making the object public.
Help?

Exception in thread “main” java.lang.NullPointerException
at mygame.Main.getSpatial(Main.java:59)
at mygame.Main.<init>(Main.java:19)
at mygame.Main.main(Main.java:21)
Java Result: 1

MAIN:

[java]package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.texture.Texture2D;
import com.jme3.ui.Picture;

/**

  • test

  • @author normenhansen
    */
    public class Main extends SimpleApplication {

    public Spatial player = getSpatial(“Player”);
    public static void main(String[] args) {
    Main app = new Main();
    app.start();
    }

    @Override
    public void simpleInitApp() {
    // setup camera for 2D games
    cam.setParallelProjection(true);
    cam.setLocation(new Vector3f(0,0,0.5f));
    getFlyByCamera().setEnabled(false);

// turn off stats view
setDisplayStatView(false);
setDisplayFps(false);

// add a player

   player.setUserData("alive", true);
   player.move(settings.getWidth()/2, settings.getHeight()/2, 0);
   player.addControl(new PlayerControl(settings.getWidth(), settings.getHeight()));
   guiNode.attachChild(player);
}

@Override
public void simpleUpdate(float tpf) {
    //TODO: add update code
}

@Override
public void simpleRender(RenderManager rm) {
    //TODO: add render code
}

private Spatial getSpatial(String name){
    
    Node node = new Node(name);

// load picture
Picture pic = new Picture(name);
Texture2D tex = (Texture2D) assetManager.loadTexture(“Textures/”+name+".png");
pic.setTexture(assetManager,tex,true);

// adjust picture
float width = tex.getImage().getWidth();
float height = tex.getImage().getHeight();
pic.setWidth(width);
pic.setHeight(height);
pic.move(-width/2f,-height/2f,0);

// add a material to the picture
Material picMat = new Material(assetManager, “Common/MatDefs/Gui/Gui.j3md”);
picMat.getAdditionalRenderState().setBlendMode(BlendMode.AlphaAdditive);
// ^ overlapping transparent parts of multiple pictures will get brighter = make explosions brighter
node.setMaterial(picMat);

// set radius of the spatial (use width only as an approx)
node.setUserData(“radius”, width/2);

// attach pic to node and return it
node.attachChild(pic);
return node;
}
}
[/java]

BLASTERMAIN (where the problem is underlinded and in bold)

[java]
/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;

/**
*

  • @author Ezra
    */
    public class BlasterMain extends SimpleApplication implements ActionListener {

    @Override
    public void simpleInitApp() {

     inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_LEFT));
     inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_RIGHT));
     inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_UP));
     inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN));
     inputManager.addMapping("return", new KeyTrigger(KeyInput.KEY_RETURN));
     inputManager.addListener(this, "left");
     inputManager.addListener(this, "right");
     inputManager.addListener(this, "up");
     inputManager.addListener(this, "down");
     inputManager.addListener(this, "return");
    

    }

// tells the program what to do when a key is pressed
public void onAction(String name, boolean isPressed, float tpf) {

   <strong>&lt;span style="text-decoration:underline;"&gt; if ((Boolean) player.getUserData("alive")) {
    if (name.equals("up")) {
       player.getControl(PlayerControl.class).up = isPressed;
    } else if (name.equals("down")) {
        player.getControl(PlayerControl.class).down = isPressed;
    } else if (name.equals("left")) {
        player.getControl(PlayerControl.class).left = isPressed;
    } else if (name.equals("right")) {
        player.getControl(PlayerControl.class).right = isPressed;
    }&lt;/span&gt;</strong>

}

}

}

[/java]

Don’t think this is needed but here’s the PlayerControl

[java]
/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package mygame;

import com.jme3.math.FastMath;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.control.AbstractControl;

/**
*

  • @author Ezra
    */
    public class PlayerControl extends AbstractControl {

    private int screenWidth, screenHeight;

// is the player moving?
public boolean up, left, down, right;
// speed of the player
private float speed = 800f;
// last rotation of the player
private float lastRotation;

public PlayerControl(int width, int height){
    this.screenHeight = height;
    this.screenWidth = width;
}

@Override
protected void controlUpdate(float tpf) {

// move the player in a certain direction
// if he is not out of the screen
if (up) { //checks whether the player can go up and if it can go up any further
if (spatial.getLocalTranslation().y < screenHeight - (Float)spatial.getUserData(“radius”)) {
spatial.move(0,tpfspeed,0);
}
spatial.rotate(0,0,-lastRotation + FastMath.PI/2);
lastRotation=FastMath.PI/2;
// set player facing origianl direction, then face it where we want and save that rotation
} else if (down) {
if (spatial.getLocalTranslation().y > (Float)spatial.getUserData(“radius”)) {
spatial.move(0,tpf
-speed,0);
}
spatial.rotate(0,0,-lastRotation + FastMath.PI1.5f);
lastRotation=FastMath.PI
1.5f;
} else if (left) {
if (spatial.getLocalTranslation().x > (Float)spatial.getUserData(“radius”)) {
spatial.move(tpf*-speed,0,0);
}
spatial.rotate(0,0,-lastRotation + FastMath.PI);
lastRotation=FastMath.PI;
} else if (right) {
if (spatial.getLocalTranslation().x < screenWidth - (Float)spatial.getUserData(“radius”)) {
spatial.move(tpf*speed,0,0);
}
spatial.rotate(0,0,-lastRotation + 0);
lastRotation=0;
}
}

@Override
protected void controlRender(RenderManager rm, ViewPort vp) {}

// reset the moving valuse for spawn
public void reset(){
up = false;
down = false;
right = false;
left = false;
}

}
[/java]

Thanks!

I’m dumb, thought it would actually underline and bold.

if ((Boolean) player.getUserData(“alive”)) {
if (name.equals(“up”)) {
player.getControl(PlayerControl.class).up = isPressed;
} else if (name.equals(“down”)) {
player.getControl(PlayerControl.class).down = isPressed;
} else if (name.equals(“left”)) {
player.getControl(PlayerControl.class).left = isPressed;
} else if (name.equals(“right”)) {
player.getControl(PlayerControl.class).right = isPressed;
}

This:
public Spatial player = getSpatial(“Player”);

…is run when the application is constructed. But not of the stuff in JME is initialized until simpleInitApp(). In other words, you cannot run that there. You must run the getSpatial() from somewhere else (probably simple init).

Thanks, that fixed the problem of it not running, but

it still can’t find the variable.

Did you move the whole line or just the get call?!?

You still have to have the field there. You just can’t initialize it there.

Note: these aren’t really JME issues but beginner Java issues. Some Java tutorials and/or a Java developers forum might be good to have in your bookmarks list, too.