尽管做得对,但是空指针异常

时间:2013-11-15 19:35:05

标签: java nullpointerexception 2d

我最近编码但遇到空指针异常 堆栈跟踪说

Exception in thread "main" java.lang.NullPointerException
at com.masterkgames.twisteddream.level.SpawnLevel.generateLevel(SpawnLevel.java:34)
at com.masterkgames.twisteddream.level.Level.<init>(Level.java:22)
at com.masterkgames.twisteddream.level.SpawnLevel.<init>(SpawnLevel.java:16)
at com.masterkgames.twisteddream.Game.<init>(Game.java:49)
at com.masterkgames.twisteddream.Game.main(Game.java:138)

以下是提到的3个类

Spawnlevel.java:     包com.masterkgames.twisteddream.level;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.masterkgames.twisteddream.level.tile.Tile;

public class SpawnLevel extends Level {

private Tile[] tiles;
private int[] levelPixels;

public SpawnLevel(String path) {
    super(path);

}

protected void loadLevel(String path){
    try{
        BufferedImage image = ImageIO.read(SpawnLevel.class.getResource(path));
        int w = image.getWidth();
        int h = image.getHeight();
        tiles = new Tile[w * h];
        levelPixels = new int[w * h];
        image.getRGB(0,0,w,h,levelPixels,0,w);
    }catch(IOException e){
        e.printStackTrace();
    }

}
protected void generateLevel(){
        for(int i = 0; i < levelPixels.length; i++){
            if(levelPixels[i] == 0xff00) tiles[i] = Tile.Grass;
            if(levelPixels[i] == 0xffff00) tiles[i] = Tile.Rose;
            if(levelPixels[i] == 0x7f7f00) tiles[i] = Tile.Stone;
        }
    }
}

level.java:

package com.masterkgames.twisteddream.level;

import com.masterkgames.twisteddream.graphics.Screen;
import com.masterkgames.twisteddream.level.tile.Tile;

public class Level {

public Screen screen;
protected int width, height;
protected Tile[] tiles;
protected int[] tilesInt;

public Level(int width, int height) {
    this.width = width;
    this.height = height;
    tilesInt = new int[width * height];
    generateLevel();
}

public Level(String path) {
    loadLevel(path);
    generateLevel();
}

protected void generateLevel() {

}

private void loadLevel(String path) {

}

public void update() {

}

private void time() {

}

public void render(int xScroll, int yScroll, Screen screen) {
    screen.setOffset(xScroll, yScroll);
    int x0 = xScroll >> 4;
    int x1 = (xScroll + screen.width + 16) >> 4;
    int y0 = yScroll >> 4;
    int y1 = (yScroll + screen.height + 16) >> 4;

    for (int y = y0; y < y1; y++) {
        for (int x = x0; x < x1; x++) {
            // getTile(x, y).render(x, y, screen);
            if (x + y * 16 < 0 || x + y * 16 >= 256) {
                Tile.Void.render(x, y, screen);
                continue;
            }
            tiles[x + y * 16].render(x, y, screen);

        }
    }
}

public Tile getTile(int x, int y) {
    if (x < 0 || y < 0)
        return Tile.Void;
    if (x >= width || y >= height)
        return Tile.Void;
    if (tilesInt[x + y * width] == 0)
        return Tile.Grass;
    if (tilesInt[x + y * width] == 1)
        return Tile.Rose;
    if (tilesInt[x + y * width] == 2)
        return Tile.Stone;

    return Tile.Void;
}

}

最后 game.java:

package com.masterkgames.twisteddream;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

import javax.swing.JFrame;

import com.masterkgames.twisteddream.entity.mob.Player;
import com.masterkgames.twisteddream.graphics.Screen;
import com.masterkgames.twisteddream.input.Keyboard;
import com.masterkgames.twisteddream.level.Level;
import com.masterkgames.twisteddream.level.SpawnLevel;

public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;

public static int width = 300;
public static int height = 168;
public static int scale = 3;

public String Title = "Twisted Dream";

private Thread thread;

private boolean running = false;

private Screen screen;
private Keyboard key;
private Level level;
private Player player;

private JFrame frame;
private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

private int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();

public Game() {
    Dimension size = new Dimension(width * scale, height * scale);
    setPreferredSize(size);

    screen = new Screen(width,height);
    key = new Keyboard();
    level = new SpawnLevel("/textures/level.png");
    player = new Player(key);

    frame = new JFrame();

    addKeyListener(key);
}

public synchronized void start() {
    thread = new Thread(this, "Display");
    thread.start();
    running = true;
}

public synchronized void stop() {
    running = false;
    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void run() {
    long lastTime = System.nanoTime();
    long timer = System.currentTimeMillis();
    final double ns = 1000000000.0 / 60.0;
    double delta = 0; 
    int frames = 0;
    int updates = 0;
    requestFocus();
    while (running) {
        long nowTime = System.nanoTime();
        delta += (nowTime - lastTime) / ns;
        lastTime = nowTime;
        while (delta >= 1){
        update();
        updates++;
        delta--;

        }
        render();
        frames++;

        if(System.currentTimeMillis() - timer > 1000){
            timer += 1000;
            System.out.println(updates + " ups, " + frames + " fps");
            frame.setTitle(Title + "  |  " + updates + " ups, " + frames + " fps");
            updates = 0;
            frames = 0;
        }
    }
    stop();
}

public void update() {
    key.update();
    player.update();
}

public void render() {
    BufferStrategy bs = getBufferStrategy();

    if (bs == null) {
        createBufferStrategy(3);
        return;
    }


    screen.clear();
    int xScroll = player.x - screen.width / 2;
    int yScroll = player.y - screen.height / 2;
    level.render(xScroll, yScroll, screen);
    player.render(screen);


    for(int i = 0; i < pixels.length; i++){
        pixels[i] = screen.pixels[i];
    }

    Graphics g = bs.getDrawGraphics();
    g.drawImage(image,0,0,getWidth(),getHeight(),null);
    g.setFont(new Font("arial", 0, 15));
    g.setColor(Color.white);
    g.dispose();
    bs.show();
}

public static void main(String[] args) {
    Game game = new Game();

    game.frame.setResizable(false);
    game.frame.setTitle(game.Title);
    game.frame.add(game);
    game.frame.pack();
    game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    game.frame.setLocationRelativeTo(null);
    game.frame.setVisible(true);

    game.start();
}

}

p.s这个问题根据堆栈跟踪在SpawnLevel.java中的(int i = 0; i&lt; levelPixels.length; i ++)行中

2 个答案:

答案 0 :(得分:2)

在Level构造函数中,你有generateLevel();你在哪里使用levelPixels,它没有被初始化

contructor call

private void loadLevel(String path) {

}
从类Level开始,你必须在SpawnLevel构造函数中调用方法loadLevel

答案 1 :(得分:0)

您正在访问null数组levelPixels。

以下是您的错误: 在你的主要调用一个新的SpawnLevel(路径) 但SpawnLevel(path)调用超级构造函数,该构造函数调用其空白但定义的loadLevel和generateLevel。从不调用SpawnLevel中的loadLevel和generateLevel,并且永远不会初始化成员变量。

所以基本上,你试图使用Level类作为抽象类,但你没有正确地做到这一点。如果要由该类的子级共享,则成员变量应位于Level类中。我猜这是你想要做的。

你应该真的熟悉调试器,它将成为这样的小问题的救星。