拼图小游戏单机版---java实现

news2024/9/20 16:55:53

一、为什么要在这个阶段做这样的一个项目?

1、理解Swing框架:
这个项目使用了Swing框架来构建图形用户界面(GUI)。通过实践,你可以更好地掌握如何使用Swing组件(如JFrame, JLabel, JMenuBar等)以及它们的布局和事件处理机制。
2、提高编程技能:
完成一个实际的项目可以帮助你巩固Java基础知识,包括数组操作、循环、条件语句、类和对象等。你还可以学习到如何处理图像文件、键盘事件监听等更高级的主题。
3、增强解决问题的能力:
在开发过程中,你会遇到各种问题,例如如何正确地处理键盘输入、如何更新界面等。解决这些问题可以锻炼你的逻辑思维能力和调试技巧。
4、了解面向对象编程:
项目采用了面向对象的设计方式,这有助于加深对Java面向对象特性的理解,如封装、继承和多态等。

二、 实现思路

需要的素材:通过百度网盘分享的文件:素材.rar
链接:https://pan.baidu.com/s/1xWpsMy67xhfx9spylxN68g?pwd=yrpn 
提取码:yrpn

我们在写游戏的时候,也是一部分一部分完成的。

先写游戏主界面,实现步骤如下:

1,完成最外层窗体的搭建。

2,再把菜单添加到窗体当中。

3,把小图片添加到窗体当中。

4,打乱数字图片的顺序。

5,让数字图片可以移动起来。

6,通关之后的胜利判断。

7,添加其他额外的功能。

2.1完成最外层窗体的搭建

import Gameoperation.GameJFrame;
import Gameoperation.LoginJFrame;
import Gameoperation.RegisterJFrame;

public class APP {
    public static void main(String[] args) {

        //程序的主入口,需要运行直接运行就可以
        new GameJFrame();
//        new LoginJFrame();
//        new RegisterJFrame();

    }
}

这个游戏涉及到java中图形化界面操作的内容,所以需要使用GUI。s

首先,有建好包,然后再包里面写三个不同的javablean类,用来操作不同的界面,在包的外面写一个APP类,用来启动游戏。

2.2完成GameJFrame中的操作 

package Gameoperation;

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 [][]win={
            {1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}
            };

    JMenuItem replayItem = new JMenuItem("重新游戏");
    JMenuItem LoginItem = new JMenuItem("重新登录");
    JMenuItem CloseItem = new JMenuItem("关闭游戏");

    JMenuItem AccountItem = new JMenuItem("公众号");

    String path = "E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\animal\\animal3\\";
    // x y 用来记录空白图片的位置
    int x = 0;
    int y = 0;

    // 4 个为一组 添加数据
    int[][] data = new int[4][4];

    // 设置 步数记录
    int step = 0;

    //这里写游戏界面的主框架,所有游戏内容都放到这里面
    public GameJFrame() {

        //   初始化界面
        initJFrame();

        // 初始化菜单
        initMenuBar();

        //(打乱图片) 初始化数据
        initData();

        initImageView();

        // 显示游戏界面,建议放到最后
        this.setVisible(true);

    }

    // 初始化数据
    // 现在 需要按照二维数据 来添加图片
    private void initData() {
        // 把一个一维数组中的数据 打乱 然后放到二维数组中 4 个一组
        int[] tempArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
        Random r = new Random();
        for (int i = 0; i < tempArr.length; i++) {
            // 获取的是随机索引
            int index = r.nextInt(tempArr.length);
            /// 拿到的数据与 随机索引的值 交换
            int temp = tempArr[i];
            tempArr[i] = tempArr[index];
            tempArr[index] = temp;
        }

        // 遍历二维数组 ,给二维数组 赋值
      for(int i=0;i<tempArr.length;i++){
          if ( tempArr[i]==0 ){
              x=i/4;
              y=i%4;
          }
          data[i/4][i%4]=tempArr[i];
      }
}



    private void initMenuBar() {
        // 初始化菜单 --创建这个对象的菜单
        JMenuBar jMenuBar = new JMenuBar();

        // 创建 菜单上面的2个选项
        JMenu functionMenu = new JMenu("功能");
        JMenu abortMenu = new JMenu("关于我们");

        // 创建 选项下面的对象


        // 给每一个条目邦定事件
        replayItem.addActionListener(this);
        LoginItem.addActionListener(this);
        CloseItem.addActionListener(this);
        AccountItem.addActionListener(this);


        //功能     把每一个对象都放到 上面的选项中
        functionMenu.add(replayItem);
        functionMenu.add(LoginItem);
        functionMenu.add(CloseItem);


        // 公众号
        abortMenu.add(AccountItem);

        // 把两个选项添加到 菜单中
        jMenuBar.add(functionMenu);
        jMenuBar.add(abortMenu);

        //  给整个界面设置菜单
        this.setJMenuBar(jMenuBar);


    }

    public void initImageView() {
        //  删除所有的图片
        this.getContentPane().removeAll();
        if(victory()){
            // 如果胜利 需要返回一个胜利的图标
            JLabel win=new JLabel(new ImageIcon("E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\win.png"));
            win.setBounds(203,283,197,73);
            this.getContentPane().add(win);
        }

        //计数
        JLabel stepCount=new JLabel("步数:"+step);
        stepCount.setBounds(50,30,100,20);
        this.getContentPane().add(stepCount);





        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int num = data[i][j];
                JLabel jLabel = new JLabel(new ImageIcon(path + num + ".jpg"));
                //  指定图片位置
                jLabel.setBounds(105 * j + 83, 105 * i + 134, 105, 105);
                // 给图片添加边框
                jLabel.setBorder(new BevelBorder(1));
                // 把容器放到 界面中
                this.getContentPane().add(jLabel);
            }
        }
        JLabel backgroundLabel = new JLabel(new ImageIcon("E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\background.png"));
        backgroundLabel.setBounds(40, 40, 508, 560);
        this.getContentPane().add(backgroundLabel);
        // 刷新所有的图片
        this.getContentPane().repaint();

    }


    private void initJFrame() {
        //设置游戏界面的宽高
        this.setSize(683, 680);
        // 设置游戏名称
        this.setTitle("拼图小游戏.单机版1.0");
        //设置游戏置顶
        this.setAlwaysOnTop(true);
        // 设置游戏界面居中
        this.setLocationRelativeTo(null);
        // 关闭游戏
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 取消默认的居中放置,才能按照x ,y 轴的新式添加图片
        this.setLayout(null);
        this.addKeyListener(this);


    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
// 按住不松,调用这个方法

    @Override
    public void keyPressed(KeyEvent e) {

        int code = e.getKeyCode();
        if ( code == 65 ) {
            // 删去所有的图片
            this.getContentPane().removeAll();

            // 加载上all图片

            JLabel all = new JLabel(new ImageIcon(path + "all.jpg"));
            all.setBounds(83, 134, 420, 420);
            this.getContentPane().add(all);
            // 添加背景图片
            JLabel backgroundLabel = new JLabel(new ImageIcon("E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\background.png"));
            backgroundLabel.setBounds(40, 40, 508, 560);
            this.getContentPane().add(backgroundLabel);
            // 刷新图片
            this.getContentPane().repaint();

        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        ///   判断游戏是否已经胜利 如果胜利就不能再执行下面的代码了

        if (victory()){
            // 结束方法
            return;
        }
        int code = e.getKeyCode();
        // 左: 37  上:38 右:39 下:40
        if ( code == 37 ) {
            System.out.println("向左移动");
            if ( y == 3 ) {
                return;
            }
            data[x][y] = data[x][y + 1];
            data[x][y + 1] = 0;
            y++;
            //  每移动一次,step就自增
            step++;
            initImageView();
        } else if ( code == 38 ) {
            System.out.println("向上移动");
            if ( x == 3 ) {
                return;
            }
            data[x][y] = data[x + 1][y];
            data[x + 1][y] = 0;
            x++;
            //  每移动一次,step就自增
            step++;
            initImageView();
        } else if ( code == 39 ) {
            System.out.println("向右移动");
            if ( y == 0 ) {
                return;
            }
            data[x][y] = data[x][y - 1];
            data[x][y - 1] = 0;
            y--;
            //  每移动一次,step就自增
            step++;
            initImageView();
        } else if ( code == 40 ) {
            System.out.println("向下移动");
            if ( x == 0 ) {
                return;
            }
            data[x][y] = data[x - 1][y];
            data[x - 1][y] = 0;
            x--;
            //  每移动一次,step就自增
            step++;
            initImageView();
        } else if ( code == 65 ) {
            initImageView();
        } else if ( code == 87 ) {
            data = new int[][]{
                    {1, 2, 3, 4},
                    {5, 6, 7, 8},
                    {9, 10, 11, 12},
                    {13, 14, 15, 16}
            };
            initImageView();

        }

    }
    // 判断输赢 输 false ---- 赢 true
    public boolean victory() {
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
               if( data[i][j] != win[i][j]){return  false;}
               }
            }
        return true;
            
        }

    @Override
    public void actionPerformed(ActionEvent e) {
        /// 获取当前被点击的 项目
        Object  obj=e.getSource();
        if(obj==replayItem){
            System.out.println("重新游戏");

            // 计步器 清零
            step=0;
            // 再次打乱二维数组的数据
            initData();
            // 图片再次重新加载
            initImageView();


        }
        else if(obj==LoginItem){
            System.out.println("重新登录");
            // 返回登录界面
            // 清除 游戏界面
            this.setVisible(false);

            // 打开登录界面
            new LoginJFrame();

        } else if(obj==CloseItem){
            System.out.println("关闭游戏");
            // 关闭虚拟机
            System.exit(0);

        }else if(obj==AccountItem){
            System.out.println("公众号");
            // 创建一个弹框对象
             JDialog jDialog = new JDialog();
             // 创建一个图片管理对象
            JLabel jLabel1 = new JLabel(new ImageIcon("E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\about.png"));
            jLabel1.setBounds(0,0,258,258);
            // 把图片添加到弹框中
            this.getContentPane().add(jLabel1);
            // 给弹窗设置大小
            jDialog.setSize(344,344);
            //给弹框置顶
            jDialog.setAlwaysOnTop(true);
            //给弹框据中
            jDialog.setLocationRelativeTo(null);
            // 弹框不关闭 就不执行下面的操作
            jDialog.setModal(true);
            // 让弹框显示出来
            jDialog.setVisible(true);



        }

    }
}



代码较长,这个是游戏界面的全部代码,至于注册和登录界面后续会跟新。

2.3检测游戏中的核心代码是否实现?

接下来我们开始运行程序

1.快捷键:a 直接可以看到结果

2.作弊键:w 直接结束游戏

2.4注意事项: 

由于时间较短,我没有完成登录和注册部分,但是游戏的核心的代码是完成的,需要注意的是,图片的地址是绝度路径,这个大家需要把图片下载到自己的电脑中,然后更改路径。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2039745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis20-通信协议

目录 RESP协议 概述 数据类型 模拟Redis客户端 RESP协议 概述 Redis是一个CS架构的软件&#xff0c;通信一般分两步&#xff08;不包括pipeline和PubSub&#xff09;&#xff1a; 客户端&#xff08;client&#xff09;向服务端&#xff08;server&#xff09;发送一条命…

6RA8075-6DV62-0AA0模块可面价

6RA8075-6DV62-0AA0模块可面价 6RA8075-6DV62-0AA0模块可面价 6RA8075-6DV62-0AA0模块可面价 6ES7655-5DX40-2AA0模块接线图 6ES7655-5DX40-2AA0模块说明书 6ES7655-5DX40-2AA0模块选型手册 6ES7655-5DX40-2AA0功能模块是指数据说明、可执行语句等程序元素的集合&#xf…

