在记忆游戏小程序中重叠背景图形

时间:2013-08-18 17:48:42

标签: java swing japplet mouselistener

好的,我已经在java中使用这个内存游戏applet已经有一段时间了,而且我已经找到了所有的排序和匹配算法,我只是有一个不幸的时间试图让我的GUI正常运行。每当我点击其中一张“卡片”进行“翻转”时,我最终会创建一列卡片,而他们的后面对应部分保留在卡片下方,直到您用光标覆盖它。这一切都非常令人沮丧,因为我不太确定为什么这一半正在发生或如何阻止它。这是我的Display类:

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");
}

}

一些注意事项是实际游戏由棋盘对象处理并具有创建和运行多人记忆游戏所需的所有方法,并且Card对象仅包含两个字符串形状和颜色匹配的内容通过游戏。最后一个类是我将提供的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);
}

}

请提前感谢任何提示都会非常有用!

1 个答案:

答案 0 :(得分:4)

您的图片显得混乱。我看到的问题:

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