2014-03-28 2 views
1

jMonkey Engine 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); 
    } 
} 

등급이 : 발전기 :

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 클래스에서 무언가를 호출하거나 private 대신에 public을 만드는 것을 잊어 버렸다. 그러나 나는 확실하지 않다. 누구나 알아낼 수 있다면 크게 감사하겠습니다. 감사!

편집 :

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

당신은'포함 언급 세대 = 새로운 생성기 (이) :

public Generator(Main main) { //..... this.main = main; // give the main field an object } 

그래서에 발전기를 만들 수 위의 코드를 변경 ' 예상 됨' 'gen = new Generator (this); '를 생성자 안에 넣었습니까? –

+0

아마도'Main'의 생성자에'Generator' 인스턴스를 생성하고있을 것입니다. Generator 생성자는 또한'Main' 자체의 새로운 인스턴스를 생성합니다. 이제는 무한 루프입니다. 불행히도 현재 코드는 마지막 Stacktrace와 맞지 않습니다. 그냥 디버깅하려고하면 그것을 볼 수 있습니다! – bobbel

답변

2

NullPointerException을 디버깅 할 때 가장 중요한 것은 예외를 throw하는 행을 찾는 것입니다. 해당 행에서 사용하려고 시도하는 변수가 널입니다.


가능한 범인 : 자신의 메인 클래스에서

, 당신의 발전기 변수 세대는, 인스턴스를 할당하지 않으며, 따라서 널 않습니다. 생성자 생성자를 호출하여 인스턴스를 지정하십시오.

gen = new Generator(); 

Generator 클래스에서 기본 필드 인 main은 할당하지 않으므로 Main 필드 인 main은 null입니다. 생성자 클래스에 Main 매개 변수를 지정하면 Main 메서드에서 생성 된 현재 사용 된 Main 인스턴스 (이 이름은 혼란 스럽습니다!)를 Generator 클래스에 전달할 수 있으며이 매개 변수를 사용하여 기본 필드를 초기화 할 수 있습니다.

즉`이 당신을 nullPointer 제거하지만 주었다있어,

gen = new Generator(this); 
+0

나는 당신이 말한 것을 시도해 보았지만 코드에 이것을 넣을 때마다 : ' expected'. 나는 다소 자바에 익숙하지 않기 때문에 이것이 무엇을 의미하는지 모른다. 이 문제를 해결하는 방법을 알고 계십니까? – 1Poseidon3

+0

@ 1 포세이돈 3 : 우리는 더 이상의 정보없이 당신을 도울 수 없습니다. 어떤 라인에 오류가 있습니까? 어떤 점에서 NPE에 문제가 있습니까? –

+0

오류가있는 줄에 주석을 달았습니다.하지만 여기에있는 내용은 다음과 같습니다.'gen.initBlockTerrain();'이 줄은 null이라고합니다. – 1Poseidon3