java - Java 中纹理仅显示在第一行

标签 java eclipse

我正在尝试使用Java,我有一个游戏读取的保存文件,其组成如下; enter image description here

0 是草纹理(这有效),但是当我将 0 更改为 1 以将草更改为石头时,它在第一个之后不起作用,就像我可以将它们更改为 1 一样,它工作得很好,但不是休息。我已经坐下来试图找出问题一段时间了,但找不到。我将更新更多信息。

处理 block 类型的代码是这样的;

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) { }
    }
}

这处理不同的 block 类型;

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

最佳答案

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 没有为 null 并且之前也不是 null (因为它显然只是初始化了一个上面几行,并且前 8 个地面图 block 加载正确),我们认为异常可能是由 Scene.room.block[y][x].groundID 产生的。

我们可以使用与之前相同的逻辑将 Screen.roomScreen.room.block 排除为 null 引用排除 loadScanner 作为候选者。看起来有些block[y][x]null。搜索 Room.block 的初始化,我们找到 Room.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, block.length]< 中的 x, y/em>; block.length 对应于 worldHeight,问题就清楚了:这个循环只初始化了 block 的前 8x8。一旦我们尝试读入 Screen.room.block[y][x].groundID ,例如 block @ 0, 8,我们发现它是默认值 null。抛出一个 NullPointerException ,它被异常处理程序捕获,并且保存文件的其余部分保持未读状态。 初始化blocks部分的groundID保留为默认值0,它对应于草:

  public static int groundGrass = 0;

起初,我怀疑这也会导致房间第一行中的前 8 个 block 的渲染未完成,因为 Room.draw 调用 block[y] [x].draw(g) 在循环中...但是,您的循环条件在这里也同样被破坏。

<小时/>

现在,解决方案很简单。更正 Room.defineRoom.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);
        }
    }

对于Room.define,以及以下对于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 不客气:-)

关于java - Java 中纹理仅显示在第一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12117415/

相关文章:

java - 数组不返回字符串

java - 是否有一种独立于格式的方法来处理 JVM 上的文件?

eclipse - 无法让 Symfony2 Eclipse 插件工作

java - 如何在 Eclipse 中移动条件断点?

java - Eclipse Mars 自动完成问题

java - 在 ExecutorService 上调用 shutdown() 的原因

java - 如何在 Java 1.4 中设置 BufferedReader 和 PrintWriter 的超时?

Java - 加载 PHP 网页(Just LOAD)

c++ - git clone 修改eclipse C/C++项目包含路径

java - 使用 Eclipse 调试不同的命令行参数