2014-03-28 44 views
1

我在jMonkey引擎3中製作遊戲,我的世代代碼有點笨重,所以我打算將它移動到一個名爲Generator的新類中,但是當我終於得到了一切,並運行我的程序,我得到了一個NullPointerException在我試圖使用其他類的方法的地方。我過去碰到過NullPointerException,但這是最糟糕的一次。代碼在主類文件中工作。我會給你兩個類的代碼以及錯誤。嘗試引用從一個類到另一個類的方法= NullPointerException

請注意,我不包括包裝聲明或進口來節省空間。

類之一:主要:

public class Main extends SimpleApplication implements ActionListener { 

    private static final Logger logger = Logger.getLogger(Main.class.getName()); 
    private BulletAppState bulletAppState; 
    private CharacterControl playerControl; 
    private Vector3f walkDirection = new Vector3f(); 
    private boolean[] arrowKeys = new boolean[4]; 
    private CubesSettings cubesSettings; 
    private BlockTerrainControl blockTerrain; 
    private Node terrainNode = new Node(); 
    private Generator gen; 

    public static void main(String[] args){ 
     Logger.getLogger("").setLevel(Level.FINE); 
     AppSettings s = new AppSettings(true); 
     Main app = new Main(); 
     try { 
      s.load("com.bminus"); 
     } catch(BackingStoreException e) { 
      logger.log(Level.SEVERE, "Could not load configuration settings.",e); 
     } 
     try { 
      s.setIcons(new BufferedImage[]{ImageIO.read(new File("assets/Textures/icon.gif"))}); 
     } catch (IOException e) { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "Icon file missing",e); 
     } 
     s.setRenderer(AppSettings.LWJGL_OPENGL2); 
     s.setBitsPerPixel(24); 
     s.setFrameRate(-1); 
     s.setFullscreen(false); 
     s.setResolution(640,480); 
     s.setSamples(0); 
     s.setVSync(true); 
     s.setFrequency(60); 
     s.setTitle("The Third Power Pre-Alpha 1.1.0"); 
     try { 
      s.save("com.bminus"); 
     } catch(BackingStoreException e) { 
      logger.log(Level.SEVERE, "Could not save configuration settings.",e); 
     } 
     app.setShowSettings(false); 
     app.setSettings(s); 
     app.start(); 
    } 

    public Main(){} 

    @Override 
    public void simpleInitApp(){ 

     setDisplayFps(false); 
     setDisplayStatView(false); 
     bulletAppState = new BulletAppState(); 
     stateManager.attach(bulletAppState); 
     initControls(); 
     gen.initBlockTerrain(); //THIS LINE IS THE ONE THAT IS NULL!!! 
     initGUI(); 
     initPlayer(); 
     cam.lookAtDirection(new Vector3f(1, 0, 1), Vector3f.UNIT_Y); 
    } 

    private void initControls(){ 
     inputManager.addMapping("fps_show", new KeyTrigger(KeyInput.KEY_F3)); 
     inputManager.addMapping("fps_hide", new KeyTrigger(KeyInput.KEY_F4)); 
     inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_A)); 
     inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_D)); 
     inputManager.addMapping("forward", new KeyTrigger(KeyInput.KEY_W)); 
     inputManager.addMapping("backward", new KeyTrigger(KeyInput.KEY_S)); 
     inputManager.addMapping("jump", new KeyTrigger(KeyInput.KEY_SPACE)); 
     inputManager.addMapping("place", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); 
     inputManager.addMapping("break", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); 
     inputManager.addListener(this, "fps_show"); 
     inputManager.addListener(this, "fps_hide"); 
     inputManager.addListener(this, "left"); 
     inputManager.addListener(this, "right"); 
     inputManager.addListener(this, "forward"); 
     inputManager.addListener(this, "backward"); 
     inputManager.addListener(this, "jump"); 
     inputManager.addListener(this, "place"); 
     inputManager.addListener(this, "break"); 
    } 

    private void initGUI(){ 
     BitmapText crosshair = new BitmapText(guiFont); 
     crosshair.setText("+"); 
     crosshair.setSize(guiFont.getCharSet().getRenderedSize() * 2); 
     crosshair.setLocalTranslation(
       (settings.getWidth()/2) - (guiFont.getCharSet().getRenderedSize()/3 * 2), 
       (settings.getHeight()/2) + (crosshair.getLineHeight()/2), 0); 
     guiNode.attachChild(crosshair); 

     BitmapText instructionsText1 = new BitmapText(guiFont); 
     instructionsText1.setText("Left Click: Remove"); 
     instructionsText1.setLocalTranslation(0, settings.getHeight(), 0); 
     guiNode.attachChild(instructionsText1); 
     BitmapText instructionsText2 = new BitmapText(guiFont); 
     instructionsText2.setText("Right Click: Place"); 
     instructionsText2.setLocalTranslation(0, settings.getHeight() - instructionsText2.getLineHeight(), 0); 
     guiNode.attachChild(instructionsText2); 
     BitmapText instructionsText3 = new BitmapText(guiFont); 
     instructionsText3.setText("Bottom Layer Cannot Be Broken"); 
     instructionsText3.setLocalTranslation(0, settings.getHeight() - (2 * instructionsText3.getLineHeight()), 0); 
     guiNode.attachChild(instructionsText3); 
    } 

    private void initPlayer(){ 
     playerControl = new CharacterControl(new CapsuleCollisionShape((cubesSettings.getBlockSize()/2), cubesSettings.getBlockSize() * 2), 0.05f); 
     playerControl.setJumpSpeed(25); 
     playerControl.setFallSpeed(140); 
     playerControl.setGravity(100); 
     playerControl.setPhysicsLocation(new Vector3f(5, 257, 5).mult(cubesSettings.getBlockSize())); 
     bulletAppState.getPhysicsSpace().add(playerControl); 
    } 

    @Override 
    public void simpleUpdate(float lastTimePerFrame) { 
     float playerMoveSpeed = ((cubesSettings.getBlockSize() * 2.5f) * lastTimePerFrame); 
     Vector3f camDir = cam.getDirection().mult(playerMoveSpeed); 
     Vector3f camLeft = cam.getLeft().mult(playerMoveSpeed); 
     walkDirection.set(0, 0, 0); 
     if(arrowKeys[0]){ walkDirection.addLocal(camDir); } 
     if(arrowKeys[1]){ walkDirection.addLocal(camLeft.negate()); } 
     if(arrowKeys[2]){ walkDirection.addLocal(camDir.negate()); } 
     if(arrowKeys[3]){ walkDirection.addLocal(camLeft); } 
     walkDirection.setY(0); 
     playerControl.setWalkDirection(walkDirection); 
     cam.setLocation(playerControl.getPhysicsLocation()); 
    } 
     @Override 
     public void onAction(String actionName, boolean value, float lastTimePerFrame){ 
     if(actionName.equals("forward")) { 
      arrowKeys[0] = value; 
     } 
     else if(actionName.equals("right")) { 
      arrowKeys[1] = value; 
     } 
     else if(actionName.equals("left")) { 
      arrowKeys[3] = value; 
     } 
     else if(actionName.equals("backward")) { 
      arrowKeys[2] = value; 
     } 
     else if(actionName.equals("jump")) { 
      playerControl.jump(); 
     } 
    else if(actionName.equals("fps_show")) { 
     setDisplayFps(true); 
    } 
     else if(actionName.equals("fps_hide")) { 
      setDisplayFps(false); 
     } 
     else if(actionName.equals("place") && value){ 
      Vector3Int blockLocation = getCurrentPointedBlockLocation(true); 
      if(blockLocation != null){ 
       blockTerrain.setBlock(blockLocation, Block_Wood.class); 
      } 
     } 
     else if(actionName.equals("break") && value){ 
      Vector3Int blockLocation = getCurrentPointedBlockLocation(false); 
      if((blockLocation != null) && (blockLocation.getY() > 0)){ 
       blockTerrain.removeBlock(blockLocation); 
      } 
     } 
    } 

     private Vector3Int getCurrentPointedBlockLocation(boolean getNeighborLocation){ 
     CollisionResults results = getRayCastingResults(terrainNode); 
     if(results.size() > 0){ 
      Vector3f collisionContactPoint = results.getClosestCollision().getContactPoint(); 
      return BlockNavigator.getPointedBlockLocation(blockTerrain, collisionContactPoint, getNeighborLocation); 
     } 
     return null; 
    } 

    private CollisionResults getRayCastingResults(Node node){ 
     Vector3f origin = cam.getWorldCoordinates(new Vector2f((settings.getWidth()/2), (settings.getHeight()/2)), 0.0f); 
     Vector3f direction = cam.getWorldCoordinates(new Vector2f((settings.getWidth()/2), (settings.getHeight()/2)), 0.3f); 
     direction.subtractLocal(origin).normalizeLocal(); 
     Ray ray = new Ray(origin, direction); 
     CollisionResults results = new CollisionResults(); 
     node.collideWith(ray, results); 
     return results; 
    } 

    public void attachRootChildTerrain(){ //THIS IS CALLED IN THE GENERATOR CLASS!! 
     rootNode.attachChild(gen.terrainNode); 
    } 
} 

