我已经在java中创建了一个Soitaire游戏,但是当我编译应用程序(没有错误)由于某种原因卡片最终为空时。
以下是包含图形的代码部分。
在Card.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JPanel;
public class Card extends JPanel {
/**
* defines all values of rank a card can achieve
*/
public enum Rank {
Ace, One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
}
/**
* defines all values of color a card can achieve
*/
public enum Suit {
HEARTS, DIAMONDS, CLUBS, SPADES
}
private Rank cardRank; ///< will store the rank of our card
private Suit cardColor; ///< will store the color of our card
private boolean faceUp; ///< determines which side the card is facing
private Point location; ///< location of our card on board, has to be stored individually
private Point where; ///< location of Card to others
/// @2DD coordinates
private int x = 0;
private int y = 0;
/// offsets for cards
private final int x_offset = 10;
private final int y_offset = 20;
private final int new_x_offset = x_offset + (CARD_WIDTH - 30);
/// constants for card graphical view
final static public int CARD_WIDTH = 100;
final static public int CARD_HEIGHT = 150;
final static public int ANGLE = 25;
/**
* Defines a sample card object that specifies it's parameters
*
* @param defRank - pre-defined rank
* @param defColor - pre-defined color
*/
public Card(Rank defRank, Suit defColor){
cardRank = defRank;
cardColor = defColor;
faceUp = false;
location = new Point();
x = 0;
y = 0;
location.x = x;
location.y = y;
where = new Point();
}
/* Function for drawing out a card Color
*
* @param defColor - defines which card color (symbol we want)
* @param defColorCode - defines which actual color code should be used for the symbol
*/
private void drawSuit(Graphics2D g, String defColor, Color defColorCode)
{
g.setColor(defColorCode);
g.drawString(defColor, location.x + x_offset, location.y + y_offset);
g.drawString(defColor, location.x + x_offset, location.y + CARD_HEIGHT - 5);
}
/**
* similar as color, but instead of symbol we draw the value
* @see drawColor for more info
*/
private void drawRank(Graphics2D g, String defRank){
g.drawString(defRank, location.x + new_x_offset, location.y + y_offset);
g.drawString(defRank, location.x + new_x_offset, location.y + y_offset + CARD_HEIGHT - 25);
}
/**
* basically acts as a main for the Card. Creates card with graphical display
*
* @param g2d - utilizes java graphic library to draw compotents of our defined functions
*/
public void createCard(Graphics g2d){
Graphics2D g = (Graphics2D) g2d; ///< konvertujeme do 2d grafiky
RoundRectangle2D rect = new RoundRectangle2D.Double(location.x, location.y, CARD_WIDTH, CARD_HEIGHT, ANGLE, ANGLE);
g.setColor(Color.WHITE);
g.fill(rect);
g.setColor(Color.BLACK);
g.draw(rect);
if (faceUp == true){
switch(cardColor){
case HEARTS:
drawSuit(g, "Hearts", Color.RED);
break;
case DIAMONDS:
drawSuit(g, "Diamonds", Color.RED);
break;
case CLUBS:
drawSuit(g, "Clubs", Color.BLACK);
break;
case SPADES:
drawSuit(g, "Spades", Color.BLACK);
break;
}
int new_x_offset = x_offset + (CARD_WIDTH - 30);
switch (cardRank){
case Ace:
drawRank(g, "Ace (A)");
break;
case Two:
drawRank(g, "Two (2)");
break;
case Three:
drawRank(g, "Three (3)");
break;
case Four:
drawRank(g, "Four (4)");
break;
case Six:
drawRank(g, "Six (5)");
break;
case Five:
drawRank(g, "Five (6)");
break;
case Seven:
drawRank(g, "Seven (7)");
break;
case Eight:
drawRank(g, "Eight (8)");
break;
case Nine:
drawRank(g, "Nine (9)");
break;
case Ten:
drawRank(g, "Ten (10)");
break;
case Jack:
drawRank(g, "Jack (J)");
break;
case Queen:
drawRank(g, "Queen (Q)");
break;
case King:
drawRank(g, "King (K)");
break;
}
} // end of if
else { ///< ked je karta otocena spodkom
RoundRectangle2D rect2D = new RoundRectangle2D.Double(location.x, location.y, CARD_WIDTH, CARD_HEIGHT, ANGLE, ANGLE);
g.setColor(Color.LIGHT_GRAY);
g.fill(rect2D);
g.setColor(Color.BLACK);
g.draw(rect2D);
} // end of else
} // end of function
} // end of file (class Card.java)
在CardStack.java
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ListIterator;
import java.util.Stack;
import java.util.Collections;
import javax.swing.*;
import java.awt.geom.RoundRectangle2D;
/**
* We decided to fuse CardDeck with CardStack. CardDeck can contain multiple card stacks
*
* @param isDeck - a boolean that checks if we want a deck or only a stack. Deck contains all cards
*/
public CardStack(boolean isDeck) {
deck = new Stack<Card>();
this.setLayout(null);
if(isDeck) {
for (Card.Suit suit : Card.Suit.values()) {
for (Card.Rank rank : Card.Rank.values()) {
deck.push(new Card(rank, suit));
}
}
} else
playStack = true;
}
/**
* Paints the entire component, similar to card
*
* @see Card
* @param g - utilizes Graohic library.
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (playStack) {
removeAll();
ListIterator<Card> iter = deck.listIterator();
Point prev = new Point(); /// positioning relative to the container
Point prevWhereAmI = new Point();/// abs positioning on the board
if (iter.hasNext()) {
Card c = iter.next();
//// this origin is point(0,0) inside the cardstack container
prev = new Point();/// c.getXY(); /// starting deck pos
add(Solitaire.moveCard(c, prev.x, prev.y));
/// setting x & y position
c.setWhere(getXY());
prevWhereAmI = getXY();
} else {
removeAll();
}
for (; iter.hasNext(); ) {
Card c = iter.next();
c.setXY(new Point(prev.x, prev.y + SPREAD));
add(Solitaire.moveCard(c, prev.x, prev.y + SPREAD));
prev = c.getXY();
/// setting x & y position
c.setWhere(new Point(prevWhereAmI.x, prevWhereAmI.y + SPREAD));
prevWhereAmI = c.getWhere();
}
}
}
protected void paintComponent(Graphics g, boolean isFinalStack)
{
removeAll();
if (!emptyStack())
{
add(Solitaire.moveCard(this.peekLast(), 1, 1));
} else
{
/// draw back of card if empty
Graphics2D g2d = (Graphics2D) g;
RoundRectangle2D rect = new RoundRectangle2D.Double(0, 0, Card.CARD_WIDTH, Card.CARD_HEIGHT,
Card.ANGLE, Card.ANGLE);
g2d.setColor(Color.LIGHT_GRAY);
g2d.fill(rect);
g2d.setColor(Color.black);
g2d.draw(rect);
}
}
最后是课程的最后一部分, Solitaire.java ,基本上将它们联系在一起。
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import src.ija.Card;
import src.ija.CardStack;
/// GUI COMPONENTS (top level)
private static final JFrame frame = new JFrame("IJA Klondike Solitaire");
protected static final JPanel table = new JPanel();
/// other components
private static JEditorPane gameTitle = new JEditorPane("text/html", "");
private static JButton showRulesButton = new JButton("Show Rules");
private static JButton newGameButton = new JButton("New Game");
private static JButton toggleTimerButton = new JButton("Pause Timer");
private static JTextField scoreBox = new JTextField();/// displays the score
private static JTextField timeBox = new JTextField();/// displays the time
private static JTextField statusBox = new JTextField();/// status messages
private static final Card newCardButton = new Card();/// reveal waste card
private static void playNewGame()
{
deck = new CardStack(true); /// deal 52 cards
deck.shuffle();
table.removeAll();
/// reset stacks if user starts a new game in the middle of one
if (playCardStack != null && final_cards != null)
{
for (int x = 0; x < NUM_PLAY_DECKS; x++)
{
while(!playCardStack[x].emptyStack()){
playCardStack[x].popStack();
}
}
for (int x = 0; x < NUM_FINAL_DECKS; x++)
{
while(!final_cards[x].emptyStack()){
final_cards[x].popStack();
}
}
}
/// initialize & place final (foundation) decks/stacks
final_cards = new CardStack[NUM_FINAL_DECKS];
for (int x = 0; x < NUM_FINAL_DECKS; x++)
{
final_cards[x] = new CardStack(false, true);
final_cards[x].setXY((FINAL_POS.x + (x * Card.CARD_WIDTH)) + 10, FINAL_POS.y, true);
table.add(final_cards[x]);
}
/// place new card distribution button
table.add(moveCard(newCardButton, DECK_POS.x, DECK_POS.y));
/// initialize & place play (tableau) decks/stacks
playCardStack = new CardStack[NUM_PLAY_DECKS];
for (int x = 0; x < NUM_PLAY_DECKS; x++)
{
playCardStack[x] = new CardStack(false);
playCardStack[x].setXY((DECK_POS.x + (x * (Card.CARD_WIDTH + 10))), PLAY_POS.y);
table.add(playCardStack[x]);
}
/// Dealing new game
for (int x = 0; x < NUM_PLAY_DECKS; x++)
{
int hld = 0;
Card c = deck.popStack().turnFaceUp();
playCardStack[x].putFirst(c);
for (int y = x + 1; y < NUM_PLAY_DECKS; y++)
{
playCardStack[y].putFirst(c = deck.popStack());
}
}
/// reset time
time = 0;
newGameButton.addActionListener(new NewGameListener());
newGameButton.setBounds(0, TABLE_HEIGHT - 70, 120, 30);
showRulesButton.addActionListener(new ShowRulesListener());
showRulesButton.setBounds(120, TABLE_HEIGHT - 70, 120, 30);
gameTitle.setText("<b>IJA Solitaire</b> <br>");
gameTitle.setEditable(false);
gameTitle.setOpaque(false);
gameTitle.setBounds(245, 20, 100, 100);
scoreBox.setBounds(240, TABLE_HEIGHT - 70, 120, 30);
scoreBox.setText("Score: 0");
scoreBox.setEditable(false);
scoreBox.setOpaque(false);
timeBox.setBounds(360, TABLE_HEIGHT - 70, 120, 30);
timeBox.setText("Seconds: 0");
timeBox.setEditable(false);
timeBox.setOpaque(false);
startTimer();
toggleTimerButton.setBounds(480, TABLE_HEIGHT - 70, 125, 30);
toggleTimerButton.addActionListener(new ToggleTimerListener());
statusBox.setBounds(605, TABLE_HEIGHT - 70, 180, 30);
statusBox.setEditable(false);
statusBox.setOpaque(false);
table.add(statusBox);
table.add(toggleTimerButton);
table.add(gameTitle);
table.add(timeBox);
table.add(newGameButton);
table.add(showRulesButton);
table.add(scoreBox);
table.repaint();
}
public static void main(String[] args)
{
Container contentPane;
frame.setSize(TABLE_WIDTH, TABLE_HEIGHT);
table.setLayout(null);
table.setBackground(new Color(0, 180, 0));
contentPane = frame.getContentPane();
contentPane.add(table);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
playNewGame();
table.addMouseListener(new CardMovementManager());
table.addMouseMotionListener(new CardMovementManager());
frame.setVisible(true);
}
}
我很抱歉有大量代码转储,但我真的不知道造成这个问题的原因。这是我启动应用程序后产生的游戏。
这是由此产生的游戏。首先,我认为卡片总是朝错误的方向走,但即使我粗暴地强迫faceUp为真;他们看起来仍然像这样。
可能不是有史以来最整洁的问题,但我真的不知道我在这里做错了什么。