0

好的,我已经在 java 中研究这个记忆游戏小程序一段时间了,我已经弄清楚了所有的排序和匹配算法,我只是在试图让我的 GUI 正常运行时度过了一段痛苦的时光。每当我单击其中一个“卡片”进行“翻转”时,我最终都会创建一列卡片,而它们的背面对应物仍保留在卡片下方,直到您用光标将其移过为止。这一切都非常令人沮丧,因为我不太清楚为什么会发生一半或如何阻止它。这是我的显示类:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.*;

public class Display extends JPanel implements MouseListener {

private String[] Colors = Card.validColors();
private String[] Shapes = Card.validShapes();
private Component[] place;
private JButton[][] buttonGrid= new JButton[6][6];
private Rectangle[][] triggers = new Rectangle[6][6];
private Board game;
private Polygon star = new Polygon();
private Card pick;
private boolean turnPhase2 = false;
private Font serifNames = new Font(Font.SERIF, Font.PLAIN, 18);
private Font serifCards = new Font(Font.SERIF, Font.ROMAN_BASELINE, 36);
private JPanel panel = new JPanel();

public Display() {
    this.setBackground(Color.BLACK);
    this.setLayout(new GridBagLayout());
    panel.setSize(590, 410);
    panel.setLayout(new GridLayout(6, 6, 10, 10));
    panel.setOpaque(false);

    generateStar();
    buildBoard();
    fillButtonArray();

    this.addMouseListener(this);
    this.add(panel);
    System.out.println(getFontMetrics(serifCards));
    System.out.println(getFontMetrics(serifNames));
}



public void paintComponent(Graphics g) {
    super.paintComponent(g);
    place = panel.getComponents();
    for (int i = 0; i < place.length; i++) {
        paintBack(g, place[i].getX() + 25, place[i].getY() + 35);
    }
    displayNames(g);
    displayTurn(g);
    if (game.flippedCard() != null) {
        int[] xy = game.flippedCardLocation();
        paintCard(g, game.flippedCard(), xy[0], xy[1]);
    }
}

/**
 * This method builds the game board.
 * 
 * 
 */
private void buildBoard() {
    game = new Board(buildDeck());
}

/**
 * This method creates a "deck" of cards with which we can create the game board.
 * 
 * @return deck Returns the deck of Card objects in the form of an ArrayList.
 */
private ArrayList<Card> buildDeck() {
    ArrayList<Card> deck = new ArrayList<Card>();

    for (int i = 0; i < Colors.length; i++) {
        for (int s = 0; s < Shapes.length; s++) {
            Card first = new Card(Shapes[s], Colors[i]);
            Card second = new Card(Shapes[s], Colors[i]);
            deck.add(first);
            deck.add(second);
        }
    }
    System.out.println(deck.size());
    return deck;
}

private void fillButtonArray() {
    for (int i = 0; i < 6; i++) {
        for (int n = 0; n < 6; n++) {
            JButton button = new JButton();
            button.setPreferredSize(new Dimension(90, 60));
            button.addMouseListener(this);
            button.setOpaque(false);
            button.setContentAreaFilled(false);
            button.setBorderPainted(false);

            buttonGrid[i][n] = button;
        }
    }
    fillGrid();
}

private void fillGrid() {
    panel.setBounds(25, 35, panel.getSize().width, panel.getSize().height);
    int count = 0;
    for (int i = 0; i < 6; i++) {
        for (int s = 0; s < 6; s++) {
            panel.add(buttonGrid[i][s]);
            place = panel.getComponents();
            int x = panel.getComponent(count).getBounds().x;
            int y = panel.getComponent(count).getBounds().y;
            Rectangle rect = new Rectangle(x, y, 90, 60);
            triggers[i][s] = rect;
        }
    }

}

private void paintBack(Graphics g, int x, int y) {
    g.setColor(Color.WHITE);
    g.drawRoundRect(x, y, 90, 60, 2, 4);
    g.fillRoundRect(x, y, 90, 60, 2, 4);
    g.setColor(Color.BLACK);
    g.setFont(serifCards);
    g.drawString("M", x + 28, y + 42);
}

private void paintCard(Graphics g, Card card, int x, int y) {
    g.setColor(Color.GRAY);
    g.drawRoundRect(x, y, 90, 60, 2, 4);
    g.fillRoundRect(x, y, 90, 60, 2, 4);
    String color = card.getColor();
    String shape = card.getShape();

    if (shape.equals("Star")) {
        g.setColor(pickColor(color));
        star.translate(x + 25, y + 10);
        g.drawPolygon(star);
        g.fillPolygon(star);

    }
    else if (shape.equals("Circle")) {
        g.setColor(pickColor(color));
        g.drawOval(x + 25, y + 10, 40, 40);
        g.fillOval(x + 25, y + 10, 40, 40);
    }
    else if (shape.equals("Square")) {
        g.setColor(pickColor(color));
        g.drawRect(x + 25, y + 10, 40, 40);
        g.fillRect(x + 25, y + 10, 40, 40);
    }
}



private void displayNames(Graphics g) {
    g.setFont(serifNames);
    int[] scores = game.getCurrentScores();

    for (int i = 0; i < scores.length; i++) {
        if (i == 0) {
            g.setColor(Color.CYAN);
            g.drawString("Cyan: " + scores[i], 10, 24);
        }
        else if (i == 1) {
            g.setColor(Color.ORANGE);
            g.drawString("Orange: " + scores[i], 560, 24);
        }
        else if (i == 2) {
            g.setColor(Color.MAGENTA);
            g.drawString("Magenta: " + scores[i], 10, 470);
        }
        else {
            g.setColor(Color.WHITE);
            g.drawString("White: " + scores[i], 569, 470);
        }
    }
}

private void displayTurn(Graphics g) {
    int player = game.getCurrentPlayer();

    if (player == 0) {
        g.setColor(Color.CYAN);
        String str = "Cyan's Turn";
        g.drawString(str, 640 / 2 - 48, 24);
        //System.out.println(getFontMetrics(serifNames).stringWidth(str) / 2 + " Cyan");
    }
    else if (player == 1) {
        g.setColor(Color.ORANGE);
        String str = "Orange's Turn";
        g.drawString(str, 640 / 2 - 52, 24);
        //System.out.println(getFontMetrics(serifNames).stringWidth(str) / 2 + " Orange");
    }
    else if (player == 2) {
        g.setColor(Color.MAGENTA);
        String str = "Magenta's Turn";
        g.drawString(str, 640 / 2 - 57, 24);
        //System.out.println(getFontMetrics(serifNames).stringWidth(str) / 2 + " Magenta");
    }
    else {
        g.setColor(Color.WHITE);
        String str = "White's Turn";
        g.drawString(str, 640 / 2 - 47, 24);
        //System.out.println(getFontMetrics(serifNames).stringWidth(str) / 2 + " White");
    }
}

private void findTrigger(int x, int y) {
    for (int i = 0; i < 6; i++) {
        if () {

        }
        for (int s = 0; s < 6; s++) {
            Rectangle rectTest = triggers[i][s];
            if (x >= rectTest.getMinX() &&
                    x <= rectTest.getMaxX() &&
                    y >= rectTest.getMinY() &&
                    y <= rectTest.getMaxY()) {
                Graphics g = getGraphics();
                paintCard(g, game.flip(i,s), buttonGrid[i][s].getBounds().x, buttonGrid[i][s].getBounds().y);
                break;
            }
        }
    }
}

private void generateStar() {
    star.addPoint(20, 0);
    star.addPoint(25, 15);
    star.addPoint(40, 15);
    star.addPoint(28, 24);
    star.addPoint(32, 40);
    star.addPoint(20, 30);
    star.addPoint(8, 40);
    star.addPoint(12, 24);
    star.addPoint(0, 15);
    star.addPoint(15, 15);
}

private Color pickColor(String color) {
    if (color.equals("Black")) {
        return Color.BLACK;
    }
    if (color.equals("Yellow")) {
        return Color.YELLOW;
    }
    if (color.equals("Green")) {
        return Color.GREEN;
    }
    if (color.equals("Blue")) {
        return Color.BLUE;
    }
    if (color.equals("Red")) {
        return Color.RED;
    }
    if (color.equals("Purple")) {
        return new Color(128, 0, 255);
    }
    return null;
}

@Override
public void mouseClicked(MouseEvent e) {
    System.out.println("Mouse Clicked");
    int x = e.getX();
    System.out.println(x + " is x");
    int y = e.getY();
    System.out.println(y + " is Y");
    System.out.println(panel.getWidth() + 25);
    System.out.println(panel.getHeight() + 35);

    System.out.println("Finding the trigger rectangle");
    findTrigger(x, y);
}

@Override
public void mouseEntered(MouseEvent e) {
    //System.out.println("Mouse Entered");
}

@Override
public void mouseExited(MouseEvent e) {
    //System.out.println("Mouse Exited");
}

@Override
public void mousePressed(MouseEvent e) {
    System.out.println("Mouse Pressed");
}

@Override
public void mouseReleased(MouseEvent e) {
    System.out.println("Mouse Released");
}

}

