0

私は Java を試しています。ゲームが読み取る保存ファイルは次のように構成されています。ここに画像の説明を入力

0 は草のテクスチャです (これは機能します) が、0 を 1 に変更して草を石に変更すると、1 に変更できるように最初の 1 つを超えて機能せず、正常に機能しますが、残りは機能しません。私はしばらく座って問題を見つけようとしましたが、できません。私はより多くの情報を更新します。

ブロック型を処理するコードは次のとおりです。

public class Value {
    public static int groundGrass = 0;
    public static int groundRoad = 1;

    public static int airAir = -1;
}

これにより、ファイルの保存が処理されます。

import java.io.*;
import java.util.*;

public class Save {
    public void loadSave(File loadPath){
        try{
            Scanner loadScanner = new Scanner(loadPath);

            while(loadScanner.hasNext()){
                for(int y=0;y<Screen.room.block.length;y++){
                    for(int x=0;x<Screen.room.block[0].length;x++){
                        Screen.room.block[y][x].groundID = loadScanner.nextInt();
                    }
                }

                for(int y=0;y<Screen.room.block.length;y++){
                    for(int x=0;x<Screen.room.block[0].length;x++){
                        Screen.room.block[y][x].airID = loadScanner.nextInt();
                    }
                }
            }

            loadScanner.close();
        } catch(Exception e) { }
    }
}

これは、さまざまなブロック タイプを処理します。

import java.awt.*;

public class Block extends Rectangle{
    public int groundID;
    public int airID;

    public Block(int x, int y, int width, int height, int groundID, int airID){
        setBounds(x, y, width, height);
        this.groundID = groundID;
        this.airID = airID;
    }

    public void draw(Graphics g){
        g.drawImage(Screen.tileset_ground[groundID], x, y, width, height, null);

        if(airID !=Value.airAir){
            g.drawImage(Screen.tileset_ground[airID], x, y, width, height, null);
        }
    }
}

それが重要な部分のはずです。

e.printStackTrace(); に追加しました。(正しい場所に?)

そして、コンソールでこれを取得しました。

java.lang.NullPointerException
    at com.humans.vs.technology.Save.loadSave(Save.java:14)
    at com.humans.vs.technology.Screen.define(Screen.java:39)
    at com.humans.vs.technology.Screen.paintComponent(Screen.java:47)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JComponent.paintChildren(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JComponent.paintChildren(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JLayeredPane.paint(Unknown Source)
    at javax.swing.JComponent.paintChildren(Unknown Source)
    at javax.swing.JComponent.paintToOffscreen(Unknown Source)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
    at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
    at javax.swing.RepaintManager.paint(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
    at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
    at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
    at java.awt.Container.paint(Unknown Source)
    at java.awt.Window.paint(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.access$700(Unknown Source)
    at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

役立つ場合は完全なコードをダウンロードしてください - https://dl.dropbox.com/u/3531994/HvsT.zip

4

1 に答える 1

1

e.printStackTraceの例外ハンドラに追加するとloadSave、次の出力が生成されました。

java.lang.NullPointerException
          at com.humans.vs.technology.Save.loadSave(Save.java:14)
          at com.humans.vs.technology.Screen.define(Screen.java:39)
          at com.humans.vs.technology.Screen.paintComponent(Screen.java:47)
          ...

問題の行は次のとおりです。

Screen.room.block[y][x].groundID = loadScanner.nextInt();

以前もそうでもloadScannerなかったことがわかっているため (わずか数行上で明らかに初期化され、最初の 8 つの地上タイルが正しく読み込まれるため)、例外はおそらく から生成されると考えられます。nullnullScene.room.block[y][x].groundID

候補として排除するために使用したのと同じロジックを使用して、参照を除外し、参照からScreen.room除外することができます。いくつかあるようです。の初期化を検索すると、以下に示す が見つかります。Screen.room.blocknullloadScannerblock[y][x]nullRoom.blockRoom.define

public void define(){
    block = new Block[worldHeight][worldWidth];

    for(int y=0;y<block.length;y++){
        for(int x=0;x<block.length;x++){
            block[y][x] = new Block((Screen.myWidth/2) - ((worldWidth * blockSize)/2) + (x * blockSize), y * blockSize, blockSize, blockSize, Value.groundGrass, Value.airAir);
        }
    }
}

お気づきと思いますが、ループは[0, ]の間隔で , をxカバーしています。に対応し、問題が明らかになります。このループは、ブロック の最初の 8x8 のみを初期化します。たとえば、ブロック @ 0, 8を読み込もうとすると、それがデフォルト値であることがわかります。例外ハンドラーによってキャッチされるがスローされ、保存ファイルの残りの部分は読み取られないままになります。初期化される8x8の部分は、草に対応するデフォルト値のままです。yblock.lengthblock.lengthworldHeightScreen.room.block[y][x].groundIDnullNullPointerExceptionblocksgroundID0

  public static int groundGrass = 0;

Room.draw最初は、ループ内の呼び出しのため、これも部屋の最初の行の最初の 8 ブロックのみの未完成のレンダリングを引き起こすのではないかと思いblock[y][x].draw(g)ました...ただし、ループ条件はここでも同様に壊れています。


さて、解決策は簡単です。Room.defineおよびのループ条件を修正しますRoom.draw。たとえば、

    for(int y=0;y<worldHeight;y++){
        for(int x=0;x<worldWidth;x++){
            block[y][x] = new Block((Screen.myWidth/2) - ((worldWidth * blockSize)/2) + (x * blockSize), y * blockSize, blockSize, blockSize, Value.groundGrass, Value.airAir);
        }
    }

for Room.define、および次の for Room.draw

    for(int y=0;y<worldHeight;y++){
        for(int x=0;x<worldWidth;x++){
            block[y][x].draw(g);
        }
    }

あなたのコードは以下を生成します: http://puu.sh/YvAJ どういたしまして:-)

于 2012-08-24T23:13:28.687 に答える