1. 抛双骰游戏的Swing界面版(CLI命令行版本见:学以致用——Java源码——抛双骰儿游戏改进版(Craps Game Modification with wagering),https://blog.csdn.net/hpdlzu80100/article/details/85231636)
2. 单一页面游戏(Single page application)
3. 设置了初始金额账户为1000,账户金额等于0时,无法继续游戏
4. 用户可设置下注金额(默认为0,即,不下注,没有输赢,但可以无限玩下去)
5. 添加了动态图,提高游戏的生动程度
注:相比命令行版本的游戏,这个版本已经有一定的可玩性了,准备有空给孩子们“炫炫”。
1. 实体类
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.security.SecureRandom;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
*
* 6.33 (Craps Game Modification) Modify the craps program of Fig. 6.8 to allow
* wagering. Initialize variable bankBalance to 1000 dollars. Prompt the player
* to enter a wager. Check that wager is less than or equal to bankBalance, and
* if it’s not, have the user reenter wager until a valid wager is entered.
* Then, run one game of craps. If the player wins, increase bankBalance by
* wager and display the new bankBalance. If the player loses, decrease
* bankBalance by wager, display the new bank- Balance, check whether
* bankBalance has become zero and, if so, display the message "Sorry. You
* busted!" As the game progresses, display various messages to create some
* “chatter,” such as "Oh, you're going for broke, huh?" or "Aw c'mon, take a
* chance!" or "You're up big. Now's the time to cash in your chips!". Implement
* the “chatter” as a separate method that randomly chooses the string to
* display.
*
* 12.16 (GUI-Based Craps Game) Modify the application of Section 6.10 to
* provide a GUI that enables the user to click a JButton to roll the dice. The
* application should also display four JLabels and four JTextFields, with one
* JLabel for each JTextField. The JTextFields should be used to display the
* values of each die and the sum of the dice after each roll. The point should
* be displayed in the fourth JTextField when the user does not win or lose on
* the first roll and should continue to be displayed until the game is lost.
*
*/
public class CrapsWithWagerFrame extends JFrame
{
//声明控件
private JLabel dice1PointJLabel;
private JLabel dice2PointJLabel;
private JLabel totalPointJLabel;
private JLabel gameResultJLabel;
private JLabel wagerJLabel;
private JLabel accountBalanceJLabel;
private JLabel errorMsgJLabel;
private JLabel hintJLabel;
private JLabel expressionJLabel;
private JButton startJButton;
private JTextField randMsgJTextField;
private JTextField dice1PointTextField;
private JTextField dice2PointTextField;
private JTextField totalPointTextField;
private JTextField gameResultTextField;
private JTextField wagerTextField;
private JTextField accountBalanceTextField;
private JPanel mainJPanel;
private JPanel topJPanel;
private static final String[] expressions =
{"smile.gif", "cry.gif", "fight.gif", "dice.gif"};
private final Icon[] icons = {
new ImageIcon(getClass().getResource(expressions[0])),
new ImageIcon(getClass().getResource(expressions[1])),
new ImageIcon(getClass().getResource(expressions[2])),
new ImageIcon(getClass().getResource(expressions[3]))};
// create secure random number generator for use in method rollDice
private static final SecureRandom randomNumbers = new SecureRandom();
// enum type with constants that represent the game status
private enum Status {CONTINUE, WON, LOST, NOTSTARTED};
// constants that represent common rolls of the dice
private static final int SNAKE_EYES = 2;
private static final int TREY = 3;
private static final int SEVEN = 7;
private static final int YO_LEVEN = 11;
private static final int BOX_CARS = 12;
private int myPoint = 0; // point if no win or loss on first roll
private Status gameStatus; // can contain CONTINUE, WON or LOST
private int bankBalance = 1000;
private int wager = 0;
private int sumOfDice;
private int count = 0; //记录游戏一局游戏的回合次数
public CrapsWithWagerFrame () {
super("抛双骰游戏——图形界面版(GUI-Based Craps Game)");
//setLayout(new FlowLayout(FlowLayout.CENTER,3,2));
//初始化基本控件及变量
accountBalanceJLabel = new JLabel("账户余额:");
wagerJLabel = new JLabel("下注金额:");
dice1PointJLabel = new JLabel("骰子1点数:");
dice2PointJLabel = new JLabel("骰子2点数:");
totalPointJLabel = new JLabel("平手点数:");
gameResultJLabel = new JLabel("游戏结果:");
errorMsgJLabel = new JLabel("");
errorMsgJLabel.setFont(new Font("宋体", Font.BOLD, 16));
hintJLabel = new JLabel("温馨提示:");
hintJLabel.setFont(new Font("宋体", Font.BOLD,13));
expressionJLabel = new JLabel(icons[3]);
startJButton = new JButton("开始游戏");
wagerTextField = new JTextField("0",5);
dice1PointTextField = new JTextField(5);
dice1PointTextField.setEditable(false);
dice2PointTextField = new JTextField(5);
dice2PointTextField.setEditable(false);
totalPointTextField = new JTextField(5);
totalPointTextField.setEditable(false);
gameResultTextField = new JTextField(30);
gameResultTextField.setEditable(false);
randMsgJTextField = new JTextField(30);
randMsgJTextField.setEditable(false);
randMsgJTextField.setText(chat());
accountBalanceTextField = new JTextField(6);
accountBalanceTextField.setText(Integer.toString(bankBalance));
accountBalanceTextField.setEnabled(false);
accountBalanceTextField.setFont(new Font("Arial", Font.BOLD,13));
mainJPanel = new JPanel();
topJPanel = new JPanel();
gameStatus = Status.NOTSTARTED; //游戏启动时的状态
//注册事件监听程序
startJButton.addActionListener(new ButtonHandler());
startJButton.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
playGame();
}
});
topJPanel.setLayout(new FlowLayout(FlowLayout.LEFT,10,2));
topJPanel.add(startJButton);
topJPanel.add(hintJLabel);
topJPanel.add(randMsgJTextField);
add(topJPanel,BorderLayout.NORTH);
mainJPanel.setLayout(new FlowLayout(FlowLayout.LEFT,5,3));
mainJPanel.add(accountBalanceJLabel);
mainJPanel.add(accountBalanceTextField);
mainJPanel.add(wagerJLabel);
mainJPanel.add(wagerTextField);
mainJPanel.add(dice1PointJLabel);
mainJPanel.add(dice1PointTextField);
mainJPanel.add(dice2PointJLabel);
mainJPanel.add(dice2PointTextField);
mainJPanel.add(totalPointJLabel);
mainJPanel.add(totalPointTextField);
mainJPanel.add(gameResultJLabel);
mainJPanel.add(gameResultTextField);
mainJPanel.add(expressionJLabel);
add(mainJPanel);
add(errorMsgJLabel,BorderLayout.SOUTH);
setVisible(true);
}
// inner class for button event handling
// plays one game of craps
private class ButtonHandler implements ActionListener
{
// handle button event
@Override
public void actionPerformed(ActionEvent event)
{
playGame();
}
}
// roll dice, calculate sum and display results
/**
*
* @return 抛双骰点数
* @Date Jan 15, 2019, 10:10:14 AM
*/
private int rollDice()
{
// pick random die values
int die1 = 1 + randomNumbers.nextInt(6); // first die roll
int die2 = 1 + randomNumbers.nextInt(6); // second die roll
dice1PointTextField.setText(Integer.toString(die1));
dice2PointTextField.setText(Integer.toString(die2));
int sum = die1 + die2; // sum of die values
return sum;
}
// 输出随机聊天信息
/**
*
* @return 随机聊天信息
* @Date Jan 15, 2019, 10:09:33 AM
*/
public String chat()
{
int msgNum = 1 + randomNumbers.nextInt(4); // 生成随机消息编号
String randMsg = "";
//表示随机聊天信息的常数
final String MSG1 = "不要小看抛双骰儿,这里面有大学问!";
final String MSG2 = "今天点子有点儿背?积德行善会转运哦!";
final String MSG3 = "小赌怡情,大赌伤身哦!";
final String MSG4 = "运气是什么,账户余额翻倍靠的就是运气!";
//提示下注
switch (msgNum){
case 1:
randMsg = MSG1;
break;
case 2:
randMsg = MSG2;
break;
case 3:
randMsg = MSG3;
break;
case 4:
randMsg = MSG4;
break;
}
return randMsg;
}
public void playGame() {
//新开一局
if (gameStatus != Status.CONTINUE) {
randMsgJTextField.setText(chat()); //随机输出聊天信息,增强游戏的互动性
//新开一局初始化
count = 0; //重置回合计数器
totalPointTextField.setText(""); //平手点数重置
errorMsgJLabel.setText(""); //重置错误消息显示区
wagerTextField.setEditable(true); //启用下注金额文本框的编辑功能
expressionJLabel.setIcon(icons[3]); //重置表情
wager = Integer.parseInt(wagerTextField.getText()); //重新设置下注金额
//下注金额校验 (下注金额等于0时,账户余额不会发生改变)
if (wager <0 || wager > bankBalance) {
errorMsgJLabel.setText("输入错误:请输入有效的下注金额!");
wagerTextField.setText("");
}
else {
sumOfDice = rollDice(); // first roll of the dice
// determine game status and point based on first roll
switch (sumOfDice)
{
case SEVEN: // win with 7 on first roll
case YO_LEVEN: // win with 11 on first roll
gameStatus = Status.WON;
bankBalance += wager;
gameResultTextField.setText(String.format("恭喜你,你赢了!你当前账户余额为:%d", bankBalance));
accountBalanceTextField.setText(Integer.toString(bankBalance));
randMsgJTextField.setText(chat()); //随机输出聊天信息,增强游戏的互动性
wagerTextField.setEditable(true); //启用下注金额文本框的编辑功能
expressionJLabel.setIcon(icons[0]);
break;
case SNAKE_EYES: // lose with 2 on first roll
case TREY: // lose with 3 on first roll
case BOX_CARS: // lose with 12 on first roll
gameStatus = Status.LOST;
//计算账户余额
if (bankBalance - wager >= 0) {
bankBalance -= wager;
gameResultTextField.setText(String.format("哦哦,你输了!你当前账户余额为:%d", bankBalance));
}
else {
bankBalance = 0;
gameResultTextField.setText("哦哦,你输了!你当前账户余额已清零!请努力工作,挣钱后再来吧!");
}
gameResultTextField.setText(String.format("哦哦,你输了!你当前账户余额为:%d", bankBalance));
accountBalanceTextField.setText(Integer.toString(bankBalance));
randMsgJTextField.setText(chat()); //随机输出聊天信息,增强游戏的互动性
wagerTextField.setEditable(true); //启用下注金额文本框的编辑功能
expressionJLabel.setIcon(icons[1]);
break;
default: // did not win or lose, so remember point
gameStatus = Status.CONTINUE; // game is not over
wagerTextField.setEditable(false); //平手时不能修改下注金额
count ++;
myPoint = sumOfDice; // remember the point,第一次平手时,记录点数
gameResultTextField.setText(String.format("哦,平手!点数为: %d%n", myPoint));
totalPointTextField.setText(Integer.toString(myPoint));
startJButton.setText("继续游戏");
randMsgJTextField.setText(chat()); //随机输出聊天信息,增强游戏的互动性
expressionJLabel.setIcon(icons[2]);
break;
}
}
}
//平手状态,继续当前一局的游戏
else if (gameStatus == Status.CONTINUE) {
randMsgJTextField.setText(chat()); //随机输出聊天信息,增强游戏的互动性
errorMsgJLabel.setText(""); //重置错误消息显示区
sumOfDice = rollDice(); // roll dice again
// determine game status
if (sumOfDice == myPoint) // win by making point
{gameStatus = Status.WON;
bankBalance += wager;
gameResultTextField.setText(String.format("恭喜你,你赢了!你当前账户余额为:%d", bankBalance));
accountBalanceTextField.setText(Integer.toString(bankBalance));
startJButton.setText("开始游戏");
randMsgJTextField.setText(chat()); //随机输出聊天信息,增强游戏的互动性
wagerTextField.setEditable(true); //启用下注金额文本框的编辑功能
expressionJLabel.setIcon(icons[0]);
}
else if (sumOfDice == SEVEN) // lose by rolling 7 before point
{
gameStatus = Status.LOST;
//计算账户余额
if (bankBalance - wager >= 0) {
bankBalance -= wager;
gameResultTextField.setText(String.format("哦哦,你输了!你当前账户余额为:%d", bankBalance));
}
else {
bankBalance = 0;
gameResultTextField.setText("哦哦,你输了!你当前账户余额已清零!请努力工作,挣钱后再来吧!");
}
accountBalanceTextField.setText(Integer.toString(bankBalance));
startJButton.setText("开始游戏");
randMsgJTextField.setText(chat()); //随机输出聊天信息,增强游戏的互动性
wagerTextField.setEditable(true); //启用下注金额文本框的编辑功能
expressionJLabel.setIcon(icons[1]);
}
else {
gameStatus = Status.CONTINUE; // game is not over
count++;
gameResultTextField.setText(String.format("还是平手哦!第%d次平手",count));
totalPointTextField.setText(Integer.toString(myPoint));
randMsgJTextField.setText(chat()); //随机输出聊天信息,增强游戏的互动性
expressionJLabel.setIcon(icons[2]);
}
}
}
} // end class
2. 测试类
import javax.swing.JFrame;
public class CrapsWithWagerFrameTest {
public static void main(String[] args)
{
CrapsWithWagerFrame testFrame = new CrapsWithWagerFrame();
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testFrame.setSize(600, 580);
testFrame.setVisible(true);
}
}