连接 GUI 和游戏
Connecting GUI with game
我正在尝试在 java 中使用游戏 class 构建 GUI。我一直收到 NullPointerException 并且我不知道为什么,我以为我正在将对象 "cPlayer" 传递给小程序,然后小程序将它传递给 JPanel 部分(它应该与 cPlayer 比较命中或未命中)但是我不知道我做错了什么。有没有其他方法可以将 cPlayer 对象传递给小程序,然后传递给 JPanel?
public class gamePlay {
public final static ComputerBoard cPlayer = new ComputerBoard();
public static void main(String args){
BattleshipApplet play = new BattleshipApplet();
play.setBoard(cPlayer);
}
}
public class BattleshipApplet extends JApplet {
private final JButton playButton = new JButton("Play");
private final JLabel msgBar = new JLabel("Click Play to start game");
private BoardPanel panel;
private ComputerBoard game;
public BattleshipApplet(){
playButton.addActionListener(this::playButtonClicked);
}
public void init(){
configureGui();
}
private void configureGui(){
setLayout(new BorderLayout());
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));
buttons.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
buttons.add(playButton);
add(buttons, BorderLayout.NORTH);
msgBar.setBorder(BorderFactory.createEmptyBorder(10,10,5,5));
add(createBoardPanel(), BorderLayout.CENTER);
add(msgBar, BorderLayout.SOUTH);
}
private BoardPanel createBoardPanel(){
panel = new BoardPanel(game);
return panel;
}
private void displayMessage(String msg){
msgBar.setText(msg);
}
private void playButtonClicked(ActionEvent event){
displayMessage("Game has started!");
}
void setBoard(ComputerBoard b){
game = b;
}
}
public class BoardPanel extends JPanel {
private static final int ROWS = 10;
private static final int CELL_WIDTH = 28;
private static final int PAD = 20;
private static final Color GRID_COLOR = Color.blue;
private static final Color CIRCLE_COLOR_HIT = Color.red;
private static final Color CIRCLE_COLOR_MISS = Color.white;
private static final Color TEXT_COLOR = Color.blue;
private static final int SML_GAP = 2;
private boolean[][] grid = new boolean[ROWS][ROWS];
private int counter;
private int x, y;
private boolean gameBoardpiece;
ComputerBoard gameBoard;
public BoardPanel(ComputerBoard b) {
addMouseListener((MouseListener) new MyMouse());
counter =0;
gameBoard = b;
gameBoardpiece = false;
}
public void reset() {
grid = new boolean[ROWS][ROWS]; // fills grid with false
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// draws grid
g.setColor(GRID_COLOR);
for (int i = 0; i <= ROWS; i++) {
int x1 = PAD + i * CELL_WIDTH;
int y1 = PAD;
int x2 = x1;
int y2 = PAD + CELL_WIDTH * ROWS;
g.drawLine(x1, y1, x2, y2);
g.drawLine(y1, x1, y2, x2);
}
// iterate through the grid boolean array
// draw circles if the grid value is true.
int w = CELL_WIDTH - 2 * SML_GAP; // width of the circle to draw
int h = w;
// nested for loop to go through the grid array
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
if (grid[r][c]) {
//if was a hit
if(gameBoardpiece == false){
g.setColor(CIRCLE_COLOR_HIT);
}
//shot was a miss
else{
g.setColor(CIRCLE_COLOR_MISS);
}
int x = PAD + c * CELL_WIDTH + SML_GAP;
int y = PAD + r * CELL_WIDTH + SML_GAP;
g.fillOval(x, y, w, h);
}
}
}
//states the number of shots in the game
g.setColor(TEXT_COLOR);
g.drawString("Shots: "+counter, 305,300 );
}
private class MyMouse extends MouseAdapter {
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
if (x < PAD || y < PAD ) {
// clicked above or to right of grid
return;
}
int r = (y - PAD) / CELL_WIDTH;
int c = (x - PAD) / CELL_WIDTH;
// if clicked to right or below grid.
if (r >= ROWS || c >= ROWS) {
return;
}
if(gameBoard.matchBoard(r,c) == 0){
gameBoardpiece = true;
}
if(gameBoard.matchBoard(r,c) == 1){
gameBoardpiece = false;
}
counter++;
grid[r][c] = true;
repaint();
}
}
}
我收到的错误信息是:
Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException
at battleship.BoardPanel$MyMouse.mousePressed(BoardPanel.java:113)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
小程序的生命周期不同于应用程序的生命周期。如果此小程序在小程序通常 运行 所在的环境中 运行,则不会调用 main()
方法。上下文调用小程序的构造函数后,生命周期将从调用小程序的 init()
方法开始。
因此像下面这样的东西会更好。
public void init(){
ComputerBoard cPlayer = new ComputerBoard();
setBoard(cPlayer);
configureGui();
}
或者完全取消 setBoard
方法并编写
public void init(){
game = new ComputerBoard();
configureGui();
}
我正在尝试在 java 中使用游戏 class 构建 GUI。我一直收到 NullPointerException 并且我不知道为什么,我以为我正在将对象 "cPlayer" 传递给小程序,然后小程序将它传递给 JPanel 部分(它应该与 cPlayer 比较命中或未命中)但是我不知道我做错了什么。有没有其他方法可以将 cPlayer 对象传递给小程序,然后传递给 JPanel?
public class gamePlay {
public final static ComputerBoard cPlayer = new ComputerBoard();
public static void main(String args){
BattleshipApplet play = new BattleshipApplet();
play.setBoard(cPlayer);
}
}
public class BattleshipApplet extends JApplet {
private final JButton playButton = new JButton("Play");
private final JLabel msgBar = new JLabel("Click Play to start game");
private BoardPanel panel;
private ComputerBoard game;
public BattleshipApplet(){
playButton.addActionListener(this::playButtonClicked);
}
public void init(){
configureGui();
}
private void configureGui(){
setLayout(new BorderLayout());
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));
buttons.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
buttons.add(playButton);
add(buttons, BorderLayout.NORTH);
msgBar.setBorder(BorderFactory.createEmptyBorder(10,10,5,5));
add(createBoardPanel(), BorderLayout.CENTER);
add(msgBar, BorderLayout.SOUTH);
}
private BoardPanel createBoardPanel(){
panel = new BoardPanel(game);
return panel;
}
private void displayMessage(String msg){
msgBar.setText(msg);
}
private void playButtonClicked(ActionEvent event){
displayMessage("Game has started!");
}
void setBoard(ComputerBoard b){
game = b;
}
}
public class BoardPanel extends JPanel {
private static final int ROWS = 10;
private static final int CELL_WIDTH = 28;
private static final int PAD = 20;
private static final Color GRID_COLOR = Color.blue;
private static final Color CIRCLE_COLOR_HIT = Color.red;
private static final Color CIRCLE_COLOR_MISS = Color.white;
private static final Color TEXT_COLOR = Color.blue;
private static final int SML_GAP = 2;
private boolean[][] grid = new boolean[ROWS][ROWS];
private int counter;
private int x, y;
private boolean gameBoardpiece;
ComputerBoard gameBoard;
public BoardPanel(ComputerBoard b) {
addMouseListener((MouseListener) new MyMouse());
counter =0;
gameBoard = b;
gameBoardpiece = false;
}
public void reset() {
grid = new boolean[ROWS][ROWS]; // fills grid with false
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// draws grid
g.setColor(GRID_COLOR);
for (int i = 0; i <= ROWS; i++) {
int x1 = PAD + i * CELL_WIDTH;
int y1 = PAD;
int x2 = x1;
int y2 = PAD + CELL_WIDTH * ROWS;
g.drawLine(x1, y1, x2, y2);
g.drawLine(y1, x1, y2, x2);
}
// iterate through the grid boolean array
// draw circles if the grid value is true.
int w = CELL_WIDTH - 2 * SML_GAP; // width of the circle to draw
int h = w;
// nested for loop to go through the grid array
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
if (grid[r][c]) {
//if was a hit
if(gameBoardpiece == false){
g.setColor(CIRCLE_COLOR_HIT);
}
//shot was a miss
else{
g.setColor(CIRCLE_COLOR_MISS);
}
int x = PAD + c * CELL_WIDTH + SML_GAP;
int y = PAD + r * CELL_WIDTH + SML_GAP;
g.fillOval(x, y, w, h);
}
}
}
//states the number of shots in the game
g.setColor(TEXT_COLOR);
g.drawString("Shots: "+counter, 305,300 );
}
private class MyMouse extends MouseAdapter {
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
if (x < PAD || y < PAD ) {
// clicked above or to right of grid
return;
}
int r = (y - PAD) / CELL_WIDTH;
int c = (x - PAD) / CELL_WIDTH;
// if clicked to right or below grid.
if (r >= ROWS || c >= ROWS) {
return;
}
if(gameBoard.matchBoard(r,c) == 0){
gameBoardpiece = true;
}
if(gameBoard.matchBoard(r,c) == 1){
gameBoardpiece = false;
}
counter++;
grid[r][c] = true;
repaint();
}
}
}
我收到的错误信息是:
Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException
at battleship.BoardPanel$MyMouse.mousePressed(BoardPanel.java:113)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
小程序的生命周期不同于应用程序的生命周期。如果此小程序在小程序通常 运行 所在的环境中 运行,则不会调用 main()
方法。上下文调用小程序的构造函数后,生命周期将从调用小程序的 init()
方法开始。
因此像下面这样的东西会更好。
public void init(){
ComputerBoard cPlayer = new ComputerBoard();
setBoard(cPlayer);
configureGui();
}
或者完全取消 setBoard
方法并编写
public void init(){
game = new ComputerBoard();
configureGui();
}