permutation sequence(

60. Permutation Sequence class Solution:def getPermutation(self, n: int, k: int) -> str:def rec(k, l, ans, n):if(n0): return# 保留第一个位置&#xff0c;剩下数字的组合leftCom math.factorial(n - 1) #用于计算 (n-1) 的阶乘值ele k // leftCommod k % leftCo…

SpringBoot入门笔记

本文是看黑马老师讲课视频学习笔记整理 目录 入门案例 基于IDEA联网 基于Springboot官网创建 基于阿里云创建项目 手工创建 隐藏文件 入门案例解析: parent​编辑 starter 引导类 内嵌tomcat 入门案例 基于IDEA联网 RestController RequestMapping("/books&…

Electron:摄像头录制和屏幕录制

摄像头录制 main.js const { app, BrowserWindow} require(electron)let mainWin null const createWindow () > {mainWin new BrowserWindow({width: 800,height: 600,title: 自定义菜单,webPreferences: {// 允许渲染进程使用nodejsnodeIntegration: true,// 允许渲…

首站,北京!OpenCSG邀您共赴AI之约【2024戴尔科技峰会预告】

图片来源&#xff1a;戴尔 在数字化浪潮的推动下&#xff0c;人工智能正成为推动社会进步的关键力量及带来生产力的提升。据相关数据显示,全球企业对人工智能的投资已增长50%&#xff0c;预计到2025年&#xff0c;人工智能将为全球经济贡献15.7万亿美元。人工智能将革新我们的生…

PyTorch深度学习实战(12)—— 神经网络工具箱nn.functional

1. nn.functional torch.nn中还有一个很常用的模块&#xff1a;nn.functional。torch.nn中的大多数layer&#xff0c;在functional中都有一个与之相对应的函数。nn.functional中的函数和nn.Module的主要区别在于&#xff1a;使用nn.Module实现的layer是一个特殊的类&#xff0c…

【人工智能】Transformers之Pipeline(九):物体检测(object-detection)

目录​​​​​​​ 一、引言 二、物体检测&#xff08;object-detection&#xff09; 2.1 概述 2.2 技术原理 2.3 应用场景 2.4 pipeline参数 2.4.1 pipeline对象实例化参数 2.4.2 pipeline对象使用参数 2.4 pipeline实战 2.5 模型排名 三、总结 一、引言 pipel…

黑马头条vue2.0项目实战(八)——文章评论

目录 1. 展示文章评论列表 1.1 准备组件 1.2 获取文章评论数据并展示 1.3 展示文章评论总数量 1.4 文章评论项 2. 评论点赞 3. 发布文章评论 3.1 准备弹出层 3.2 封装发布文章评论组件 3.3 请求发布 4. 评论回复 4.1 准备回复弹层 4.2 封装内容组件 4.3 处理头部…

【深度学习】创建和训练Transformer神经网络模型,将葡萄牙语翻译成英语

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1. 安装2. 数据处理2.1 下载数据集2.2 设置标记器2.3 使用tf.data设置数据管道 3. 测试数据集4. 定义组件4.1 嵌入和位置编码层4.2 添加并规范化4.3 基础注意力…

Android 12系统源码_多屏幕(二)模拟辅助设备功能开关实现原理

前言 上一篇我们通过为Android系统开启模拟辅助设备功能开关&#xff0c;最终实现了将一个Activity显示到多个屏幕的效果。 本篇文章我们具体来分析一下当我们开启模拟辅助设备功能开关的时候&#xff0c;Android系统做了什么哪些操作。 一、模拟辅助设备功能开关应用位置 …

Qt5编译qmqtt库使用MQTT协议连接华为云IOT完成数据上传与交互

一、前言 随着物联网技术的发展,越来越多的设备通过网络互相连接,形成了庞大的智能系统。这些系统能够收集、分析并响应各种数据,从而实现自动化控制和智能化管理。在这个背景下,MQTT 成为了一个广泛使用的轻量级消息传输协议,特别适用于资源受限的环境,如移动应用或远程…

WebSocket 实现:注解与原生方式对比

WebSocket 作为一种在单个长连接上进行全双工、双向通信的协议&#xff0c;已经成为现代Web应用中实现实时通信的重要技术。本文将探讨如何使用注解和原生方式来实现 WebSocket&#xff0c;并对这两种方法进行比较。 一、注解方式实现 WebSocket 在许多现代Java框架中&#x…

GBJ406-ASEMI无人机专用GBJ406

编辑&#xff1a;ll GBJ406-ASEMI无人机专用GBJ406 型号&#xff1a;GBJ406 品牌&#xff1a;ASEMI 封装&#xff1a;GBJ-4 批号&#xff1a;2024 现货&#xff1a;50000 最大重复峰值反向电压&#xff1a;600V 最大正向平均整流电流(Vdss)&#xff1a;4A 功率(Pd)&am…

43.【C语言】指针(重难点)(F)

目录 15.二级指针 *定义 *演示 16.三级以及多级指针 *三级指针的定义 *多级指针的定义 17.指针数组 *定义 *代码 18.指针数组模拟二维数组 往期推荐 15.二级指针 *定义 之前讲的指针全是一级指针 int a 1; int *pa &a;//一级指针 如果写成 int a 1; int *pa &a…

MES生产执行系统源码,支持 SaaS 多租户,技术架构:springboot + vue-element-plus-admin

MES的定义与功能 MES是制造业中一种重要的管理信息系统&#xff0c;用于协调和监控整个生产过程。它通过收集、分析和处理各种生产数据&#xff0c;实现对生产流程的实时跟踪和监控&#xff0c;并为决策者提供准确的数据支持。MES涵盖了工厂运营、计划排程、质量管理、设备维护…

AI时代下的智慧体育, 用科技赋能体育创新

在科技飞速发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动各行各业创新的重要力量。体育&#xff0c;作为人类文明的重要组成部分&#xff0c;同样在AI的浪潮中迎来了新的变革机遇。AI时代下的智慧体育&#xff0c;不再局限于传统的运动模式&#xff0c;…

Spring Boot集成Devtools实现热更新?

1.什么Devtools&#xff1f; DevTools是开发者工具集&#xff0c;主要用于简化开发过程中的热部署问题。 热部署是指在开发过程中&#xff0c;当代码发生变化时&#xff0c;无需手动重启应用&#xff0c;系统能够自动检测并重新加载修改后的代码&#xff0c;大大提高了开发效率…

量化投资策略与技术学习PART2:量化选股之风格轮动

市场上的投资者是有偏好的&#xff0c;有时候偏好于价值股&#xff0c;有时候偏好于成长股&#xff0c;有时偏于大盘&#xff0c;有时又偏于小盘&#xff0c;由于投资者的这种不同的交易行为&#xff0c;形成了市场风格&#xff0c;本节主要研究如何判断市场风格&#xff0c;以…

MyBatis介绍(1)

前言 MyBatis 是一个半 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了 JDBC&#xff0c;开发时只需要关注 SQL 语句本身&#xff0c;不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。程序员直接编写原生态 sql&#xff0c;可以…