蛇游戏,开始

时间:2013-05-06 20:34:32

标签: java eclipse swing

我已修复错误,但仍无法启动游戏

这是一场蛇游戏,我无法开始。当我尝试在Eclipse上运行它时,它一直在给我

Exception in thread "main" java.lang.NullPointerException
at Snake.createSnake(Snake.java:110)
at Snake.<init>(Snake.java:95)
at Driver.main(Driver.java:6)

我只需要有人请解释并帮我解决这个问题。我问了很多朋友,我知道没有人可以帮我解决。

public class Driver {


    public static void main(String[] args) {

    Snake game = new Snake();
    }

}

以下是这个Snake课程。

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import java.util.*;



@SuppressWarnings("serial")
class Snake extends JFrame implements KeyListener, Runnable{

JPanel gamePanel, scorePanel;
JButton extraFood;
JTextArea textAreaScore;
int x = 500;
int y = 250;
int minSnake = 3;
int directionx = 1;
int directiony = 0;
int speed = 50;
int difference = 0;
int oldx = 0;
int oldy = 0;
int score = 0;
boolean food = false;
boolean runLeft = false;
boolean runRight = true;
boolean runUp = true;
boolean runDown = true;
boolean bonusFlag = true;
Random ran = new Random();
JButton[] bc = new JButton[200];
int[] bx = new int[300];
int[] by = new int[300];
Thread myThread;
Point[] bp = new Point[300];
Point bonusp = new Point();


//initializing values
public void Values() {
    minSnake = 3;
    directionx = 10;
    directiony = 0;
    difference = 0;
    score = 0;
    food = false;
    runLeft = false;
    runRight = true;
    runUp = true;
    runDown = true;
    bonusFlag = true;
}

//sets layout of game
public Snake() {
    getContentPane().setBackground(Color.GRAY);
    getContentPane().setLayout(null);

    gamePanel = new JPanel();
    gamePanel.setBackground(Color.LIGHT_GRAY);
    gamePanel.setBounds(6, 6, 438, 223);
    getContentPane().add(gamePanel);
    gamePanel.setLayout(new GridLayout(1, 0, 0, 0));

    scorePanel = new JPanel();
    scorePanel.setBackground(Color.GRAY);
    scorePanel.setBounds(6, 241, 438, 31);
    getContentPane().add(scorePanel);
    scorePanel.setLayout(null);

    textAreaScore = new JTextArea("Your score is:" + score);
    textAreaScore.setBackground(Color.LIGHT_GRAY);
    textAreaScore.setBounds(0, 0, 303, 31);
    scorePanel.add(textAreaScore);

    //Exit Game button
    JButton btnExitGame = new JButton("Exit Game");
    btnExitGame.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
        }
    });
    btnExitGame.setBounds(315, 0, 117, 29);
    scorePanel.add(btnExitGame);

    btnExitGame.addActionListener(new ActionListener(){

        public void actionPerformed(ActionEvent e) {
            System.exit(0);

        }

    });
    setVisible(true);
    createSnake();
    extraFood = new JButton();
    extraFood.setEnabled(false);

    addKeyListener(this);
    //This starts the game
    myThread = new Thread(this);
    myThread.start();
}

   //Creates snake
public void createSnake() {
    for (int i = 0; i < 3; i++){
        bc[i] = new JButton("b" + i);
        bc[i].setEnabled(false);
        gamePanel.add(bc[i]);
        bc[i].setBounds(bx[0], by[0], 10, 10);
        bx[i + 1] = bx[i] - 10;
        by[i + 1] = by[i];

    }
}

@SuppressWarnings("deprecation")
void reset(){
    Values();
    gamePanel.removeAll();
    myThread.stop();
    createSnake();
    textAreaScore.setText("Your score is: " + score);

     myThread = new Thread(this);
     myThread.start();

}

//As snake eats food, it grows
void snakeGrow(){
    bc[minSnake] = new JButton();
    bc[minSnake].setEnabled(false);
    gamePanel.add(bc[minSnake]);

    int a = 10 + (10 * ran.nextInt(48));
    int b = 10 + (10 * ran.nextInt(23));

    bx[minSnake] = a;
    by[minSnake] = b;
    bc[minSnake].setBounds(a, b, 10, 10);
    minSnake++;
}