一些旁注是,实际游戏由棋盘对象处理,并具有创建和运行多人记忆游戏所需的所有方法,而卡片对象仅包含两个字符串,分别是游戏要匹配的形状和颜色. 最后一个类是我将提供的 Memory 类:

import java.awt.Color;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JApplet;

public class Memory extends JApplet {
private Display _theDisplay;
final int width = 640;
final int height = 480;

private Action reDraw = new AbstractAction() {
    public void actionPerformed(ActionEvent e) {
        repaint();
    }
};

public Memory() {
    _theDisplay = new Display();
}

public void init() {
    setSize(width, height);
    setBackground(Color.BLACK);
    this.add(_theDisplay);
}

}

请任何提示都会非常有帮助,在此先感谢!

4

1 回答 1

4

你的图形看起来很乱。我看到的问题:

  • 你调用getGraphics()一个组件用它的 Graphics 上下文进行绘制,但是请理解这样获得的 Graphics 对象不会持久化,因此会弄乱甚至导致 NPE 被抛出。
  • paintComponent(...)最好通过你的方法做全被动图形。如果您需要任何预制绘图,请在 BufferedImages 中进行这些操作,并在 JComponent 的paintComponent(...)方法中绘制 BufferedImages。
  • 与其让您的 Display JPanel 完成卡片和背面的所有绘制,我建议每张卡片都是具有自己状态的独立对象,根据其状态正确绘制自己。您可能希望扩展一个 JComponent,或者让它成为一个逻辑实体,然后由您的 Display JPanel 绘制,由您决定,但将逻辑与显示分开以简化您的编码和调试。
  • 您的方法似乎存在一个主要问题findTrigger(...),这就是您应该集中精力的地方。您应该使用鼠标单击来更改被单击的逻辑卡片(如上所述)的状态,然后repaint()如果卡片被绘制在 中,则调用 Display JPanel (this) paintComponent(...)
  • 否则,如果卡片自己绘制,考虑让它们成为 JLabels 并简单地交换 ImageIcons,这可能是“翻转”卡片的最简单方法。
  • 您的主要问题是程序错误行为。在快速浏览您的代码时,我还没有看到导致此问题的原因,并建议您使用调试器或 println 语句首先尝试隔离问题。
于 2013-08-18T18:00:08.137 回答