学以致用——Java源码——抛双骰游戏图形界面版(GUI-Based Craps Game)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hpdlzu80100/article/details/86493324

游戏简介:

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

}

猜你喜欢

转载自blog.csdn.net/hpdlzu80100/article/details/86493324
今日推荐