//Snake moving logic
void moveForward() {
    for (int i = 0; i < minSnake; i++) {
        bp[i] = bc[i].getLocation();
    }

    bx[0] += directionx;
    by[0] += directiony;
    bc[0].setBounds(bx[0], by[0], 10, 10);

    for (int i = 1; i < minSnake; i++) {
        bc[i].setLocation(bp[i - 1]);
    }

    if (bx[0] == x) {
        bx[0] = 10;
    } else if (bx[0] == 0) {
        bx[0] = x - 10;
    } else if (by[0] == y) {
        by[0] = 10;
    } else if (by[0] == 0) {
        by[0] = y - 10;
    }

    if (bx[0] == bx[minSnake - 1] && by[0] == by[minSnake - 1]) {
        food = false;
        score += 1;
        textAreaScore.setText("Your score is: " + score);
        if (score % 50 == 0 && bonusFlag == true) {
            gamePanel.add(extraFood);
            extraFood.setBounds((10 * ran.nextInt(50)), (10 * ran.nextInt(25)), 15, 15);
            bonusp = extraFood.getLocation();
            bonusFlag = false;
        }
    }

    if (bonusFlag == false) {
        if (bonusp.x <= bx[0] && bonusp.y <= by[0] && bonusp.x + 10 >= bx[0] && bonusp.y +
    10 >= by[0]) {
            gamePanel.remove(extraFood);
            score += 100;
            textAreaScore.setText("Your score is: " + score);
            bonusFlag = true;
        }
    }

    if (food == false) {
        snakeGrow();
        food = true;
    } else {
        bc[minSnake - 1].setBounds(bx[minSnake - 1], by[minSnake - 1], 10, 10);
    }



    gamePanel.repaint();
    extracted();
}

@SuppressWarnings("deprecation")
private void extracted() {
    show();
}

public void keyPressed(KeyEvent e) {
    //Move to the left when player presses the left arrow key
    if (runLeft == true && e.getKeyCode() == 37) {
        directionx = -10; //Moves to the left by 10 pixels
        directiony = 0;
        runRight = false;     
        runUp = true;      
        runDown = true;      
    }
    //Move up when player presses the up arrow key
    if (runUp == true && e.getKeyCode() == 38) {
        directionx = 0;
        directiony = -10; //Moves up by 10 pixels
        runDown = false;     
        runRight = true;      
        runLeft = true;      
    }
   //Move to the right when the player presses the right arrow key
    if (runRight == true && e.getKeyCode() == 39) {
        directionx = +10; //Moves right by 10 pixels
        directiony = 0;
        runLeft = false;
        runUp = true;
        runDown = true;
    }
    //Move down when the player presses the down arrow key
    if (runDown == true && e.getKeyCode() == 40) {
        directionx = 0;
        directiony = +10; //Moves down by 10 pixels
        runUp = false;
        runRight = true;
        runLeft = true;
    }
}

public void keyReleased(KeyEvent e) {
}

public void keyTyped(KeyEvent e) {
}

public void run() {
    for (;;) {

        //Moves the snake forward
        moveForward();
        try {
            Thread.sleep(speed);
        } catch (InterruptedException ie) {
            }
        }
    }


}   

4 个答案:

答案 0 :(得分:8)

问题是你没有在构造函数中设置全局gamePanel变量只是它的本地版本。删除变量初始化前面的JPanel,它应该可以工作。

同样适用于您的scorePaneltextAreaScore变量。

答案 1 :(得分:3)

您将视图对象(即gamePanel,scorePanel,extraFood,textAreaScore)声明为类Snake的成员变量,但随后在构造函数中声明了同名的局部变量。

成员变量:

JPanel gamePanel, scorePanel;
JButton extraFood;
JTextArea textAreaScore;

局部变量:

public Snake() {
    ...
    JPanel gamePanel = new JPanel();

    ...
    JPanel scorePanel = new JPanel();
    ...

    JTextArea textAreaScore = new JTextArea("Your score is:" + score);
    ...

更改构造函数以实例化您的成员变量,如下所示:

public Snake() {
    ...
    this.gamePanel = new JPanel();

    ...
    this.scorePanel = new JPanel();
    ...

    this.textAreaScore = new JTextArea("Your score is:" + score);
    ...

答案 2 :(得分:3)

问题在于:
您定义了全局变量:

JPanel gamePanel, scorePanel;
JTextArea textAreaScore;

但你定义了dupplicate:

public Snake() {
    JPanel gamePanel = new JPanel();
    ...
    JPanel scorePanel = new JPanel();
    ...
    JTextArea textAreaScore = new JTextArea("Your score is:" + score);
    ...
}

所以,将它们改为:

public Snake() {
        gamePanel = new JPanel();
        ...
        scorePanel = new JPanel();
        ...
        textAreaScore = new JTextArea("Your score is:" + score);
        ...
    }

就是这样。

答案 3 :(得分:2)

gamePanel的构造函数中的shadowing Snake。取代

JPanel gamePanel = new JPanel();

gamePanel = new JPanel();

变量scorePaneltextAreaScore具有相同的问题。


附带问题:

  • 不要在Swing应用程序中使用KeyListeners。它们不适用于Swing应用程序。请改用Key Bindings
  • 同样,不要将原始线程用于Swing应用程序,而是使用Swing Timer代替