java中的记忆游戏
我想写一个记忆游戏。当我们运行应用程序时,“菜单”首先出现。选择是一人和两人。当我们点击一个玩家时,“等级”选择部分出现。这里的选择是简单的,中等的,困难的。然后点击其中一个,游戏开始。但我在实现如何检查所选卡是否相等时遇到了问题。创建卡时,会为其分配一个id。当点击两张卡片时,我正在检查ID。如果ID相同,则返回“匹配”,如果不匹配,则返回“关闭”,这意味着牌面朝下。我正在使用MVC模式。我有9节课。卡片、游戏、关卡(枚举)、菜单、状态(枚举);视图卡片按钮、游戏面板、水平面板、菜单面板。 类游戏面板:java中的记忆游戏,java,model-view-controller,Java,Model View Controller,我想写一个记忆游戏。当我们运行应用程序时,“菜单”首先出现。选择是一人和两人。当我们点击一个玩家时,“等级”选择部分出现。这里的选择是简单的,中等的,困难的。然后点击其中一个,游戏开始。但我在实现如何检查所选卡是否相等时遇到了问题。创建卡时,会为其分配一个id。当点击两张卡片时,我正在检查ID。如果ID相同,则返回“匹配”,如果不匹配,则返回“关闭”,这意味着牌面朝下。我正在使用MVC模式。我有9节课。卡片、游戏、关卡(枚举)、菜单、状态(枚举);视图卡片按钮、游戏面板、水平面板、菜单面板。 类
package view;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import model.Game;
import model.State;
public class GamePanel extends JPanel {
private Game model;
ActionListener cardButtonActionListener;
private JFrame frame;
public GamePanel(Game gameModel, JFrame frame) {
int width=gameModel.getRowSize();
int height=gameModel.getColumnSize();
setLayout(new GridLayout(width,height));
this.model = gameModel;
this.cardButtonActionListener = new CardButtonActionListener();
this.frame = frame;
show();
}
public void show() {
for(int row=0; row<model.getRowSize(); row++) {
for (int col=0; col<model.getColumnSize(); col++) {
CardButton cardBtn = new CardButton(model.getCard(row, col));
cardBtn.addActionListener(cardButtonActionListener);
add(cardBtn);
}
}
frame.repaint();
}
public class CardButtonActionListener implements ActionListener {
private int i = 0;
CardButton b ,b2;
State currentState;
@Override
public void actionPerformed(ActionEvent e) {
if(i==0){
b = (CardButton) e.getSource();
b.setFaceUp();
JOptionPane.showInputDialog("id "+b.getCard().getValue());
i++;
}
else{
b2 = (CardButton) e.getSource();
b2.setFaceUp();
i--;
}
currentState = model.compareCards(b, b2);
if(currentState == State.Match){
b.setVisible(false);
b2.setVisible(false);
}
if(currentState == State.Close){
b.setFaceDown();
b2.setFaceDown();
}
if(currentState == State.Continue){
}
}
}
}
但我不知道怎样才能纠正。非常感谢。
编辑:整个项目在这里当创建
CardButtonActionListener
时,b和b2变量为空。因此,第一次调用actionPerformed()
时,如果(i==0)条件语句失败,则只有b或b2中的一个从e.getSource()获得返回值。所以当你调用currentState=model.compareCards(b,b2)代码>b或b2仍然为null,您发现这将导致该方法抛出null指针异常
看起来这与其说是一个编码错误,不如说是您的设计需要一些补充。主要原因是每个卡片都有自己的cardbuttonationlistener
实例,单击时,此侦听器类不知道已经单击的任何其他卡片。为了快速解决这个问题,您可以添加一个公共静态卡代码>游戏类的成员变量(免责声明:注意,我说的是“快”,不是“好”,因为这违反了良好的OOP设计,在多线程应用程序中会给你带来很多麻烦…但是对于像你这样的单线程应用程序,如果你只想让它工作,这对你来说可能没问题-但是请注意,使用这样的公共静态变量肯定是not养成一个好习惯)。然后您可以像这样修改您的CardButtonActionListener.actionPerformed()(注意,我去掉了'I'变量):
创建cardbuttonationlistener
时,b和b2变量为null。因此,第一次调用actionPerformed()
时,如果(i==0)
条件语句,则只有b或b2中的一个从e.getSource()获得返回值因此,当您调用currentState=model.compareCards(b,b2);
b或b2仍将为null,您发现这将导致该方法抛出null指针异常
看起来这与其说是一个编码错误,不如说是您的设计需要添加一些内容。主要原因是每个卡都有自己的cardbuttonationlistener
实例,单击时,此侦听器类不知道已经单击过的任何其他卡。要快速解决此问题,您可以添加一个public上次单击静态卡;
将成员变量添加到游戏类(免责声明:注意,我说的是“快”,不是“好”,因为这违反了良好的OOP设计,在多线程应用程序中会给你带来很多麻烦…但是对于像你这样的单线程应用程序,如果你只想让它工作,这对你来说可能没问题-但是请注意,使用这样的公共静态变量肯定是not养成一个好习惯)。然后您可以像这样修改您的CardButtonActionListener.actionPerformed()(注意,我去掉了'I'变量):
…什么是null,在哪里?在类游戏中,“v2=b2.getCard().getValue();”和在游戏面板中,“currentState=model.compareCards(b,b2);”你需要将其分解为小的、可管理的任务。也许你应该学习如何编写更大的项目。也许是类图、序列图……我没有立即开始编码。我设计了类图、交互图等等。我也在没有视图的情况下编码,只是控制台应用程序。但说到gui,我遇到了问题。…什么是null,在哪里?在类游戏中,“v2=b2.getCard().getValue();”和在游戏面板中,“currentState=model.compareCards(b,b2);”你需要将其分解为小的、可管理的任务。也许你应该学习如何编写更大的项目。也许是类图、序列图……我没有立即开始编码。我设计了类图、交互图等等。我也在没有视图的情况下编码,只是控制台应用程序。但说到gui,我遇到了问题。非常感谢,这比我的“我”解决方案好:)非常感谢,这比我的“我”解决方案好:)
package model;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.JPanel;
import view.CardButton;
public class Game extends JPanel {
private Level level;
private ArrayList<ArrayList<Card>> board;
private int rowSize;
private int colSize;
private ArrayList<Card> cardList;
public Game() {
}
public void setLevel(Level level,int x) {
this.level = level;
initBoard(x);
}
private void initBoard(int x) {
// Create board according to level variable
int s = x;
rowSize = s;
colSize = s;
int a=rowSize*colSize/2;
int b=0;
this.board = new ArrayList<ArrayList<Card>>();
for(int row=0; row<s; row++) {
this.cardList = new ArrayList<Card>();
for (int col=0; col<s/2; col++) {
cardList.add(new Card(b));
cardList.add(new Card(b));
b++;
}
board.add(getCardList());
}
Collections.shuffle(board);
}
public ArrayList<Card> getCardList(){
Collections.shuffle(cardList);
return cardList;
}
public int getRowSize() {
return rowSize;
}
public int getColumnSize() {
return colSize;
}
public Card getCard(int row, int col) {
return board.get(row).get(col);
}
public State compareCards(CardButton b, CardButton b2) {
int v1, v2;
v1 = b.getCard().getValue();
v2 = b2.getCard().getValue();
if(b.getCard()!= null && b2.getCard()!= null){
return State.Continue;
}else{
if(v1 == v2){
return State.Match;
}
else{
return State.Close;
}
}
}
}
if(i==0){
b = (CardButton) e.getSource();
b.setFaceUp();
JOptionPane.showInputDialog("id "+b.getCard().getValue());
i++;
}
else{
b2 = (CardButton) e.getSource();
b2.setFaceUp();
i--;
}
@Override
public void actionPerformed(ActionEvent e) {
CardButton justClickedButton = e.getSource();
justClickedButton.setFaceUp();
CardButton previouslyClickedButton = Game.lastClicked;
if(previouslyClickedButton == null){
JOptionPane.showInputDialog("id "+justClickedButton.getCard().getValue());
previouslyClickedButton = justClickedButton;
}
else{
currentState = model.compareCards(justClickedButton, previouslyClickedButton);
if(currentState == State.Match){
justClickedButton.setVisible(false);
previouslyClickedButton.setVisible(false);
}
if(currentState == State.Close){
justClickedButton.setFaceDown();
previouslyClickedButton.setFaceDown();
}
if(currentState == State.Continue){
}
previouslyClickedButton = null;
}
}