Java实验-Swing 扑克牌游戏
实验要求:
- 扑克牌游戏是非常具有趣味性游戏,如下图所示,建立一个窗口界面,用JLable和相关组件(比如适当增加按钮,文本域等,可以自由发挥)实现以下界面,要求:
- 点击任何一张牌,能控制其向上方移动,表示选中状态。再次点击该张扑克牌,又能回复到初始状态。
- 可以增加洗牌功能,让扑克牌的位置打乱。需要增加按钮。
- 其他趣味性的组件,自己可以增加。
代码:
(扑克牌资源:)
PukerFrame类:
package com.junlin.exer5;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PukerFrame extends JFrame {
private Container contentPane;
private String template = "resources/%s"; //图片路径字符串模板
private Map<JLabel,Integer> hs = new HashMap<>(); //用来记录每张扑克牌的状态,方便判断扑克牌是否被选中
private Map<JLabel,Integer> label2num = new HashMap<>(); //用来记录label到数字的映射,方便理牌
List<JLabel> pukers; //存放每一张扑克牌label,方便进行洗牌和理牌
JButton shuffleBtn; //洗牌按键
JButton tidyBtn; //理牌按键
public PukerFrame() {
super("扑克牌游戏");
this.setSize(1200,800);
this.contentPane = this.getContentPane();
// this.contentPane.setBackground(Color.GREEN);
this.contentPane.setLayout(null);
addBackground(); //为窗体添加背景图片
shuffleBtn = new JButton("洗牌");
tidyBtn = new JButton("理牌");
shuffleBtn.setBounds(400,50,70,50);
tidyBtn.setBounds(700,50,70,50);
initListener(); //初始化两个按键的监听事件
this.contentPane.add(shuffleBtn);
this.contentPane.add(tidyBtn);
ImageIcon imageIcon = null;
pukers = new ArrayList<>(); //用来存储所有扑克牌label
//初始化所有的扑克牌Label,并存储到pukers集合中
//添加大小王
JLabel xw = new JLabel(change(new ImageIcon(String.format(template, "puke53.jpg")), 0.6));
JLabel dw = new JLabel(change(new ImageIcon(String.format(template, "puke54.jpg")), 0.6));
pukers.add(xw); pukers.add(dw);
label2num.put(xw, -2); label2num.put(dw, -1);
for(int i = 1;i <= 52;i++) {
String pic = "puke" + i + ".jpeg";
imageIcon = change(new ImageIcon(String.format(template, pic)), 0.6); //把图片进行缩放
JLabel label = new JLabel(imageIcon);
pukers.add(label);
label2num.put(label, i);
}
paintPuker(); //在窗口中展示扑克牌
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//为洗牌和理牌两个按键添加监听事件
private void initListener(){
this.shuffleBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Collections.shuffle(pukers); //打乱集合中的扑克牌
paintPuker(); //重新绘制扑克牌
}
});
this.tidyBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//将集合中的扑克牌进行排序
Collections.sort(pukers, (o1, o2) -> label2num.get(o1) - label2num.get(o2));
paintPuker(); //重新绘制扑克牌contentPane.validate();
}
});
}
/**
* 为窗体添加背景图片
*/
private void addBackground(){
JLabel bgLabel = new JLabel(/*new ImageIcon("resources/bg.jpg")*/);
bgLabel.setOpaque(true);
bgLabel.setPreferredSize(new Dimension(this.getWidth(), this.getHeight()));
ImageIcon bgImage = new ImageIcon("resources/bg.jpg");
bgImage.setImage(bgImage.getImage().getScaledInstance(1200, 800, Image.SCALE_DEFAULT));
bgLabel.setIcon(bgImage);
bgLabel.setBounds(0,0,this.getWidth(), this.getHeight());
System.out.printf("%d %d\n",bgLabel.getWidth(), bgLabel.getHeight());
this.contentPane.add(bgLabel);
JPanel imagePanel = (JPanel) this.contentPane;
imagePanel.setOpaque(false);
this.getLayeredPane().add(bgLabel, new Integer(Integer.MIN_VALUE));
}
/**
* 图片缩放
*/
public ImageIcon change(ImageIcon image,double i) {// i 为放缩的倍数
int width = (int) (image.getIconWidth() * i);
int height = (int) (image.getIconHeight() * i);
Image img = image.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT);
ImageIcon image_new = new ImageIcon(img);
return image_new;
}
/**
* 将所有的扑克牌绘制到窗体中
*/
public void paintPuker(){
int X = this.getWidth() - 130, Y = 500;
for(int i = 54;i >= 1;i--) { //从后往前添加扑克牌
JLabel label = pukers.get(i-1);
label.setBounds(X, Y, label.getIcon().getIconWidth(), label.getIcon().getIconHeight());
this.contentPane.add(label);
hs.put(label,0);
X -= 20; //X坐标依次递减
label.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
int x = label.getX(), y = label.getY(), width = label.getWidth(), height = label.getHeight();
if(hs.get(label) == 0) { //之前没有被选中
label.setBounds(x, y - 50, width, height);
}else { //之前被选中了
label.setBounds(x, y + 50, width, height);
}
hs.put(label,1-hs.get(label)); //更新当前扑克牌的状态
}
});
}
}
}
ImagePanel类:
package com.junlin.exer5;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.sql.SQLOutput;
public class ImagePanel extends JPanel {
private Image image = Toolkit.getDefaultToolkit().getImage("resources/bg.jpg");
public void paintImage(Image image) {
this.image = image;
this.repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.printf("%d %d\n", this.getWidth(), this.getHeight());
g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
}
}
JavaMain类:
package com.junlin.exer5;
public class JavaMain {
public static void main(String[] args) {
new PukerFrame();
}
}
你只管出发,旅途自有风景~~