Java 内存游戏小程序中的重叠背景图形

Java 内存游戏小程序中的重叠背景图形,java,swing,japplet,mouselistener,Java,Swing,Japplet,Mouselistener,好的,我已经用java开发这个内存游戏小程序有一段时间了,我已经弄明白了所有的排序和匹配算法,我只是在努力让我的GUI正常工作。每当我点击其中一张“卡片”进行“翻转”时,我最终会看到一列卡片被创建,而它们的背面对应物会一直放在卡片下面,直到你用光标浏览它为止。这一切都非常令人沮丧,因为我不太清楚为什么会有一半的事情发生,或者如何阻止它。这是我的显示类: import java.awt.Color; import java.awt.Component; import java.awt.Dimens

好的,我已经用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");
}

请注意,任何提示都会非常有用,提前谢谢

您的图形看起来乱七八糟。我看到的问题:

  • 您可以调用组件上的
    getGraphics()
    ,以使用其图形上下文进行绘制,但请理解,以这种方式获得的图形对象不会持久存在,因此可能会弄乱甚至引发NPE
  • 最好通过
    paintComponent(…)
    方法进行所有被动图形。如果需要任何预先制作的图形,请在BuffereImage中执行这些操作,然后在JComponent的
    paintComponent(…)
    方法中绘制BuffereImage
  • 与其让你的显示器JPanel绘制所有的卡片和背面,我建议每张卡片都是自己的独立对象,有自己的状态,根据状态正确地绘制自己。您可能希望让它扩展一个JComponent,或者让它成为一个逻辑实体,然后由您的Display JPanel绘制,具体取决于您,但将逻辑从显示中分离出来,以简化您的编码和调试
  • 一个主要的问题似乎出现在您的
    findTrigger(…)
    方法中,这就是您应该集中精力的地方。如果在
    paintComponent(…)
    中绘制了逻辑卡,则应使用鼠标单击更改单击的逻辑卡(如上所述)的状态,然后在显示屏JPanel上调用
    repaint()
    (此)
  • 否则,如果卡片自己涂抹,考虑让它们成为J标签并简单地交换图像,很可能是“翻转”卡片的最简单的方法。
  • 您的主要问题是程序错误行为。我还没有在代码的快速概述中看到这一问题的原因,建议您使用调试器或println语句来首先尝试隔离问题

您的图形看起来乱七八糟。我看到的问题:

  • 您可以调用组件上的
    getGraphics()
    ,以使用其图形上下文进行绘制,但请理解,以这种方式获得的图形对象不会持久存在,因此可能会弄乱甚至引发NPE
  • 最好通过
    paintComponent(…)
    方法进行所有被动图形。如果需要任何预先制作的图形,请在BuffereImage中执行这些操作,然后在JComponent的
    paintComponent(…)
    方法中绘制BuffereImage
  • 与其让你的显示器JPanel绘制所有的卡片和背面,我建议每张卡片都是自己的独立对象,有自己的状态,根据状态正确地绘制自己。您可能希望让它扩展一个JComponent,或者让它成为一个逻辑实体,然后由您的Display JPanel绘制,具体取决于您,但将逻辑从显示中分离出来,以简化您的编码和调试
  • 一个主要的问题似乎出现在您的
    findTrigger(…)
    方法中,这就是您应该集中精力的地方。如果在
    paintComponent(…)
    中绘制了逻辑卡,则应使用鼠标单击更改单击的逻辑卡(如上所述)的状态,然后在显示屏JPanel上调用
    repaint()
    (此)
  • 否则,如果卡片自己涂抹,考虑让它们成为J标签并简单地交换图像,很可能是“翻转”卡片的最简单的方法。
  • 您的主要问题是程序错误行为。我还没有在代码的快速概述中看到这一问题的原因,建议您使用调试器或println语句来首先尝试隔离问题

我发现了问题所在。我有一个隐形的JPanel面板,里面有一个完整的二维JButton阵列。这些按钮都有自己的侦听器,因此每当有人单击任何按钮时,if语句都会立即被证明是正确的,因为MouseClicker的X和Y被认为是“自己”的另一个面板。你给我指明了正确的方向,伙计。干杯@杜斯夸德:很高兴你把事情朝着正确的方向发展!我知道问题出在哪里了。我有一个隐形的JPanel面板,里面有一个完整的二维JButton阵列。这些按钮都有自己的侦听器,因此每当有人单击任何按钮时,if语句都会立即被证明是正确的,因为MouseClicker的X和Y被认为是“自己”的另一个面板。你给我指明了正确的方向,伙计。干杯@杜斯夸德:很高兴你把事情朝着正确的方向发展!
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);
}

}