Java实现拼图小游戏

        Java中的图形化界面使用得是比较少的,但是可以用来结合前期学习的面向对象编程的思想,通过图形化的呈现,创造一个拼图小游戏。

        主要用的到的包:

import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

        类的继承和实现:

public class GameJFrame extends JFrame implements KeyListener, ActionListener

        主要思想:JFrame 、JMenu、JMenuBar、JMenuItem、JLabel、ImageIcon;数组、随机数、面向对象、键盘、鼠标监视、动作监视……

        游戏主体代码:

package GameUI;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
public class GameJFrame extends JFrame implements KeyListener, ActionListener {
    int x = 0; // 用x来记录空白块的数组行标
    int y = 0; // 用y来记录空白快数组的列标
    int[][] imageArray = new int[4][4];
    // 创建胜利数组,当imageArray和胜利数组完全一样的时候,代表游戏胜利
    int[][] winArray = new int[][] {
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,0}
    };
    // 用字符串来记录图片的路径,方便修改
    String path = "Game\\image\\animal\\animal3\\";
    // 用以记录移动步数
    int step = 0;
    // 创建功能中条目
    JMenuItem replayItem = new JMenuItem("重新开始");
    JMenuItem reLoginItem = new JMenuItem("重新登录");
    JMenuItem closeItem = new JMenuItem("关闭游戏");
    // 创建关于制作人员中条目
    JMenuItem accountItem = new JMenuItem("Rose");
    public GameJFrame() {
        // 设置界面
        setJFrame();
        // 设置菜单
        setMenu();
        // 初始化数组
        initArray();
        // 设置图片
        setImage();
        // 设置界面可见
        this.setVisible(true);
    }

    private void setJFrame() {
        // 设置界面大小
        this.setSize(603, 680);
        // 设置界面标题
        this.setTitle("Puzzle version 1.0");
        // 设置界面居中
        this.setLocationRelativeTo(null);
        // 设置界面永远在上
        this.setAlwaysOnTop(true);
        // 设置界面关闭模式
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        // 取消默认放置(JFrame只是一个框架,真正存放组件的是其中的ContentPanel
        // ,必须要取消默认放置的设定才可以自定义坐标放置)
        this.setLayout(null);
        // 添加键盘监听
        this.addKeyListener(this);
    }

    private void setMenu() {
        // 创建整个菜单对象
        JMenuBar jMenuBar = new JMenuBar();
        // 创建选项功能
        JMenu functionJMenu = new JMenu("功能  ");
        JMenu aboutJMenu = new JMenu("制作人员");
        // 给条目绑定事件
        replayItem.addActionListener(this);
        reLoginItem.addActionListener(this);
        closeItem.addActionListener(this);
        accountItem.addActionListener(this);

        // 在功能中加入条目
        functionJMenu.add(replayItem);
        functionJMenu.add(reLoginItem);
        functionJMenu.add(closeItem);
        // 在关于我们中加入条目
        aboutJMenu.add(accountItem);
        // 在菜单中加入选项
        jMenuBar.add(functionJMenu);
        jMenuBar.add(aboutJMenu);
        //  在JFrame中创建菜单
        this.setJMenuBar(jMenuBar);
    }

    public void setImage() {
        // 清空本来已经出现的图片
        this.getContentPane().removeAll();
        if (victory()) {
            JLabel victoryImage = new JLabel(new ImageIcon("D:\\codes\\Java\\PuzzleGame\\Game\\image\\win.png"));
            victoryImage.setBounds(203, 283, 197, 73);
            this.getContentPane().add(victoryImage);
        }
        JLabel stepImage = new JLabel("步数:" + step);
        stepImage.setBounds(50, 30, 100, 20);
        this.getContentPane().add(stepImage);
        for(int i = 0; i < 4; i++) {
            for(int j = 0; j < 4; j++) {
                int number = imageArray[i][j];
                // 创建新的图片对象(构造方法可以传入图片文件的路径)
                ImageIcon image = new ImageIcon(path + number + ".jpg");
                // JLabel是一个图片容器,可以将ImageIcon创造出来的图片对象加入这个容器
                JLabel jLabel = new JLabel(image);
                 /*设置图片在界面中的显示位置,每个小图片的像素是105*105;通过双重循环
                 可以达到将不同的图片,按行列放置到对应位置的效果*/
                jLabel.setBounds(105 * j + 83, 105 * i + 134, 105, 105);
                // 给每张图片设置一个边框,增强美观性
                jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));
                /*JFrame实际上只是一个框架,真正的组件实际上是“放置”于JFrame中的
                 ContentPanel中的,可以通过JFrame的getContentPanel方法得到,并且
                 在其中添加JLabel对象*/
                this.getContentPane().add(jLabel);
            }
        }

        // 添加背景图片
        ImageIcon background = new ImageIcon("Game\\image\\background.png");
        JLabel bg = new JLabel(background);
        bg.setBounds(40, 40, 508, 560);
        this.getContentPane().add(bg);
        // 刷新界面
        this.getContentPane().repaint();
    }

    public void initArray() {
        int[] arr = new int[16];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i;
        }

        Random r = new Random();
        int randomNumber;
        for (int i = 15; i >= 0; i--) {
            randomNumber = r.nextInt(i + 1);
            int temp = arr[randomNumber];
            arr[randomNumber] = arr[i];
            arr[i] = temp;
        }

        // 初始化时必须将二维数组全部设置为0
        // 如果不全部设置为0,上一次的数据会遗留
        for (int i = 0; i < imageArray.length; i++) {
            for (int j = 0; j < imageArray.length; j++) {
                imageArray[i][j] = 0;
            }
        }
        for(int i = 0; i < arr.length; i++) {
            if (arr[i] == 0) {
                this.x = i / 4;
                this.y = i % 4;
            } else{
                imageArray[i / 4][i % 4] = arr[i];
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if (code == 65) {
            this.getContentPane().removeAll();
            JLabel allImage = new JLabel(new ImageIcon(path + "all.jpg"));
            allImage.setBounds(83,134,420,420);
            this.getContentPane().add(allImage);
            // 添加背景图片
            ImageIcon background = new ImageIcon("Game\\image\\background.png");
            JLabel bg = new JLabel(background);
            bg.setBounds(40, 40, 508, 560);
            this.getContentPane().add(bg);
            // 刷新界面
            this.getContentPane().repaint();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (victory()) {
            return;
        }
        int code = e.getKeyCode();
        // 左移
        if (code == 37) {
            if (y == 3) {
                return;
            } else {
                imageArray[x][y] = imageArray[x][y + 1];
                imageArray[x][y + 1] = 0;
                y++;
                step++;
                setImage();
            }
        }
        // 上移
        else if (code == 38) {
            if (x == 3) {
                return;
            } else {
                imageArray[x][y] = imageArray[x + 1][y];
                imageArray[x + 1][y] = 0;
                x++;
                step++;
                setImage();
            }
        }
        // 右移
        else if (code == 39) {
            if (y == 0) {
                return;
            } else {
                imageArray[x][y] = imageArray[x][y - 1];
                imageArray[x][y - 1] = 0;
                y--;
                step++;
                setImage();
            }
        }
        // 下移
        else if (code == 40) {
            if (x == 0) {
                return;
            } else {
                imageArray[x][y] = imageArray[x - 1][y];
                imageArray[x - 1][y] = 0;
                x--;
                step++;
                setImage();
            }
        } else if (code == 65) {
            setImage();
        } else if (code == 87) {
            for (int i = 0; i < imageArray.length* imageArray.length; i++) {
                if (i == 15) {
                   imageArray[3][3] = 0;
                   break;
                }
                imageArray[i / 4][i % 4] = i + 1;
            }
            setImage();
        }
    }

    public boolean victory() {
        for (int i = 0; i < imageArray.length; i++) {
            for (int j = 0; j < imageArray.length; j++) {
                if (imageArray[i][j] != winArray[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object obj = e.getSource();
        if(obj == replayItem) {
            // 重开游戏
            // 步数清零
            step = 0;
            // 初始化图片数组
            initArray();
            // 展示打乱的图片
            setImage();
        } else if (obj == reLoginItem) {
            System.out.println("重新登录(待开发)");
        } else if (obj == accountItem) {
            // 制作者
            System.out.println("rose");
            // 创建一个新的JFrame对象
            JFrame rose = creatRose();
            // 创建玫瑰图像的对象
            ImageIcon roseImage = new ImageIcon("D:\\codes\\Java\\PuzzleGame\\Game\\image\\rose.jpg");
            // 创建JLabel容器存放玫瑰图像
            JLabel roseJB = new JLabel(roseImage);
            // 设置图像的位置和大小
            roseJB.setBounds(40, 40, 1080, 1080);
            // 将图像容器加入JFrame中
            rose.getContentPane().add(roseJB);

        } else if (obj == closeItem) {
            // 退出游戏
            // 直接关闭JVM虚拟机
            System.exit(0);
        }
    }

    public JFrame creatRose() {
        JFrame rose = new JFrame();
        // 设置宽高为1080*1080
        rose.setSize(1080, 1080);
        // 设置窗口可见
        rose.setVisible(true);
        // 设置窗口标题
        rose.setTitle("制作人员");
        // 设置窗口默认在屏幕中央
        rose.setLocationRelativeTo(null);
        // 设置窗口总是在最上层
        rose.setAlwaysOnTop(true);
        // 设置窗口关闭模式(只关闭当前JFrame窗口(默认关闭的方式))
        rose.setDefaultCloseOperation(HIDE_ON_CLOSE);
        // 返回JFrame对象
        return rose;
    }
}

        游戏的测试

import GameUI.GameJFrame;
import GameUI.LoginJFrame;
import GameUI.RegisterJFrame;
public class Application {
    public static void main(String[] args) {
        // 注册
        RegisterJFrame rj = new RegisterJFrame();
        // 登录
        LoginJFrame lj = new LoginJFrame();
        // 游戏
        GameJFrame gj = new GameJFrame();
    }
}

        还剩下的坑:登录、注册,等到日后有时间再把这个坑填上

package GameUI;
import javax.swing.*;
public class LoginJFrame extends JFrame {
    public LoginJFrame() {
        // 设置界面大小
        this.setSize(488, 430);
        // 设置界面标题
        this.setTitle("Login");
        // 设置界面居中
        this.setLocationRelativeTo(null);
        // 设置界面永远在上
        this.setAlwaysOnTop(true);
        // 设置界面关闭模式
        this.setDefaultCloseOperation(3);
        // 设置界面可见
        this.setVisible(true);
    }
}
package GameUI;
import javax.swing.*;
public class RegisterJFrame extends JFrame{
    public RegisterJFrame() {
        // 设置界面大小
        this.setSize(488, 500);
        // 设置界面标题
        this.setTitle("Register");
        // 设置界面居中
        this.setLocationRelativeTo(null);
        // 设置界面永远在上
        this.setAlwaysOnTop(true);
        // 设置界面关闭模式
        this.setDefaultCloseOperation(3);
        // 设置界面可见
        this.setVisible(true);
    }
}

 

 

 

        

  • 69
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值