2類:發電機:

public class Generator { 

    private CubesSettings cubesSettings; 
    private BlockTerrainControl blockTerrain; 
    private final Vector3Int terrainSize = new Vector3Int(1000, 256, 1000); 
    private final Vector3Int bottomLayer = new Vector3Int(1000,1,1000); 
    private BulletAppState bulletAppState; 
    public Node terrainNode = new Node(); 
    private SimpleApplication sa; 
    private Main main; 

    public void initBlockTerrain(){ 
     CubesTestAssets.registerBlocks(); 
     CubesTestAssets.initializeEnvironment(sa); 

     cubesSettings = CubesTestAssets.getSettings(sa); 
     blockTerrain = new BlockTerrainControl(cubesSettings, new Vector3Int(7, 1, 7)); 
     blockTerrain.setBlocksFromNoise(new Vector3Int(), terrainSize, 20f, Block_Grass.class); 
     blockTerrain.setBlocksFromNoise(new Vector3Int(), bottomLayer, 0.0f, Block_Stone.class); 
     blockTerrain.addChunkListener(new BlockChunkListener(){ 

      @Override 
      public void onSpatialUpdated(BlockChunkControl blockChunk){ 
       Geometry optimizedGeometry = blockChunk.getOptimizedGeometry_Opaque(); 
       RigidBodyControl rigidBodyControl = optimizedGeometry.getControl(RigidBodyControl.class); 
       if(rigidBodyControl == null){ 
        rigidBodyControl = new RigidBodyControl(0); 
        optimizedGeometry.addControl(rigidBodyControl); 
        bulletAppState.getPhysicsSpace().add(rigidBodyControl); 
       } 
       rigidBodyControl.setCollisionShape(new MeshCollisionShape(optimizedGeometry.getMesh())); 
      } 
     }); 
     terrainNode.addControl(blockTerrain); 
     terrainNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); 
     main.attachRootChildTerrain(); 
    } 
} 

