Reputation: 622
I'm doing a collegeproject to make tetris, however I'm stuck at the moment. I have a nullpointerexception when I simply want to change a value of an array. Should be easy right? Apparently not...
I'm not an advanced programmer yet, so if anyone could help me find the incorrect code, and specifically explain to me why it's wrong, it'll be appreciated.
Here's my code:
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];
}
}
}
}
and for making the block(and where it goes wrong)
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;
}
}
Here's the errorcode:
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)
Upvotes: 0
Views: 131
Reputation: 14413
In your constructor you put
public Blok(int type) {
this.setType(type);
setCoords(type);
x = new int[4];
y = new int[4];
}
You call setCoords
that calls setX(..)
and setX
use x
that is null
then NullPointerException
is thrown.
A workaround is to change order.
public Blok(int type) {
this.setType(type);
x = new int[4];
y = new int[4];
setCoords(type);
}
But calling an overridable method in a constructor is not a good practice. Read more What's wrong with overridable method calls in constructors?. A workaround is making setCoords(..)
final or making your class final or make that method private
or remove from constructor and call it from client code of this class.
Upvotes: 3