Java实验-Swing 扑克牌游戏

实验要求:

  1. 扑克牌游戏是非常具有趣味性游戏,如下图所示,建立一个窗口界面,用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();
    }
}

posted @ 2023-03-02 13:10  junlin623  阅读(448)  评论(0编辑  收藏  举报