Ajuda com jogo em java

Ola, estou fazendo um exercício de um game em java, mas quando tento movimentar meu personagem aparece um erro, mas quando mudo para printar caso a tecla seja acionada funciona, o que nao funciona eh para o personagem se movimentar.
Se possivel e alguem puder me ajudar, estou ficando louco tentando descobrir o erro.

esse eh o erro: Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException
at com.zelda.main.Main.keyPressed(Main.java:143)
at java.awt.Component.processKeyEvent(Unknown Source)

codigo:

package com.zelda.main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import com.zelda.entities.Entity;
import com.zelda.entities.Player;
import com.zelda.graficos.Spritesheet;

public class Main extends Canvas implements Runnable, KeyListener {

private static final long serialVersionUID = 1L;
private boolean isRunning;
public static JFrame frame;
private Thread thread;
private final int WIDHT = 240;
private final int HEIGHT = 160;
private final int SCALE = 3;
private BufferedImage image;
public List<Entity> entities;
public Spritesheet spritesheet;
public static Player player;

public Main() {
	setPreferredSize(new Dimension(WIDHT*SCALE,HEIGHT*SCALE));
	initFrame();
	//Inicializando objetos
	image = new BufferedImage(WIDHT,HEIGHT,BufferedImage.TYPE_INT_RGB);
	entities = new ArrayList<Entity>();
	spritesheet = new Spritesheet("/spritesheet.png");

	Player player = new Player(0,0,16,16,spritesheet.getSprite(32, 0, 16, 15));
	entities.add(player);
	addKeyListener(this);
	
}

public void initFrame() {
	frame = new JFrame("game_1");
	frame.add(this);
	frame.setResizable(false);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setVisible(true);
	frame.pack();
	frame.setLocationRelativeTo(null);
}

public synchronized void start() {
	
	isRunning = true;
	thread = new Thread(this);
	thread.start();
	
}

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

public static void main(String args[]) {
	
	Main game =  new Main();
	game.start();
}

public void tick() {
	for(int i = 0;	i < entities.size(); i++) {
		Entity e = entities.get(i);
		e.tick();
	}
}

public void render() {
	BufferStrategy bs = getBufferStrategy();
	if(bs == null) {
		createBufferStrategy(3);
		return;
	}
	Graphics g = image.getGraphics();
	g.setColor(new Color(250,250,250));
	g.setColor(Color.white);
	g.fillRect(0, 0, WIDHT, HEIGHT);
	
	//Render do game
	for(int i = 0;	i < entities.size(); i++) {
		Entity e = entities.get(i);
		e.render(g);
	}
	
	g.dispose();
	g = bs.getDrawGraphics();
	g.drawImage(image, 0, 0,WIDHT*SCALE,HEIGHT*SCALE,null);
	bs.show();
}

public void run() {
	long lastTime = System.nanoTime();
	double amountOfTicks = 60.0;
	double ns = 1000000000 / amountOfTicks;
	double delta = 0;
	int frames = 0;
	double timer = System.currentTimeMillis();
	requestFocus();
	while(isRunning) {
		long now = System.nanoTime();
		delta+= (now - lastTime) / ns;
		lastTime = now;
		
		if(delta >= 1) {
	
			tick();
			render();
			frames++;
			delta--;
		}
		if(System.currentTimeMillis() - timer >= 1000) {
			System.out.println("FPS: "+ frames);
			frames = 0;
			timer+=1000;
		}
		
	}
	
	stop();
}

public void keyPressed(KeyEvent e) {
	if(e.getKeyCode() == KeyEvent.VK_RIGHT ||
			e.getKeyCode() == KeyEvent.VK_D){
		player.r = true;
	}else if(e.getKeyCode() == KeyEvent.VK_LEFT ||
			e.getKeyCode() == KeyEvent.VK_A){
		player.l = true;
	}
	
	if(e.getKeyCode() == KeyEvent.VK_UP ||
			e.getKeyCode() == KeyEvent.VK_W){
		player.u = true;
				
	}else if(e.getKeyCode() == KeyEvent.VK_DOWN ||
			e.getKeyCode() == KeyEvent.VK_S) {
		player.d = true;
	}
}

public void keyReleased(KeyEvent e) {
	if(e.getKeyCode() == KeyEvent.VK_RIGHT ||
			e.getKeyCode() == KeyEvent.VK_D){
		player.r = false;
	}else if(e.getKeyCode() == KeyEvent.VK_LEFT ||
			e.getKeyCode() == KeyEvent.VK_A){
		player.l = false;
	}
	
	if(e.getKeyCode() == KeyEvent.VK_UP ||
			e.getKeyCode() == KeyEvent.VK_W){
		player.u = false;
				
	}else if(e.getKeyCode() == KeyEvent.VK_DOWN ||
			e.getKeyCode() == KeyEvent.VK_S) {
		player.d = false;
	}

}

public void keyTyped(KeyEvent e) {
	
}

}

classe player
package com.zelda.entities;

import java.awt.image.BufferedImage;

public class Player extends Entity {

public boolean r, l, u, d;
public double speed = 0.7;

public Player(int x, int y, int w, int h, BufferedImage sprite) {
	super(x, y, w, h, sprite);
}

public void tick() {
	
	if(r) {
		x+=speed;
	}else if(l) {
		x-=speed;
	}
	if(u) {
		y-=speed;
	}else if(d) {
		y+=speed;
	}
	
}

}

classe entity:

package com.zelda.entities;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Entity {

protected double x;
protected double y;
protected int w;
protected int h;

private BufferedImage sprite;

public Entity(int x, int y, int w, int h, BufferedImage sprite) {
	
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.sprite = sprite;
}

public void setX(int newX) {
	this.x = newX;
}
public void setY(int newY) {
	this.y = newY;
}

public int getX() {
	return (int)this.x;
}

public int getY() {
	return (int)this.y;
}

public int getW() {
	return this.w;
}

public int getH() {
	return this.h;
}

public void render(Graphics g) {
	g.drawImage(sprite, this.getX(), this.getY(), null);
}

public void tick() {
	
}

}