2013-12-12 56 views
0

当我运行这个非常基础的2D游戏时,我一直在获得NPE。它与关键事件有关,但我不知道如何解决这个问题。有人能帮我吗?报告说,NPE在这一行if (_input.up.isPressed()) {在2D游戏线程中获得NPE

这里是InputHandler类

public class InputHandler implements KeyListener { 

    public InputHandler(Game game) { 
     game.addKeyListener(this); 
    } 

    public class Key { 
     private boolean pressed = false; 

     public void toggle(boolean isPressed) { 
      pressed = isPressed; 
     } 

     public boolean isPressed() { 
      return pressed; 
     } 
    } 

    // public List<Key> keys = new ArrayList<Key>(); 
    public Key up = new Key(); 
    public Key down = new Key(); 
    public Key left = new Key(); 
    public Key right = new Key(); 

    public void keyPressed(KeyEvent e) { 
     toggleKey(e.getKeyCode(), true); 
    } 

    public void keyReleased(KeyEvent e) { 
     toggleKey(e.getKeyCode(), false); 
    } 

    public void keyTyped(KeyEvent e) { 

    } 

    public void toggleKey(int keyCode, boolean isPressed) { 
     if (keyCode == KeyEvent.VK_W) { 
      up.toggle(isPressed); 
     } else if (keyCode == KeyEvent.VK_S) { 
      down.toggle(isPressed); 
     } else if (keyCode == KeyEvent.VK_A) { 
      left.toggle(isPressed); 
     } else if (keyCode == KeyEvent.VK_D) { 
      right.toggle(isPressed); 
     } 
    } 
} 

这里是球员类

public class Player extends Mob { 

    private InputHandler _input; 
    private int _speed; 
    private int _r = 10; 
    private int _x, _y; 

    public Player(int x, int y, int speed, InputHandler input) { 
     super("Player", x, y, 1); 
     _input = input; 
     _speed = speed; 
     _x = x; 
     _y = y; 
    } 

    public boolean hasCollided(int dx, int dy) { 
     return false; 
    } 

    public void update() { 
     int dx = 0; 
     int dy = 0; 

     if (_input.up.isPressed()) { 
      dy--; 
     } else if (_input.down.isPressed()) { 
      dy++; 
     } else if (_input.left.isPressed()) { 
      dx--; 
     } else if (_input.right.isPressed()) { 
      dx++; 
     } 

     if (dx != 0 || dy != 0) { 
      move(dx, dy); 
      isMoving = true; 
     } else { 
      isMoving = false; 
     } 

     if (_x < _r) 
      _x = _r; 
     if (_y < _r) 
      _y = _r; 
     if (_x > Game.WIDTH - _r) 
      _x = Game.WIDTH - _r; 
     if (_y > Game.HEIGHT - _r) 
      _y = Game.HEIGHT - _r; 
    } 

    public void render(Graphics2D g) { 
     g.setColor(Color.BLACK); 
     g.fillOval(x - _r, y - _r, 2 * _r, 2 * _r); 

     g.setStroke(new BasicStroke(3)); 
     g.setColor(Color.GRAY); 
     g.drawOval(x - _r, y - _r, 2 * _r, 2 * _r); 
     g.setStroke(new BasicStroke(1)); 
    } 
} 

这里是造成玩家的游戏类

public class Game extends Canvas implements Runnable { 

    private static Game _instance; 
    private static final String TITLE = "ProjectG"; 
    public static final int WIDTH = 960; 
    public static final int HEIGHT = WIDTH * 3/4; 
    private static final int SCALE = 1; 
    // to make it have a higher resolution double the width and height but half 
    // the scale. You are doubling the width and height but keeping the same 
    // window size by reducing the scale 
    public static final Dimension SIZE = new Dimension(WIDTH * SCALE, HEIGHT * SCALE); 

    private static final int UPDATE_RATE = 60; 
    private static final int RENDER_RATE = 60; 

    private JFrame _frame; 
    private Thread _thread; 
    private boolean _running = false; 

    private int _tps = 0; 
    private int _fps = 0; 
    private int _totalTicks = 0; 

    private BufferedImage image; 
    private Graphics2D g; 
    public InputHandler input; 

    private Player player; 

    public Game() { 
     _instance = this; 

     setPreferredSize(SIZE); 
     setMinimumSize(SIZE); 
     setMaximumSize(SIZE); 

     _frame = new JFrame(TITLE); 
     _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     _frame.setLayout(new BorderLayout()); 
     _frame.add(_instance, BorderLayout.CENTER); 
     _frame.pack(); 

     _frame.setResizable(false); 
     _frame.setLocationRelativeTo(null); 
     _frame.setVisible(true); 

     player = new Player(Game.WIDTH/2, Game.HEIGHT/2, 1, input); 
    } 

    public synchronized void start() { 
     _running = true; 
     _thread = new Thread(this, TITLE + "_main"); 
     _thread.start(); 
    } 

    public synchronized void stop() { 
     _running = false; 

     if (_thread != null) { 
      try { 
       _thread.join(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void run() { 
     double lastUpdateTime = System.nanoTime(); 
     double lastRenderTime = System.nanoTime(); 

     final int ns = 1000000000; 
     final double nsPerUpdate = (double) ns/UPDATE_RATE; 
     final double nsPerRender = (double) ns/RENDER_RATE; 
     final int maxUpdatesBeforeRender = 1; 

     int lastSecond = (int) lastUpdateTime/ns; 
     int tickCount = 0; 
     int renderCount = 0; 

     image = new BufferedImage(WIDTH * SCALE, HEIGHT * SCALE, BufferedImage.TYPE_INT_RGB); 
     g = (Graphics2D) image.getGraphics(); 

     while (_running) { 
      long currTime = System.nanoTime(); 
      int tps = 0; 

      while ((currTime - lastUpdateTime) > nsPerUpdate && tps < maxUpdatesBeforeRender) { 
       update(); 
       tickCount++; 
       _totalTicks++; 
       tps++; 
       lastUpdateTime += nsPerUpdate; 
      } 

      if (currTime - lastUpdateTime > nsPerUpdate) { 
       lastUpdateTime = currTime - nsPerUpdate; 
      } 

      float interpolation = Math.min(1.0F, (float) ((currTime - lastUpdateTime)/nsPerUpdate)); 
      render(interpolation); 
      draw(); 
      renderCount++; 
      lastRenderTime = currTime; 

      int currSecond = (int) (lastUpdateTime/ns); 
      if (currSecond > lastSecond) { 
       _tps = tickCount; 
       _fps = renderCount; 
       tickCount = 0; 
       renderCount = 0; 
       lastSecond = currSecond; 
       System.out.println(_tps + " TPS " + _fps + " FPS"); 
      } 

      while (currTime - lastRenderTime < nsPerRender && currTime - lastUpdateTime < nsPerUpdate) { 
       Thread.yield(); 
       try { 
        Thread.sleep(1); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       currTime = System.nanoTime(); 
      } 
     } 
    } 

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

    public void render(float interpolation) { 
     BufferStrategy bs = getBufferStrategy(); 
     if (bs == null) { 
      createBufferStrategy(3); 
     } 

     g.setColor(Color.WHITE); 
     g.fillRect(0, 0, WIDTH * SCALE, HEIGHT * SCALE); 
     g.setColor(Color.BLACK); 
     g.drawString("TPS: " + _fps + " FPS: " + _fps, 10, 20); 

     player.render(g); 
    } 

    public void draw() { 
     Graphics g2 = this.getGraphics(); 
     g2.drawImage(image, 0, 0, null); 
     g2.dispose(); 
    } 

    public Game getGame() { 
     return this; 
    } 
} 
+0

你是如何创建你的球员>? –

+0

@SotiriosDelimanolis增加了创建玩家的类 – zachstarnes

回答

0

您尚未初始化input,所以您传递给

player = new Player(Game.WIDTH/2, Game.HEIGHT/2, 1, input); 

null。你需要先初始化它

input = new InputHandler(this); 
+0

我在游戏构造函数中初始化了'input',它仍然给我同样的一个。 – zachstarnes

+0

没关系我在玩家初始化之后放置了初始化,所以我将它移到了上面并且它工作正常。但按下按键时,播放器不动 – zachstarnes