2014-01-23 66 views
0

我正在做一个大学项目来制作俄罗斯方块,但是我现在被卡住了。 当我只是想改变一个数组的值时,我有一个nullpointerexception。应该很容易吧? 显然不是...Java - NullPointerException,更改数组值

我不是高级程序员,所以如果任何人都可以帮我找到不正确的代码,并具体向我解释为什么它是错误的,它将不胜感激。

这里是我的代码:

package tetris; 

import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.event.KeyEvent; 

import engine.*; 

public class Tetris extends Game { 
    private int x = 0, y = 0, maxWidth = 0, bSize = 25; 
    private int[][] field; 
    private boolean busy; 
    private Blok blok = null; 

    public Tetris() { 
     title = "Tetris"; 
     height = 600; 
     width = 400; 
     delay = 100; 
     delay2 = 10; 
     field = new int[20][10]; 
     field[19][7] = 1; 
     field[18][7] = 2; 
     field[17][7] = 3; 
     field[19][2] = 4; 
     field[19][3] = 5; 
    } 

    public static void main(String arg[]) { 
     GameApplication.start(new Tetris()); 
    } 

    @Override 
    /** 
    * Right Arrow: keycode 39 
    * Left Arrow: keycode 37 
    */ 
    public void keyPressed(KeyEvent e) { 
     if(e.getKeyCode() == 37) { 
      if (tryMove(-1)) { 
       x--; 
      } 
     } 
     else if(e.getKeyCode() == 39) { 
      if (tryMove(1)) { 
       x++; 
      } 
     } else if(e.getKeyCode() == 40) { 
      if (tryMove(0)) { 
       y++; 
      } 
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void update() { 
     if(!busy) { 
      int random = (int) (Math.random()*7); 
      //debug mode 
      random = 0; 
      /// 
      System.out.println(random); 
      blok = new Blok(random); 
      y = 1; 
      x = 3; 
      busy = true; 
     } 
     if (!tryMove(0)){ 
      field[y][x] = 1; 
      busy = false; 
     } else { 
      y++; 
     } 
     scanLine(); 
    } 

    @Override 
    public void update2() { 
    } 

    @Override 
    public void draw(Graphics2D g) { 
     g.fillRect(0, 0, width, height); 
     g.setColor(Color.LIGHT_GRAY); 
     g.fillRect(0, 0, 250, 500); 

     for (int i = 0; i<20; i++){ 
      for (int j = 0; j<10; j++){ 
       if (field[i][j]>0) { 
        g.setColor(Color.black); 
        g.fillRect(j*25,i*25,bSize,bSize); 
       } 
      } 
     } 

     if(busy) { 
      maxWidth = blok.getWidth(); 
      for (int i = 0; i<3; i++){ 
       g.fillRect(blok.getX(i)*25,blok.getY(i)*25,bSize,bSize); 
      } 
     } 
    } 

    public boolean tryMove(int a) { 
     boolean b = true; 
     if (a == -1){ 
      if (x <= 0 || field[y][x-1] != 0){ 
       b = false; 
      } 
     } else if (a == 0){ 
      if (y >= 19 || field[y+1][x] != 0){ 
       b = false; 
      } 

     } else if (a == 1){ 
      if (x >= (9-maxWidth) || field[y][x+1] != 0){ 
       b = false; 
      } 
     } 
     return b; 
    } 

    public void scanLine(){ 
     for (int i = 0; i<20; i++){ 
      boolean vol = true; 
      for (int j = 0; j<10; j++){ 
       if (field[i][j]==0) { 
        vol = false; 
       } 
      } 
      if (vol) { 
       removeLine(i); 
      } 
     } 
    } 
    public void removeLine(int a){ 
     for (int i = a; i>0; i--){ 
      for (int j = 0; j<10; j++){ 
       field[i][j] = field[i-1][j]; 
      } 
     } 
    } 
} 

并作为块(以及它出错)

package tetris; 

public class Blok { 
    private int type; 
    private int[] x,y; 
    private int width; 

    public Blok(int type) { 
     this.setType(type); 
     setCoords(type); 
     x = new int[4]; 
     y = new int[4]; 
    } 

    public int getType() { 
     return type; 
    } 

    public void setType(int type) { 
     this.type = type; 
    } 

    public void setCoords(int type) { 
     if (type == 0){ 
      setWidth(3); 
      setX(0,1); setY(0,0); 
      setX(1,2); setY(1,0); 
      setX(2,3); setY(2,0); 
      setX(3,0); setY(3,0); 
      //x[0] = 1; y[0] = 0; 
      //x[1] = 2; y[1] = 0; 
      //x[2] = 3; y[2] = 0; 
      //x[3] = 0; y[3] = 0; 
     } else if (type == 1){ 
      setWidth(2); 
      x[0] = 1; y[0] = 0; 
      x[1] = 2; y[1] = 0; 
      x[2] = 0; y[2] = -1; 
      x[3] = 0; y[3] = 0; 
     } else if (type == 2){ 
      setWidth(2); 
      x[0] = 1; y[0] = 0; 
      x[1] = 2; y[1] = 0; 
      x[2] = 2; y[2] = -1; 
      x[3] = 0; y[3] = 0; 
     } else if (type == 3){ 
      setWidth(2); 
      x[0] = 1; y[0] = 0; 
      x[1] = 2; y[1] = 0; 
      x[2] = 1; y[2] = -1; 
      x[3] = 0; y[3] = 0; 
     } else if (type == 4){ 
      setWidth(2); 
      x[0] = 1; y[0] = -1; 
      x[1] = 1; y[1] = 0; 
      x[2] = 0; y[2] = -1; 
      x[3] = 0; y[3] = 0; 
     } else if (type == 5){ 
      setWidth(1); 
      x[0] = 1; y[0] = 0; 
      x[1] = 1; y[1] = -1; 
      x[2] = 2; y[2] = -1; 
      x[3] = 0; y[3] = 0; 
     } else if (type == 6){ 
      setWidth(2); 
      x[0] = 1; y[0] = 0; 
      x[1] = 1; y[1] = 1; 
      x[2] = 2; y[2] = 1; 
      x[3] = 0; y[3] = 0; 
     } 
    } 

    public int getX(int type) { 
     return x[type]; 
    } 

    public int getY(int type) { 
     return y[type]; 
    } 

    public void setX(int index, int value){ 
     x[index] = value; //This is line 82, goes wrong here. 
    } 

    public void setY(int index, int value){ 
     y[index] = value; 
    } 

    public int getWidth() { 
     return width; 
    } 

    public void setWidth(int w) { 
     this.width = w; 
    } 

} 

这里的错误代码:

Exception in thread "Thread-2" java.lang.NullPointerException 
    at tetris.Blok.setX(Blok.java:82) 
    at tetris.Blok.setCoords(Blok.java:26) 
    at tetris.Blok.<init>(Blok.java:10) 
    at tetris.Tetris.update(Tetris.java:75) 
    at engine.Engine.run(Engine.java:18) 

回答

3

在你的构造你把

public Blok(int type) { 
     this.setType(type); 
     setCoords(type); 
     x = new int[4]; 
     y = new int[4]; 
    } 

你叫setCoords调用setX(..)setX使用xnull然后NullPointerException被抛出。

解决方法是更改​​订单。

public Blok(int type) { 
      this.setType(type); 
      x = new int[4]; 
      y = new int[4]; 
      setCoords(type);    
    } 

但是在构造函数中调用可重写的方法并不是一个好习惯。阅读更多What's wrong with overridable method calls in constructors?。解决方法是使setCoords(..) final或使您的类最终或使该方法private或从构造函数中移除并从此类的客户端代码调用它。

+0

哇...完全没有看到,谢谢。如果这不是一个好的做法,那么更好的做法是将我的“setCoords()”方法结合到构造函数中? –

+0

@ user3225821如果您可以更改它,请将'setCoords()'设为私人,并且不得公开或最终确定您的班级。另一种方法是不要在构造函数中放置'setCoords',并直接在客户端代码中调用它! – nachokk

+0

谢谢,我会牢记这一点。 :) –