拼图小游戏Java简易版

news/2024/10/18 16:41:27/

Java拼图小游戏简易版

  • 技术需求
  • 代码实现
  • 完整代码
  • 相关图片

技术需求

Java基础封装、继承、多态。

代码实现

创建一个子类继承自父类JFrame,好处是继承到父类的所有方法,直接使用,更为方便。

public class MyFrame{}

创建方法用于设置窗口参数

public void window(){// 设置窗口大小setSize(514,594);// 设置窗口标题setTitle("单机游戏v1.0");// 设置窗口居中显示setLocationRelativeTo(null);// 设置窗口置顶setAlwaysOnTop(true);// 设置程序关闭模式为窗口关闭setDefaultCloseOperation(MyFrameDemo.EXIT_ON_CLOSE);// 取消默认布局setLayout(null);}

图片本身不能移动,将图片映射为二维数组下标,数组下标的改变实际上就模拟了图片的移动。
程序每次运行都需要打乱图片的摆放顺序,这里采取的办法是:将图片编号,然后把图片的序号存到一维数组中,打乱一维数组中的数据,然后把一维数组的数据再赋值给二维数组。

// 创建成员变量二维数组,用来存放随机生成的图片
int[][] arr = new int[4][4];
// 创建顺序正确的二维数组,用于校验游戏是否成功
int[][] win = {{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};// 创建成员变量行、列(用于记录空白图片的位置)、步数(用来统计步数)
int row;
int column;
int count = 0;

创建方法将二维数组随机化,以模拟图片打乱

public void initData(){Random random = new Random();// 用来保存图片的正确顺序int[] a = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};// 打乱顺序for (int i = 0; i < a.length; i++) {int index = random.nextInt(a.length);int temp = a[i];a[i] = a[index];a[index] = temp;}// 一位数组下标计数器int index = 0;// 将打乱好的数据存入二位数组中for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {arr[i][j] = a[index];// 定位空白图片位置if (arr[i][j] == 0){row = i;column = j;}// 更新一维数组小标index++;}}}

接下来完成图片的加载,上面我们已经将图片的名字编号,然后将打乱顺序的编号存入了二维数组中,接下来利用这些编号,将图片加载进容器内并显示出来。

// 加载图片public void view(){// 清除容器内的所有组件,后面图片移动时我们要刷新页面,// 如果页面中存在有组件的话,后加载的组件会被先加载的组件覆盖// JFrame中的重合问题采用的是先来先显示getContentPane().removeAll();// 创建标签用来显示移动的步数JLabel countLabel = new JLabel("一共走了" + count + "步");// 设置标签大小countLabel.setBounds(50,20,100,20);// 将标签加载到容器中(因为取消了默认布局,必须手动加载)getContentPane().add(countLabel);// 加载图片for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {// 创建图片对象用于存放图片,注意图片的路径的\要写\\,避免转义// 注意:图片的名字已映射为二位数组中的数据,所以图片的名字要//      用二维数组替换//      如:E:\\image\\" + arr[i][j] + ".pngImageIcon imageIcon = new ImageIcon("图片的全路径");// 创建标签,将图片对象添加进去JLabel imageLabel = new JLabel(imageIcon);// 设置标签大小// 将每个图片的显示位置动态设置,体现出我们设置二维数组的便捷性imageLabel.setBounds(50 + j*100, 90 + i*100, 100, 100);// 将标签添加进容器getContentPane().add(imageLabel);}}// 添加背景图片(为啥要将背景图片放到下面?知道的可以在评论区留言哦)ImageIcon imageIcon = new ImageIcon("背景图片全路径");JLabel backgroundLabel = new JLabel(imageIcon);getContentPane().add(backgroundLabel);// 获取当前容器对象,重新编辑组件(这行代码的作用?)getContentPane().repaint();}

到这完成了游戏界面的加载工作,我们希望创建对象时能自动加载界面,所以需要再空参构造器中进行初始化工作。

// 构造方法完成初始化public MyFrame(){// 初始化窗口showView();// 数据初始化initData();// 初始化图片printView();// 注册键盘监听器(这里用的this就体现出继承的好处了)this.addKeyListener(this);// 设置窗口可见setVisible(true);}

本质上图片是不能发生移动的,我们将图片映射到了二位数组中,就可以通过改变二维数组的下边来模拟移动操作,比如往左移,那么只需要将两个数组的数据互换就行。而每次移动都要去判断是否游戏胜利。

// 完成状态public boolean check(){for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {// 对比当前二位数组和预设二位数组中的数据是否相同if (arr[i][j] != win[i][j]){return false;}}}return true;}

通过键盘移动图片,需要对键盘设置监听器,需要实现键盘监听器接口

 // 键盘监听@Overridepublic void keyReleased(KeyEvent e) {move(e.getKeyCode());// 刷新页面printView();}
// 键盘监听public void move(int key){// 胜利if (check()){return;}// 左if (key == 37){if (column != 3){arr[row][column] = arr[row][column + 1];arr[row][column + 1] = 0;column++;count++;}// 上} else if (key == 38) {if (row != 3){arr[row][column] = arr[row + 1][column];arr[row + 1][column] = 0;row++;count++;}// 右} else if (key == 39) {if (column != 0){arr[row][column] = arr[row][column - 1];arr[row][column - 1] = 0;column--;count++;}// 下} else if (key == 40) {if (row != 0) {arr[row][column] = arr[row - 1][column];arr[row - 1][column] = 0;row--;count++;}} else if (key == 90){arr = new int[][]{{0, 1, 2, 3},{4, 5, 6, 7},{8, 9, 10, 11},{12, 13, 14, 15}};}}// 下面方法用不到就不管@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyPressed(KeyEvent e) {}

完整代码

MyFrame类

import javax.swing.*;
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 MyFrame extends JFrame implements KeyListener, ActionListener {// 二维数组控制图片编号int[][] arr = new int[4][4];int[][] win = {{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};// 行int row;// 列int column;// 步数int count = 0;// 构造方法完成初始化public MyFrame(){// 初始化窗口showView();// 数据初始化initData();// 初始化图片printView();// 初始化菜单Menu();// 注册键盘监听器this.addKeyListener(this);// 设置窗口可见setVisible(true);}// 菜单public void Menu(){// 创建菜单对象JMenuBar jMenuBar = new JMenuBar();// 创建栏目对象JMenu jMenu1 = new JMenu("功能");JMenu jMenu2 = new JMenu("关于");// 创建条目对象JMenuItem jMenuItem = new JMenuItem("Replay");// 条目添加进栏目jMenu1.add(jMenuItem);// 栏目添加进菜单jMenuBar.add(jMenu1);jMenuBar.add(jMenu2);// 菜单添加进窗口this.setJMenuBar(jMenuBar);// 给条目添加监听jMenuItem.addActionListener(this);}// 二位数组随机化public void initData() {Random random = new Random();int[] arr1 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};for (int i = 0; i < arr.length; i++) {int index = random.nextInt(arr1.length);int temp = arr1[i];arr1[i] = arr1[index];arr1[index] = temp;}int index = 0;for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {arr[i][j] = arr1[index];if (arr[i][j] == 0){row = i;column = j;}index++;}}}// 窗口设置public void showView(){// 设置窗口大小setSize(514,594);// 设置关闭模式setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置置顶显示setAlwaysOnTop(true);// 设置居中显示setLocationRelativeTo(null);// 设置窗口标题setTitle("石头迷阵v1.0单机版");// 取消默认布局setLayout(null);}// 界面加载public void printView(){// 清除界面getContentPane().removeAll();// 胜利,输出图片if (check()){JLabel winLabel = new JLabel(new ImageIcon("E:\\黑马程序员\\image\\image\\win.png"));winLabel.setBounds(124,230,266,88);getContentPane().add(winLabel);}// 步数加载JLabel jLabel = new JLabel("步数:" + count);jLabel.setBounds(50,20,100,20);getContentPane().add(jLabel);// 添加图片for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {//这个地址要根据你自己的地址来写JLabel image = new JLabel(new ImageIcon("E:\\image\\"+arr[i][j]+".png"));image.setBounds(50 + j*100, 90 + i*100, 100 ,100);getContentPane().add(image);}}// 背景图片JLabel backgroung = new JLabel(new ImageIcon("E:\\image\\background.png"));backgroung.setBounds(26,30,450,484);getContentPane().add(backgroung);// 获取当前容器对象,重新编辑组件getContentPane().repaint();}// 键盘监听@Overridepublic void keyReleased(KeyEvent e) {move(e.getKeyCode());// 刷新页面printView();}// 完成状态public boolean check(){for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {if (arr[i][j] != win[i][j]){return false;}}}return true;}// 键盘监听public void move(int key){// 胜利if (check()){return;}// 左if (key == 37){if (column != 3){arr[row][column] = arr[row][column + 1];arr[row][column + 1] = 0;column++;count++;}// 上} else if (key == 38) {if (row != 3){arr[row][column] = arr[row + 1][column];arr[row + 1][column] = 0;row++;count++;}// 右} else if (key == 39) {if (column != 0){arr[row][column] = arr[row][column - 1];arr[row][column - 1] = 0;column--;count++;}// 下} else if (key == 40) {if (row != 0) {arr[row][column] = arr[row - 1][column];arr[row - 1][column] = 0;row--;count++;}} else if (key == 90){arr = new int[][]{{0, 1, 2, 3},{4, 5, 6, 7},{8, 9, 10, 11},{12, 13, 14, 15}};}}//@Overridepublic void keyTyped(KeyEvent e) {}//@Overridepublic void keyPressed(KeyEvent e) {}@Overridepublic void actionPerformed(ActionEvent e) {// 初始化数据initData();// 步数初始化count = 0;// 初始化图片图片printView();}
}

测试类

public class Test {public static void main(String[] args) {new MyFrame();}
}

相关图片

可以做任何自己想做的拼图游戏,根据大小自己切割。
上述代码用到的图片:
百度网盘
链接:https://pan.baidu.com/s/1FCoXXOm6spF9qsdfjTWYug
提取码:785g
(上述代码为简易版,供学习参考,如有不足欢迎及时指正)


http://www.ppmy.cn/news/149399.html

相关文章

主板bios修改、刷新

2010-10-19&#xff1a;由于下面几个文件被大量下载&#xff0c;导致我的cnblogs下载功能被停用。决定把这几个文件删除了&#xff0c;有需要的到bios.net.cn下载即可。 bios修改&#xff1a; AMI自助修改工具AMITool 1.47 (2010.01.20) AMI自助修改工具AMITool 1.47 (2010.01…

盈通785G显卡超频/开核教程

HT总线调节——消除超频 瓶颈 HT总线频率 AMD处理器 采用HT总线和北桥链接&#xff0c;因此HT总线频率也成为超频的影响因素。在CPU外频过高的情况下&#xff0c;HT总线频率会太高导致超频失败。 虽然盈通 主板 在超频时可以自动调整HT总线频率&#xff0c;但是为了保证更…

高通骁龙 8155 到底有什么魔力?

高通骁龙8155采用安卓系统&#xff0c;兼容性更好&#xff0c;APP的数量也就相当多&#xff0c;硬件方面&#xff0c;这颗芯片最高支持3个4K屏或4个2K屏&#xff0c;4个麦克风6颗摄像头&#xff0c;还有WiFi6、5G、蓝牙5.0等功能&#xff0c;所以现在很多车有3块大屏互联&#…

微星AMD 785G主板的BIOS设置详解

一、BIOS主菜单 1、Standard CMOS Features 标准CMOS属性 2、Advanced BIOS Features 高级BIOS 属性 3、Integrated Peripherals 整合周边设备 4、Power Management 电源管理 5、H/W Monitor 硬件监测 6、Green Power 绿色节能 7、BIO…

AMD主板770,785,790的区别普及知识

AMD主板770&#xff0c;785&#xff0c;790的区别普及知识 以上3个型号的主板都可以很好的支持AM2和AM3的CPU&#xff0c;当然具体能不能插要看主板的型号。比较好的鉴别方式就是看主板是否支持DDR3还是2就好了。另外AMD是向下兼容&#xff0c;也就是AM3的CPU可以插AM2的主板&a…

redhat9 shell脚本判断磁盘、判断web运行、curl测试web(及一些报错纠正)

1、判断当前磁盘剩余空间是否有20G&#xff0c;如果小于20G&#xff0c;则将报警邮件发送给管理员&#xff0c;每天检查一次磁盘剩余空间。 2、判断web服务是否运行&#xff08;1、查看进程的方式判断该程序是否运行 2、通过查看端口的方式判断该程序是否运行&#xff09;&…

C# 静态构造函数

静态构造函数用于初始化任何静态数据&#xff0c;或执行仅需要执行一次的特定操作。在创建第一个实例或引用任何静态成员之前&#xff0c;将自动调用它。 静态构造函数是在构造函数方法前面添加了static关键字之后形成的&#xff0c;并且没有修饰符(public,private),没有参数。…

Android异常篇 Manifest merger failed : Attribute application@label value=() from AndroidM

一、问题复现 导入某个第三方依赖后&#xff0c;出现label冲突 一般是项目中使用的第三方依赖库中的AndroidManifest.xml中跟当前App的AndroidManifest.xml中有重复的某些属性时AS会提示这个&#xff0c;按照提示添加就可以解决 二、解决方案 以上蓝色框就是error错误给出的…