Java 扫描仪问题 (JFrame)

标签 java image file jframe java.util.scanner

我正在尝试使用扫描仪来编辑我的塔防游戏的关卡。但是,它不会将级别(图 block 图像)更新为自定义文件的级别(0 是草 1 是石头 -1 是什么都没有,等等)。我发现了错误,但如何修复它,我需要添加/更改什么来消除这个错误?

java.lang.NullPointerException
    at Levels.loadLevels(Levels.java:11)
    at Window.define(Window.java:28)
    at Window.paintComponent(Window.java:44)

第 11 行:for(int y=0;y<Window.room.block.length;y++) { 第 28 行:levels.loadLevels(new File("levels/level1.level")); 第 44 行:define();

这是扫描仪文件:

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

public class Levels {
    public void loadLevels(File loadPath) {
        try {
            Scanner loadLevelsScanner = new Scanner(loadPath);

            while(loadLevelsScanner.hasNext()) {

                for(int y=0;y<Window.room.block.length;y++) {
                    for(int x=0;x<Window.room.block[0].length;x++) {
                        Window.room.block[y][x].groundID = loadLevelsScanner.nextInt();
                    }
                }

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

        } catch(Exception e) {              
        }
    }
}

这是窗口文件:

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.io.*;

public class Window extends JPanel implements Runnable {

    public Thread thread = new Thread(this);        
    public static Image[] tileset_ground = new Image[100];
    public static Image[] tileset_air = new Image[100];     
    public static int myWidth, myHeight;        
    public static boolean isFirst = true;       
    public static Room room;
    public static Levels levels;

    public Window() {
        thread.start();
    }

    public void define() {
        room = new Room();
        levels = new Levels();          
        levels.loadLevels(new File("levels/level1.level"));

        for(int i=0;i<tileset_ground.length; i++) {
            tileset_ground[i] = new ImageIcon("resources/tileset_ground.png").getImage();
            tileset_ground[i] = createImage(new FilteredImageSource(tileset_ground[i].getSource(), new CropImageFilter(0, 32 * i, 32, 32)));
        }

        for(int i=0;i<tileset_air.length; i++) {
            tileset_air[i] = new ImageIcon("resources/tileset_air.png").getImage();
            tileset_air[i] = createImage(new FilteredImageSource(tileset_air[i].getSource(), new CropImageFilter(0, 32 * i, 32, 32)));
        }    
    }

    public void paintComponent(Graphics g) {
        if(isFirst) {
            define();               
            isFirst = false;
        }           
        g.clearRect(0, 0, getWidth(), getHeight());         
        room.draw(g);
    }

    public void run() { 
        while(true) {               
            if(!isFirst) {
                room.physic();
            }               
            repaint();              
            try {
                Thread.sleep(1);
            } catch(Exception e) {
            }               
        }           
    }       
}

这是房间文件:

import java.awt.*;

public class Room {
    public int worldWidth = 40;
    public int worldHeight = 20;
    public int blockSize = 32;

    public Block[][] block;

    public Room () { }
    public void define () { }    
    public void physic () { }   

    public void draw(Graphics g) {

        block = new Block[worldHeight][worldWidth];         

        for(int y=0;y<block.length;y++) {
            for(int x=0;x<block[0].length;x++) {
                block[y][x] = new Block(x * blockSize, y * blockSize, blockSize, blockSize, Value.groundGrass, Value.airAir);
                block[y][x].draw(g);
            }
        }
    }    
}

这是 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(Window.tileset_ground[groundID], x, y, width, height, null);

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

最后,这是扫描仪应该读取的自定义文件:

1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

抱歉问了这个愚蠢的问题,我是初学者。

最佳答案

一个快速而肮脏的解决方案是测试 Window.room 以及 .block 是否不为空:

        Scanner loadLevelsScanner = new Scanner (loadPath);
        if ((Window.room != null) && 
            (Window.room.block != null)) {
            // ... block until catch block 
        }

到目前为止,我编写的一个简单的测试应用程序可以工作(如果这样做的话)。

但是您需要了解“静态”是什么,以及为什么以及如何使用它。初学者常见的错误是插入“static”关键字只是为了让编译器保持沉默。

调查一下初始化类及其属性的顺序。

在Block中,要访问Window,你必须有一个引用。该引用可以传递给Block的ctor:

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

    public Block (int x, int y, int width, int height, int groundID, int airID, Window window) {
        setBounds (x, y, width, height);
        this.groundID = groundID;
        this.airID = airID;
        this.window = window;
    }
    public void draw (Graphics g) {
        g.drawImage (window.tileset_ground [groundID], x, y, width, height, null);
        if (airID != Value.airAir) {
            g.drawImage (window.tileset_air [airID], x, y, width, height, null);
        }
    }
}

谁创建区 block ?它是 Room,所以 Room 本身需要了解 Window(只要你不从根本上改变你的设计)。

public Room (Window w) {
    block = new Block [worldHeight] [worldWidth];
    for (int y=0; y <block.length; y++) {
        for (int x=0; x <block [0].length; x++) {
            block [y] [x] = new Block (x * blockSize, y * blockSize, blockSize, blockSize, Value.groundGrass, Value.airAir, w);
        }
    }
}

创建并初始化 block 数组,并将窗口参数传递给 block 。

在绘制时,您不会一遍又一遍地重新创建数组,也不会重新创建 block ,而只是重新绘制它们:

public void draw (Graphics g) {
    for (int y=0; y <block.length; y++) {
        for (int x=0; x <block [0].length; x++) {
            block [y] [x].draw (g);
        }
    }
}

在 Window 中,您创建 Room,并向其传递窗口引用:

public void define () {
    room = new Room (this);
    levels = new Levels ();

关于Java 扫描仪问题 (JFrame),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10564311/

相关文章:

java - 从结果集中输出大的 xml

jquery - CSS 图片库修改

html - 电子邮件图像不显示 (Gmail)

c - 无法从txt文件读取数据,并保持返回值3221225477

file - 埃马克。 Helm 包。如何在文件夹(不是 git 文件夹)和所有子文件夹中查找文件?

c - 使用 write() 写入文件时文件被覆盖

java - 在 JXTable 单元格中设置日期格式

java - 如何将 SQL 数据库连接到 Internet?

java - 每次单击按钮时如何在 ImageView 中旋转图像?

image - ffmpeg 将播放图像添加到缩略图输出