21點撲克牌小遊戲,想必大家都玩過。
今天我們來演示如何使用java+swing去實現一個21點撲克牌小遊戲,主要提供思路。
源碼獲取地址【當牛作碼-最專業的源代碼分享網站】:http://www.xiaoniucr.com/project/view/12.html
項目介紹:
本系統主要使用eclipse+jdk1.7開發,使用swing圖形化組件。
核心代碼:
import java.util.Vector;
public class Player {
/**
* @author qianXu
* @param money : 賭金
* @param cards : 牌面
* @param state : 勝負
*/
private double money; //賭金
private Vector<Card> cards= new Vector<Card>(); //牌面
private State state;
public Player()
{
this.money = 1000; //初始玩家有1000賭注
}
/* 設置牌面 */
public void addCard(Card card){
cards.add(card);
}
/* 設置賬戶餘額 */
public void addMoney(double point){
this.money += point;
}
public void minusMoney(double point){
this.money -= point;
}
/*設置勝負狀態*/
public void setState(State state){
this.state = state;
}
/* 重新開局 */
public void ReStart(){
cards.clear();
}
/* 獲取牌面 */
public Vector<Card> getCards(){
return cards;
}
/* 計算牌面 */
public int calculator(){
int sum = 0 ;
for (int i=0; i < cards.size(); i++ ){
Card temp = (Card) cards.elementAt(i);
if(temp.getValue()<=10)
sum += temp.getValue();
else if (temp.getValue()>10)
sum += 10;
}
if( hasBJ() && sum<12 ){ //擁有黑桃A
sum = sum + 10 ; //將黑桃A算作11
}
return sum;
}
/*獲取牌數*/
public int getNum(){
return cards.size();
}
/* 獲取餘額 */
public double getMoney()
{
return money;
}
/*獲取勝負狀態*/
public State getState(){
return state;
}
/*展示牌面 (僅爲測試)*/
public void showCard()
{
for(int i=0; i<cards.size();i++){
((Card) cards.elementAt(i)).showCard();
}
}
/*是否擁有黑傑克*/
public Boolean hasBJ()
{
boolean flagA = false;
boolean flagJ = false;
//有A
for(int i=0; i<cards.size();i++)
{
Card temp = (Card) cards.get(i);
if( temp.getValue() == 1)
flagA = true ;
}
//有J或Q或K
for(int i=0; i<cards.size();i++)
{
Card temp = (Card) cards.get(i);
if( temp.getValue()==11 ||temp.getValue()==12 ||temp.getValue()==13 )
flagJ = true ;
}
return (flagA && flagJ);
}
}
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
public class GameFrame extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
Player Comp = new Player(); //莊家 電腦
Player Gamer = new Player(); //玩家 人
JButton clear_btn=new JButton(); //洗牌按鈕
JButton compute_btn=new JButton(); //遊戲開始按鈕
JButton point_btn=new JButton(); //玩家下注按鈕
JButton game_btn=new JButton();//玩家按鈕
JButton gameover_btn=new JButton(); //遊戲結束按鈕
JLabel money_lab = new JLabel(); //玩家賬戶餘額
JLabel point_lab = new JLabel(); //玩家賬戶餘額
JLabel game[]=new JLabel[52]; //放置52張牌的標籤框
CardManager cm=new CardManager(); //定義指派管理類的對象
int i=0; //記錄抓牌數
int computer_dot=0; //記錄電腦點數
int game_dot=0; //記錄玩家點數
double point = 0; //下注金額
JLabel jLabel1=new JLabel(); //莊家區
JLabel jLabel2=new JLabel(); //玩家區
JLabel jLabel3=new JLabel(); //圖標區
JLabel jLabel4=new JLabel(); //背景區
public GameFrame(){
getContentPane().setLayout(null);
this.setTitle("二十一點遊戲");
this.setSize(1000,750);
//獲得當前屏幕的寬和高
Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize=this.getSize(); //獲得當前窗體的寬和高
//設置窗體居中
if(frameSize.height>screenSize.height) frameSize.height=screenSize.height;
if(frameSize.width>screenSize.width) frameSize.width=screenSize.width;
this.setLocation((screenSize.width-frameSize.width)/2,(screenSize.height-frameSize.height)/2);
clear_btn.setBounds(new Rectangle(78,388,120,40)); //設置位置
clear_btn.setText("洗牌"); //設置標籤內容
clear_btn.addActionListener(this); //註冊監聽器
compute_btn.setBounds(new Rectangle(233,388,120,40));
compute_btn.setEnabled(false);//不能更改
compute_btn.setText("開始遊戲");
compute_btn.addActionListener(this);
point_btn.setBounds(new Rectangle(413,389,120,40));
point_btn.setEnabled(false);
point_btn.setText("玩家下注");
point_btn.addActionListener(this);
game_btn.setBounds(new Rectangle(625,390,120,40));
game_btn.setEnabled(false);
game_btn.setText("玩家抓牌");
game_btn.addActionListener(this);
gameover_btn.setBounds(new Rectangle(837,390,120,40));
gameover_btn.setEnabled(false);
gameover_btn.setText("本輪結果");
gameover_btn.addActionListener(this);
money_lab = new JLabel("賬戶餘額:"+ Gamer.getMoney());
money_lab.setBounds(new Rectangle(800,500,250,70));
money_lab.setFont(new Font("宋體",Font.BOLD, 16));
point_lab = new JLabel("下注金額: "+ point);
point_lab.setBounds(new Rectangle(500,500,250,70));
point_lab.setFont(new Font("宋體",Font.BOLD, 16));
JMenuBar mb=new JMenuBar(); //定義菜單條
JMenu mnuFile=new JMenu("菜單"); //定義菜單
JMenu mnuHelp=new JMenu("幫助");
JMenuItem mnuFileSet=new JMenuItem("設置..."); //定義菜單項
JMenuItem mnuFileExit=new JMenuItem("退出");
JMenuItem mnuHelpAbout=new JMenuItem("關於...");
this.setJMenuBar(mb); //把菜單條添加到窗體上
jLabel1.setText("莊家顯示牌區");
jLabel1.setBounds(new Rectangle(250,340,95,38));
jLabel2.setText("玩家顯示牌區");
jLabel2.setBounds(new Rectangle(600,340,95,38));
jLabel3.setBounds(new Rectangle(0,450,250,250));
jLabel3.setIcon(new ImageIcon("images/blackJack.png"));
jLabel4.setBounds(new Rectangle(0,0,1000,340));
jLabel4.setIcon(new ImageIcon("images/background.jpg"));
mb.add(mnuFile); //將菜單加到菜單條中
mb.add(mnuHelp);
mnuFile.add(mnuFileSet); //將菜單項添加到菜單中
mnuFile.add(mnuFileExit);
mnuHelp.add(mnuHelpAbout);
//對菜單產生的事件進行註冊
mnuFileSet.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
// new SetFrame();
}
});
mnuFileExit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
mnuHelpAbout.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
new AboutFrame();
}
});
this.getContentPane().add(jLabel4);
this.getContentPane().add(jLabel3);
this.getContentPane().add(jLabel2);
this.getContentPane().add(jLabel1);
this.getContentPane().add(game_btn);
this.getContentPane().add(clear_btn);
this.getContentPane().add(point_btn);
this.getContentPane().add(gameover_btn);
this.getContentPane().add(compute_btn);
this.getContentPane().add(money_lab);
this.getContentPane().add(point_lab);
this.setVisible(true);
}
public static void main(String [] args){
new GameFrame();
}
public void actionPerformed(ActionEvent e){
//洗牌按鈕
if(e.getSource()==clear_btn){
//關閉和開啓相應的按鈕
compute_btn.setEnabled(true);
clear_btn.setEnabled(false);
getContentPane().repaint();
if(Gamer.getMoney() <= 0)
JOptionPane.showMessageDialog(null,"對不起!您已身無分文了哦 !請退出遊戲重新開局吧!","本輪遊戲的結果",JOptionPane.INFORMATION_MESSAGE);
//對記牌器,電腦點數和玩家點數進行初始化
i=0;
point = 0 ; //下注清零
Comp.ReStart(); Gamer.ReStart(); //玩家牌清空
point_lab.setText("下注金額: 0.0");
//把標籤控件數組放入窗體的窗格中
cm.gameStart(game, this.getContentPane());
cm.initCards(); //初始化一副紙牌
cm.randomCards(); //隨機打亂
cm.ShowCard(); //查看打亂的牌序 僅爲測試
}
//開始遊戲按鈕
if(e.getSource()==compute_btn){
//關閉和開啓相應的按鈕
compute_btn.setEnabled(false);
point_btn.setEnabled(true);
//電腦抓牌//最多抓5張,大於15點就不再抓牌
for(int k=0;k<5;k++){
//繪製牌面(僅有背面)
getContentPane().add(game[i]);
game[i].setIcon(new ImageIcon("images/puke.jpg"));
game[i].setBounds(new Rectangle(50+i*20,100,105,150));
getContentPane().setComponentZOrder(game[i],0);
getContentPane().repaint();
Comp.addCard(cm.cards[i]); //電腦抓牌
i=i+1; //記錄已發牌數
//如果面值大於15 或 已經擁有5張牌 則停止抓牌
if(Comp.calculator()>15 || Comp.getCards().size()>=5)
{
Comp.showCard(); //展現電腦牌面 (僅供測試)
return;
}
}
}
//玩家下注按鈕
if(e.getSource()==point_btn){
String temp = JOptionPane.showInputDialog("請輸入下注金額:"); //提示輸入員工姓名
if(temp.equals(""))
point = 0; //空值 賭注爲0
else
point = Double.parseDouble(temp);
while(point>Gamer.getMoney() || point < 0)
point = Double.valueOf(JOptionPane.showInputDialog("下注金額不能大於本金且,請重新輸入:"));
point_lab.setText("下注金額: "+point);
System.out.println("下注金額:" +point);
game_btn.setEnabled(true);
point_btn.setEnabled(false);
}
//玩家抓牌按鈕
if(e.getSource()==game_btn){
//提示玩家
if(Gamer.getNum()>=2){
int a=JOptionPane.showConfirmDialog(null,"現在點數爲:"+Gamer.calculator()+"是否再抓牌","提示",JOptionPane.NO_OPTION);
if(a==JOptionPane.NO_OPTION){
game_btn.setEnabled(false);
gameover_btn.setEnabled(true);
return;
}
}
//設置標籤,顯示抓到的紙牌
getContentPane().add(game[i]);
game[i].setIcon(new ImageIcon("images/"+cm.cards[i].getType()+"-"+cm.cards[i].getValue()+".jpg"));
game[i].setBounds(new Rectangle(450+i*20,100,105,150));
this.getContentPane().setComponentZOrder(game[i],1);
//給玩家發牌:
Gamer.addCard(cm.cards[i]);
i=i+1; //記錄已發的牌數
//面值大於21或已超過5張牌時停止抓牌,關閉和開啓相應的按鈕
if(Gamer.calculator()>21 || Gamer.getCards().size()>=5){
game_btn.setEnabled(false);
gameover_btn.setEnabled(true);
Gamer.showCard();
return;
}
}
//本輪遊戲結束按鈕
if(e.getSource()==gameover_btn){
//顯示電腦的紙牌
for(int i=0;i<Comp.getCards().size();i++){
Card card=(Card)Comp.getCards().get(i);
getContentPane().add(game[i]);
game[i].setIcon(new ImageIcon("images/"+card.getType()+"-"+card.getValue()+".jpg"));
game[i].setBounds(new Rectangle(50+i*20,100,105,150));
this.getContentPane().setComponentZOrder(game[i],Comp.getCards().size()-i);
}
JOptionPane.showMessageDialog(null,GetResult(),"本輪遊戲的結果",JOptionPane.INFORMATION_MESSAGE);
//更新賭金:
money_lab.setText("賬戶餘額: " + Gamer.getMoney());
//設置按鈕可操作
clear_btn.setEnabled(true);
gameover_btn.setEnabled(false);
}
}
/*獲取結果*/
public String GetResult()
{
new Regulation(Comp,Gamer);//創建re對象 找出獲勝者
//結果設置:
int gp = Gamer.calculator();//玩家點數
int cp = Comp.calculator();//莊家點數
String result = "莊家點數:"+cp+"\n玩家點數: "+gp +"\n"; //結果
if(Gamer.getState() == State.WIN){
if(Gamer.hasBJ()) //擁有黑傑克 雙倍賭注
point = point*2;
result = result + "恭喜你!你贏啦!贏得了: "+ point + " 賭注。";
Gamer.addMoney(point);
}
else if (Gamer.getState() == State.DRAW)
result = result + "平局哦!您的餘額沒有變化";
else if(Gamer.getState() == State.LOST){
result = result + "對不起!你輸啦!輸了: "+ point + " 賭注。";
Gamer.minusMoney(point);
}
return result;
}
}
運行截圖: