Thread NullPointerException

0

Witam! Nie dawno zacząłem naukę pisania gier w Javie. Na razie uczę się z youtube, lecz po próbie dodania własnych tekstur przez SpriteSheet wywala mi błąd. Nigdzie nie mogę poszukać rozwiązania mojego problemu. Czy mógł by ktoś powiedzieć dlaczego wywala mi błąd? Na komentarze nie zwracajcie uwagi, mają pomóc w modyfikacji kodu w późniejszym czasie, gdy już będę ogarniał nieco więcej.

Treść błędu
Thread[Display](Suspended(exception NullPointerException))

  • Sprite.load() line: 33
  • Sprite.<init>(int,int,int,SpriteSheet)line:26
  • Sprite.<clinit>() line:18
  • Screen.render(int,int) line:53
  • Game.render() line: 127
    *Game.run() line:83
  • Thread.run line: not available

Klasa Screen

 



package avim.gra.graphics;

import java.util.Random;

public class Screen {

	private int width,height;
	
	public int[]pixels;
	public final int MAP_SIZE =8; // wielkosc mapy ilosci tekstur w paczce?
									//po tej cyfrze sie zapetla
	public final int MAP_SIZE_MASK = MAP_SIZE -1;
	
	public int[] tiles = new int[64*64];	//ilosc kolorow
	
	private Random random = new Random();
	
		//pobieramy z klasy game wartosci
	public Screen(int width,int height){
		this.width=width;
		this.height=height;
		pixels = new int[width*height];
		
		for(int i = 0; i<MAP_SIZE*MAP_SIZE; i++){
			tiles[i] = random.nextInt(0xffffff);
			tiles[0]=0;
		}
		
		
	}
	//czysci pixel
	public void clear(){
		for (int i =0; i <pixels.length;i++){
			pixels[i]=0;
		}
		
	}
	//rysuje pixel
	public void render(int xOffset, int yOffset){
	
		
		
		for(int y=0;y<height;y++){
			int yy = y+yOffset;;
//			if(yy<0 || yy>=height) break; //koniec renderu przy krawdzi
			for(int x = 0; x<width;x++){
				int xx = x + xOffset;;
//				if(xx<0 || xx>=width)break; //koniec renderu przy krawedzi
//				int tileIndex = (x / 16) + (y / 16) * 64;
				int tileIndex = ((xx>>4)& MAP_SIZE_MASK) + ((yy>>4)&MAP_SIZE_MASK) * MAP_SIZE;
													//x&15 bo 16x16 jest od 0 liczymy
													
				pixels[x+y*width] = Sprite.grass.pixels[(x&15)+(y+15) * 16];
				
				
			}//petla 2
			
			
		}//petla 1
		
		
		
		
	}//render
	
	
	
	
}//screen

Klasa Sprite

 



package avim.gra.graphics;

public class Sprite {
	
	public final int SIZE;
	
	private int x,y;
	public static int[] pixels;
	private SpriteSheet sheet;
	
	
	//tworzenie sprite trawy, 16-wielkosc tekstury w px
							// pierwsze 0 pozycja x w spritesheet.png
							// drugie 0 pozycja y jak wyzej
	
							// kratka nizej to zmiana x lub y o 1 wiecej
	
	public static Sprite grass = new Sprite(16,0,0,null);
	
	public Sprite(int size, int x, int y, SpriteSheet sheet){
		SIZE = size;
		pixels = new int [SIZE * SIZE];
		this.x = x * size;
		this.y = y * size;
		this.sheet = sheet;
		load();
	}
	
	private void load(){
		for(int y = 0; y<SIZE;y++){
			for(int x = 0;x<SIZE;x++){
				
				pixels[x+y*SIZE] = sheet.pixels[(x + this.x)+(y+this.y)*sheet.SIZE];
				
			}//petla x
			
			
		}//petla y
		
		
		
	}
	

}





Klasa SpriteSheet

 


package avim.gra.graphics;

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

import javax.imageio.ImageIO;

public class SpriteSheet {
	
	private String path;
	public final int SIZE;
	public int[] pixels;
															//256 wielkosc px w pliku
	public static  SpriteSheet tiles = new SpriteSheet("/textures/spritesheet.png",256);
	
	
	
	public SpriteSheet(String path, int size){
		this.path = path;
		this.SIZE=size;
		pixels = new int[SIZE*SIZE];
		load();
		
	}
	
	private void load(){
		try {
			BufferedImage image = ImageIO.read(SpriteSheet.class.getResource(path));
			int w = image.getWidth();
			int h = image.getHeight();
			image.getRGB(0, 0,w,h,pixels,0,w);
			
			
		} catch (IOException e) {
			
			e.printStackTrace();
		}
		
		
	}

}


Klasa Game

 
package avim.gra;

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

import javax.swing.JFrame;

import avim.gra.graphics.Screen;
import avim.gra.input.Keyboard;

public class Game extends Canvas implements Runnable {

	private static final long serialVersionUID = 1L;
	public static int width = 300;
	public static int height = width / 16 * 9;
	public static int scale = 3;

	private Thread thread;
	private JFrame frame;
	private Keyboard key;
	private boolean running = false;
	public static String title="Gra";
	private Screen screen;

	private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	private int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();

	
	//tworzymy cnavas
	public Game() {
		Dimension size = new Dimension(width * scale, height * scale);
		setPreferredSize(size);
		screen = new Screen(width,height);
		frame = new JFrame();
		
		key = new Keyboard();
		addKeyListener(key);
	}
//start wątku
	public synchronized void start() {
		running = true;
		thread = new Thread(this, "Display");
		thread.start();
	}
//zatryzmanie wątku
	public synchronized void stop() {
		running = false;
		try {
			thread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}
//ekran rendering i update
	@Override
	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;
		
		
		while (running) {
			long now = System.nanoTime();
			delta += (now - lastTime) / ns;
			lastTime = now;
			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();
					
			
	}
	
			
int x=0,y=0;
	
	
	public void update() {
		key.update();
		
		//porusznie mapy X i Y
		
		if(key.up) y--;
		if(key.down) y++;
		if(key.left)x--;
		if(key.right)x++;
		
		
	}
	public void render() {
		BufferStrategy bs = getBufferStrategy();
		if (bs == null) {
			createBufferStrategy(3);
			return;
		}

		
		//polaczeni z klsa screen 
		screen.clear();
		screen.render(x,y);
		
		for(int i = 0; i<pixels.length;i++){
			pixels[i]= screen.pixels[i];
		}
		
		Graphics g = bs.getDrawGraphics();

		
		// Rysowanie tutaj
		
		
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, getWidth(), getHeight());
		
		g.drawImage(image,0,0,getWidth(),getHeight(),null);
		

		g.dispose();
		bs.show();

	}
	//ustawiamy cale okno
	public static void main(String[] args) {
		Game game = new Game();
		game.frame.setResizable(false);
		game.frame.setTitle(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();

	}

}

1

Tak na szybko to prawdopodobnie tu masz problem:

 
public static Sprite grass = new Sprite(16,0,0,null);
 
    public Sprite(int size, int x, int y, SpriteSheet sheet){
        SIZE = size;
        pixels = new int [SIZE * SIZE];
        this.x = x * size;
        this.y = y * size;
        this.sheet = sheet;
        load();
    }
    private void load(){
        for(int y = 0; y<SIZE;y++){
            for(int x = 0;x<SIZE;x++){
 
                pixels[x+y*SIZE] = sheet.pixels[(x + this.x)+(y+this.y)*sheet.SIZE];
 
            }//petla x
         }//petla y
    }

Tak wygląda twój konstruktor:

public Sprite(int size, int x, int y, SpriteSheet sheet){

Na końcu masz SpriteSheet
Nie wiem dlaczego ale tak tworzysz instancję tej klasy:

public static Sprite grass = new Sprite(16,0,0,null);

Na końcu w miejscu SpriteSheet podajesz null;

A w tym miejscu:

 pixels[x+y*SIZE] = sheet.pixels[(x + this.x)+(y+this.y)*sheet.SIZE];

starasz się odwołać do pola sheet które wcześniej ustawiłeś jako null. Dlatego masz pięknego NPE.

0

Okej teraz rozumiem co zrobiłem źle, dzięki za pomoc :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1