利用Java swing技术能够实现玩家与电脑进行二十一点游戏。要求如下:
Card.java:
package 二十一点游戏;
public class Card {
private int value = 0; //纸牌面值
private int type = 0; //纸牌花色
public Card(int type, int value) {
this.value = value;
this.type = type;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
CardManager.java:
package 二十一点游戏;
import java.awt.Container;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class CardManager {
public Card[] cards = new Card[52];
//初始化一副52张纸牌
public void initCards() {
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 13; j++) {
cards[(i - 1)*13 + j - 1] = new Card(i, j);
}
}
}
//随机打乱这52张纸牌
public void randomCards() {
Card temp = null;
//随机生成牌号
for (int i = 0; i < 52; i++) {
int a = (int)(Math.random()*52);
int b = (int)(Math.random()*52);
temp = cards[a];
cards[a] = cards[b];
cards[b] = temp;
}
}
//显示纸牌图片
public void gameStart(JLabel game[], Container c) {
//在容器中删除标签组件
if (game[0] != null) {
for (int i = 0; i < 52; i++) {
c.remove(game[i]);
}
c.repaint();
}
//在容器中放置52个标签组件用于放置图片
for (int i = 0; i < 52; i++) {
game[i] = new JLabel();
game[i].setBorder(javax.swing.BorderFactory.createEtchedBorder());
game[i].setBounds(new Rectangle(100 + i*10, 10, 101, 150));
c.add(game[i]);
}
//设置标签组件的图片为rear.jpg,即牌的背面
for (int i = 0; i < 52; i++) {
game[i].setIcon(new ImageIcon("images/rear.jpg"));
}
}
}
GameFrame.java:
package 二十一点游戏;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.*;
public class GameFrame extends JFrame implements ActionListener{
JButton clear_btn = new JButton("洗牌");
JButton compute_btn = new JButton("开始游戏");
JButton game_btn = new JButton("玩家抓牌");
JButton gameover_btn = new JButton("本轮结束");
CardManager cm = new CardManager();
JLabel game[] = new JLabel[52]; //放置52张扑克牌的标签
int i = 0; //定义抓牌数
int computer_dot = 0; //定义电脑点数
int game_dot = 0; //定义玩家点数
Vector v = new Vector(); //存储电脑抓的纸牌
JLabel jLabel1 = new JLabel("电脑显示牌区");
JLabel jLabel2 = new JLabel("玩家显示牌区");
public GameFrame() {
getContentPane().setLayout(null);
this.setTitle("二十一点游戏");
this.setSize(800, 500);
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, 73, 31));
clear_btn.addActionListener(this);
compute_btn.setBounds(new Rectangle(233, 388, 86, 31));
compute_btn.setEnabled(false);
compute_btn.addActionListener(this);
game_btn.setBounds(new Rectangle(413, 389, 91, 32));
game_btn.setEnabled(false);
game_btn.addActionListener(this);
gameover_btn.setBounds(new Rectangle(625, 390, 91, 32));
gameover_btn.setEnabled(false);
gameover_btn.addActionListener(this);
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("文件");
JMenu help = new JMenu("帮助");
JMenuItem fileExit = new JMenuItem("退出");
JMenuItem helpAbout = new JMenuItem("关于");
this.setJMenuBar(menuBar);
menuBar.add(file);
menuBar.add(help);
file.add(fileExit);
fileExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.exit(0);
}
});
help.add(helpAbout);
helpAbout.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
new AboutFrame();
}
});
jLabel1.setBounds(new Rectangle(104, 343, 95, 38));
jLabel2.setBounds(new Rectangle(499, 343, 92, 33));
this.getContentPane().add(jLabel1);
this.getContentPane().add(jLabel2);
this.getContentPane().add(clear_btn);
this.getContentPane().add(compute_btn);
this.getContentPane().add(game_btn);
this.getContentPane().add(gameover_btn);
this.setVisible(true);
this.setResizable(false);
}
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
//洗牌按钮
if (arg0.getSource() == clear_btn) {
//关闭和开启相应的按钮
compute_btn.setEnabled(true);
clear_btn.setEnabled(false);
//对记牌器、电脑点数和玩家点数进行初始化
i = 0;
computer_dot = 0;
game_dot = 0;
//把标签框控件数组放入窗体窗格中
cm.gameStart(game, this.getContentPane());
//初始化纸牌
cm.initCards();
//随机打乱纸牌
cm.randomCards();
}
//开始游戏按钮
if (arg0.getSource() == compute_btn) {
//关闭和开启相应的按钮
compute_btn.setEnabled(false);
game_btn.setEnabled(true);
//电脑抓牌
for (int k = 0; k < 20; k++) {
game[i].setIcon(new ImageIcon("images/rear.jpg"));
game[i].setBounds(new Rectangle(50 + i*20, 200, 101, 150));
getContentPane().setComponentZOrder(game[i], 1);
if (cm.cards[i].getValue() == 10) {
computer_dot = computer_dot + 1;
}else {
computer_dot = computer_dot + cm.cards[i].getValue();
}
v.add(cm.cards[i]);
getContentPane().repaint();
i = i + 1;
//如果面值总数大于15停止抓牌
if (computer_dot >= 15) {
return;
}
}
}
//玩家抓牌按钮
if (arg0.getSource() == game_btn) {
//提示
if (game_dot >= 10) {
int a = JOptionPane.showConfirmDialog(null, "现在点数为:"+game_dot+"是否再抓牌", "提示", JOptionPane.YES_NO_OPTION);
if (a == JOptionPane.NO_OPTION) {
game_btn.setEnabled(false);
gameover_btn.setEnabled(true);
return;
}
}
//设置标签框力里显示抓到的纸牌
game[i].setIcon(new ImageIcon("images/"+cm.cards[i].getType()+"-"+cm.cards[i].getValue()+".jpg"));
game[i].setBounds(new Rectangle(350 + i*20, 200, 101, 150));
this.getContentPane().setComponentZOrder(game[i], 1);
//计算抓到的纸牌面值
if (cm.cards[i].getValue() > 10) {
game_dot = game_dot + 1;
}else {
game_dot = game_dot + cm.cards[i].getValue();
}
i = i + 1;
//面值大于21停止抓牌,关闭和开启相应按钮
if (game_dot > 21) {
game_btn.setEnabled(false);
gameover_btn.setEnabled(true);
return;
}
}
//本轮游戏结束按钮
if (arg0.getSource() == gameover_btn) {
for (int i = 0; i < v.size(); i++) {
Card card = (Card)v.get(i);
game[i].setIcon(new ImageIcon("images/"+card.getType()+"-"+card.getValue()+".jpg"));
game[i].setBounds(new Rectangle(50 + i*20, 200, 101, 150));
this.getContentPane().setComponentZOrder(game[i], 1);
}
//计算胜负
String game_over = "";
if (game_dot > 21 && computer_dot <= 21) {
game_over = "电脑获胜";
} else if (game_dot <= 21 && computer_dot > 21) {
game_over = "玩家获胜";
}else if (game_dot >= 21 & computer_dot >= 21) {
game_over = "平局";
}else if (game_dot > computer_dot) {
game_over = "玩家获胜";
}else if (game_dot < computer_dot) {
game_over = "电脑获胜";
}else if (game_dot == computer_dot) {
game_over = "平局";
}
//以对话框的方式显示胜负
String message = "游戏结果\n";
message = message + "电脑点数:" + String.valueOf(computer_dot) + "\n";
message = message + "玩家点数:" + String.valueOf(game_dot) + "\n";
message = message + "游戏结果:" + game_over;
JOptionPane.showMessageDialog(null, message, "本轮游戏结果", JOptionPane.INFORMATION_MESSAGE);
//设置命令按钮可操作
clear_btn.setEnabled(true);
compute_btn.setEnabled(true);
game_btn.setEnabled(true);
gameover_btn.setEnabled(true);
}
}
public static void main(String[] args) {
GameFrame gameFrame = new GameFrame();
}
}
AboutFrame.java:
package 二十一点游戏;
import javax.swing.*;
import java.awt.*;
public class AboutFrame extends JFrame{
JLabel jLabel1 = new JLabel("游戏规则");
JLabel jLabel2 = new JLabel("声明");
JTextArea textArea1 = new JTextArea();
JTextArea textArea2 = new JTextArea();
public AboutFrame() {
getContentPane().setLayout(null);
jLabel1.setBounds(new Rectangle(27, 0, 97, 36));
jLabel2.setBounds(new Rectangle(26, 176, 80, 27));
textArea1.setColumns(40);
textArea1.setEditable(false);
textArea1.setLineWrap(true);
textArea1.setText("电脑先抓牌,玩家后抓牌。计算自己的面值总数,比较面值数,如果面值总数都大于或等于21,则平局;如果玩家和电脑的面值总数有一个大于21点,另一个不大于21点,则不大于21点的为赢家;如果玩家和电脑的面值总数都不大于21,则面值总数大的为赢家。");
textArea1.setBounds(new Rectangle(25, 36, 392, 130));
textArea1.setFont(new Font("楷体", Font.PLAIN, 16));
textArea2.setEditable(false);
textArea2.setLineWrap(true);
textArea2.setBounds(new Rectangle(26, 207, 398, 63));
textArea2.setText("该游戏中,纸牌的图片来自于WindowsXP的纸牌游戏,图片权属于原作者所有!");
textArea2.setFont(new Font("楷体", Font.PLAIN, 16));
this.getContentPane().add(jLabel1);
this.getContentPane().add(jLabel2);
this.getContentPane().add(textArea1);
this.getContentPane().add(textArea2);
this.setSize(450, 300);
this.setTitle("关于");
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);
this.setVisible(true);
}
}
最后附上项目地址以及图片资源:二十一点游戏