錯誤:

java.lang.NullPointerException 
    at com.bminus.Main.simpleInitApp(Main.java:110) 
    at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226) 
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130) 
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207) 
    at java.lang.Thread.run(Thread.java:744) 

這是我第一次試圖使用多個類。我猜測我忘記了從Generator類調用某些東西,或者做些什麼public而不是private,但我不確定。如果任何人可以弄清楚這一點,將不勝感激。謝謝!

編輯:我做你們建議的內容(我認爲),我得到這個錯誤:

Exception in thread "main" java.lang.StackOverflowError 
    at sun.misc.Unsafe.putObject(Native Method) 
    at java.util.concurrent.ConcurrentLinkedQueue$Node.<init>(ConcurrentLinkedQueue.java:187) 
    at java.util.concurrent.ConcurrentLinkedQueue.<init>(ConcurrentLinkedQueue.java:255) 
    at com.jme3.app.Application.<init>(Application.java:94) 
    at com.jme3.app.SimpleApplication.<init>(SimpleApplication.java:102) 
    at com.jme3.app.SimpleApplication.<init>(SimpleApplication.java:98) 
    at com.bminus.Main.<init>(Main.java:88) 
    at com.bminus.Generator.<init>(Generator.java:31) 
    at com.bminus.Main.<init>(Main.java:47) 

而且,因爲它是溢出錯誤最後兩個錯誤行永遠持續下去!正在稱爲錯誤在我的代碼行數:

public Main(){} 

private Main main = new Main(); 

private Generator gen = new Generator(this); 

我不知道到底爲什麼發生這種情況,但如果任何的你們這樣做了,知道如何解決這個問題真是太好了。謝謝!

+0

你提到你包括'根=新器(本);',這擺脫了空指針,但給了你期望'。你在哪裏放了'gen = new Generator(this);',它在構造函數中嗎? –

+0

你可能在'Main'的構造函數中創建'Generator'的一個實例。 'Generator'的構造函數也創建了一個'Main'本身的新實例。所以這是一個無限循環。不幸的是,你當前的代碼不適合最後一個Stacktrace。只要嘗試調試它,你會看到它! – bobbel

回答

2

調試NullPointerException的最重要的是找到引發異常的行。您嘗試在該行上使用的變量爲空。


可能的罪魁禍首:

在主類,你的發電機變量,根,從未指定一個實例,從而爲null。通過調用Generator構造函數給它一個實例。

gen = new Generator(); 

在您的Generator類中,Main字段main爲空,因爲您永遠不會爲其分配主實例。我建議你給構造函數一個Main參數,這樣你就可以將在你的main方法中創建的當前使用的Main實例(這些名字很混亂!)傳入你的Generator類並使用這個參數初始化你的main字段。

即,

public Generator(Main main) { 
    //..... 

    this.main = main; // give the main field an object 
} 

因此改變上面的代碼來創建生成器:

gen = new Generator(this); 
+0

我嘗試了你說的話,但似乎我錯過了一些非常明顯的東西,因爲無論何時將其放入代碼中,我都會看到這個錯誤:' expected'。我對Java有點新,所以我不知道這意味着什麼。你會知道如何解決這個問題嗎? – 1Poseidon3

+0

@ 1Poseidon3:沒有更多信息,我們無法幫助您。哪條線有你的錯誤?哪一行有你的NPE? –

+0

我對有錯誤的行進行了註釋,但是在這裏它是反正的:'gen.initBlockTerrain();'這行被調用爲null。 – 1Poseidon3

相關問題