我已经开始玩一个非常基本的记忆游戏。
private void tbtnCard3ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard5.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard4ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card7EWaste.png")));
if(tbtnCard7.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard5ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard3.isSelected()){
score++;
lblScore.setText(""+score);
}
}
使用 Java Swing,我已经用我需要的图像设置了图标。在底部,我有一个按钮调用 start 以便首先显示所有按钮,直到按下 start btn。
private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard6.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard7.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard8.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard9.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard10.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard11.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard12.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard13.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard14.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard15.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard16.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard17.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard18.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard19.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
tbtnCard20.setIcon(new javax.swing.ImageIcon(getClass().getResource("/BlankImage.png")));
}
我唯一的问题是在玩家从一组 2 张中选错了一张牌后,两张牌都应该回到空白图像。我该怎么做?
答案 0 :(得分:0)
这是一个简单记忆游戏的示例逻辑:
JToggleButton
表示单元格。JToggleButton
而未选中(隐藏状态)。JToggleButton
时,它会自动更改为显示状态。JToggleButton
添加相同的侦听器,以便随时跟踪最后两个选定的按钮。如果找到匹配项,则您可以禁用匹配按钮,如果未找到匹配项,则只需取消选择它们即可。为了在以下演示代码中简单起见,我使用自定义 Icon
实现来实现上述所有目的,它只是绘制了某种颜色的圆角矩形。颜色用于将按钮标识为彼此匹配,即相同颜色的按钮表示选择了匹配。我只是在 隐藏 状态下为每个按钮使用了一个白色的圆角矩形,而在 显示 状态下使用了随机颜色。
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Random;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Main {
private static class RoundRectIcon implements Icon {
private final Color c;
public RoundRectIcon(final Color c) {
this.c = Objects.requireNonNull(c);
}
public Color getColor() {
return c;
}
@Override
public void paintIcon(final Component c,
final Graphics g,
final int x,
final int y) {
g.setColor(this.c);
g.fillRoundRect(x, y, getIconWidth() - 1, getIconHeight() - 1, getIconWidth() / 2, getIconHeight() / 2);
}
@Override
public int getIconWidth() {
return 50;
}
@Override
public int getIconHeight() {
return 50;
}
}
private static class MemoryGameActionListener implements ActionListener {
private final Timer revertTimer;
private JToggleButton button1, button2;
private int pairsCount;
public MemoryGameActionListener(final int delay,
final int pairsCount) {
if (pairsCount <= 0)
throw new IllegalArgumentException("Non positive pairsCount.");
this.pairsCount = pairsCount;
button1 = button2 = null;
revertTimer = new Timer(delay, this);
revertTimer.setRepeats(false);
}
@Override
public void actionPerformed(final ActionEvent e) {
revertTimer.stop();
final Object source = e.getSource();
if (source instanceof JToggleButton) {
final JToggleButton button = (JToggleButton) source;
if (button.isSelected()) {
if (button1 == null) //If we are in an initial state:
button1 = button; //Store the first clicked button.
else if (button2 == null) { //Else we have stored the first button, so store and check the second one...
button2 = button;
final RoundRectIcon icon1 = (RoundRectIcon) button1.getSelectedIcon(),
icon2 = (RoundRectIcon) button2.getSelectedIcon();
if (Objects.equals(icon1.getColor(), icon2.getColor())) {
System.out.println("Pair of " + icon1.getColor() + " found!");
button1.setEnabled(false); //Don't let the user able to click it again.
button2.setEnabled(false); //Don't let the user able to click it again.
button1 = button2 = null; //A cycle is complete.
if (--pairsCount == 0)
JOptionPane.showMessageDialog(null, "You found every pair.", "You win", JOptionPane.INFORMATION_MESSAGE);
}
else {
System.out.println("Invalid match of " + icon1.getColor() + ", and " + icon2.getColor() + '.');
revertTimer.start(); //This timer will unselect the selected button pair after a delay.
}
}
else { //Else both buttons are stored, so this is the third one, so just ignore the previous buttons (if they did not match):
if (button1.isEnabled())
button1.setSelected(false);
if (button2.isEnabled())
button2.setSelected(false);
button1 = button; //Suppose now that the third clicked button is the first one.
button2 = null;
}
}
else { //Else the user unselected a button, so reset:
if (button1 != null) {
button1.setSelected(false);
button1 = null;
}
if (button2 != null) {
button2.setSelected(false);
button2 = null;
}
}
}
else if (source == revertTimer) { //If a pair was found previously but it didn't match up, then reset:
button1.setSelected(false);
button2.setSelected(false);
button1 = button2 = null;
}
else
System.err.println("Unknown source " + source); //This should never happen.
}
}
private static Color randomColor(final Random random) {
final byte[] components = new byte[3];
random.nextBytes(components);
return new Color(components[0] & 0xFF, components[1] & 0xFF, components[2] & 0xFF);
}
private static HashSet<Color> randomUniqueColors(final int count) {
final Random random = new Random();
final HashSet<Color> colors = new HashSet<>(count);
while (colors.size() < count) //If we produce the same color inside the loop, then 'colors.size()' will not increment.
colors.add(randomColor(random));
return colors;
}
private static JToggleButton createStandardToggleButton(final Color color,
final MemoryGameActionListener listener) {
final JToggleButton toggle = new JToggleButton(new RoundRectIcon(Color.WHITE)); //Default (ie enabled + unselected) icon is just a white round rect.
toggle.setSelectedIcon(new RoundRectIcon(color));
toggle.setDisabledIcon(toggle.getSelectedIcon());
toggle.setDisabledSelectedIcon(toggle.getSelectedIcon());
toggle.addActionListener(listener);
return toggle;
}
private static void createAndShowGUI() {
final int rows = 4, cols = 4, delay = 1000;
final int totalButtons = rows * cols; //The total number of buttons must be a multiple of 2 (because we use pairs of buttons).
final int totalPairs = totalButtons / 2;
final MemoryGameActionListener listener = new MemoryGameActionListener(delay, totalPairs);
final JPanel grid = new JPanel(new GridLayout(0, cols, 5, 5));
final ArrayList<JToggleButton> buttons = new ArrayList<>(totalButtons);
randomUniqueColors(totalPairs).forEach(color -> {
//Add the matching buttons to the list...
buttons.add(createStandardToggleButton(color, listener));
buttons.add(createStandardToggleButton(color, listener));
});
Collections.shuffle(buttons);
buttons.forEach(button -> grid.add(button));
final JFrame frame = new JFrame("Memory game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(grid);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(Main::createAndShowGUI);
}
}
我首先生成所需颜色数量的 Set
,然后为每种颜色创建两个按钮,然后将它们随机排列,最后将它们添加到 JPanel
的 GridLayout
。>
可以轻松调整上面的示例代码以包含您喜欢的任何 Icon
,其中当然包括 ImageIcon
和其他自定义的。