【进阶篇-Day4:使用JAVA编写石头迷阵游戏】

在这里插入图片描述

目录

  • 1、绘制界面
  • 2、打乱石头方块
  • 3、移动业务
  • 4、游戏判定胜利
  • 5、统计步数
  • 6、重新游戏
  • 7、完整代码:

1、绘制界面

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

上述思路是:使用一个二维数组存放图片的编号,然后在后持遍历即可获取对应的图片。

在这里插入图片描述

在这里插入图片描述

代码如下:

package com.itheima.stonepuzzle;
import javax.swing.*;public class MainFrame extends JFrame {//data使用一个二维数组存放图片的编号,然后在后持遍历即可获取对应的图片。int[][] data = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};/*** 因为初始化窗体 和 绘制游戏界面,是在进入游戏就要执行的,* 因此只需要在new对象时执行即可,而new对象时构造方法一定会执行,* 所以在构造方法里调用即可*/public MainFrame(){//初始化窗体initFrame();//绘制游戏界面paintView();//设置窗体可见setVisible(true);}/*** 此方法用于窗体初始化*/public void initFrame(){
//        JFrame jf = new JFrame(); --因为此类继承了JFrame,因此下面的方法可以直接调用//设置窗体大小setSize(514, 595);//设置窗体关闭模式:关闭窗口时,结束程序setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);//设置窗体标题setTitle("石头迷阵单机版V1.0");//设置窗体永在最上层setAlwaysOnTop(true);//设置窗体居中setLocationRelativeTo(null);//设置取消默认布局setLayout(null);}/*** 此方法用于绘制游戏的界面*/public void paintView(){for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {JLabel jl = new JLabel(new ImageIcon("C:\\Users\\MSZ\\Desktop\\java_test\\dev\\image\\" + data[i][j] + ".jpg"));//设置图片对象大小jl.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);//将图片对象塞进窗体getContentPane().add(jl);}}JLabel background = new JLabel(new ImageIcon("C:\\Users\\MSZ\\Desktop\\java_test\\dev\\image\\background.jpg"));//设置图片对象大小background.setBounds(26, 30, 450, 484);//将图片对象塞进窗体super.getContentPane().add(background);}
}

运行代码,绘制界面的结果如下:
在这里插入图片描述

2、打乱石头方块

在这里插入图片描述

代码:

/*** 初始化数据(随机打乱石头)*/
public void initData(){Random r = new Random();//1、遍历二维数组,获取每一个元素for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {//2、随机获取 (x坐, y坐标),找到其中一个数int x = r.nextInt(4);//x坐标int y = r.nextInt(4);//y坐标//3、将当前遍历到的元素,和随机获取到的元素做交换int temp = data[i][j];data[i][j] = data[x][y];data[x][y] = temp;}}
}

3、移动业务

在这里插入图片描述

    /*** 按下键盘时出发事件* @param e*/@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();move(keyCode);}/*** 此方法用于处理移动业务* @param keyCode*/private static void move(int keyCode) {if (keyCode == 37){System.out.println("左移动业务...");} else if (keyCode == 38) {System.out.println("上移动业务...");} else if (keyCode == 39) {System.out.println("右移动业务...");} else if (keyCode == 40) {System.out.println("下移动业务...");}}

在这里插入图片描述

移动石头块,实际上只需要交换二维数组中的两个数即可,然后再刷新就实现了移动业务。

做法:
在这里插入图片描述
在这里插入图片描述

//寻找0号元素的位置
lo:
for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if (data[i][j] == 0) {row = i;col = j;break lo;}}
}

下面看下上、下、左、右移动:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意:
在这里插入图片描述
在这里插入图片描述

/*** 此方法用于处理移动业务** @param keyCode*/
private void move(int keyCode) {int temp = data[row][col];//0号元素if (keyCode == 37 && col < 3) {System.out.println("左移动业务...");//左移动时,空白块和右边的数做交换data[row][col] = data[row][col + 1];data[row][col + 1] = temp;//记录0号元素的列坐标也要随之改变col++;} else if (keyCode == 38 && row < 3) {System.out.println("上移动业务...");//上移动时,空白块和下边的数做交换data[row][col] = data[row + 1][col];data[row + 1][col] = temp;//记录0号元素的列坐标也要随之改变row++;} else if (keyCode == 39 && col > 0) {System.out.println("右移动业务...");//右移动时,空白块和左边的数做交换data[row][col] = data[row][col - 1];data[row][col - 1] = temp;//记录0号元素的列坐标也要随之改变col--;} else if (keyCode == 40 && row > 0) {System.out.println("下移动业务...");//下移动时,空白块和上边的数做交换data[row][col] = data[row - 1][col];data[row - 1][col] = temp;//记录0号元素的列坐标也要随之改变row--;}else if (keyCode == 90){//z键//触发作弊器data = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};}System.out.println(row + "," + col);
}

4、游戏判定胜利

在这里插入图片描述

/*** 判断游戏是否胜利* @return*/
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;}

在这里插入图片描述

5、统计步数

在这里插入图片描述

6、重新游戏

在这里插入图片描述

7、完整代码:

package com.itheima.stonepuzzle;public class Test {public static void main(String[] args) {//启动器new MainFrame();}
}
package com.itheima.stonepuzzle;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;public class MainFrame extends JFrame implements KeyListener {//data使用一个二维数组存放图片的编号,然后在后持遍历即可获取对应的图片。int[][] data = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};//胜利的结果int[][] win = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};int row; //0号元素的行坐标int col; //0号元素的列坐标int count = 0;//记录操作的次数/*** 因为初始化窗体 和 绘制游戏界面,是在进入游戏就要执行的,* 因此只需要在new对象时执行即可,而new对象时构造方法一定会执行,* 所以在构造方法里调用即可*/public MainFrame() {//键盘监听://窗体对象.addKeyListener(KeyListener实现类对象)//this:当前对象,两个身份//1)窗体对象//2)KeyListener实现类对象this.addKeyListener(this);//初始化窗体initFrame();//初始化数据(随机打乱石头)initData();//绘制游戏界面paintView();//设置窗体可见setVisible(true);}/*** 此方法用于窗体初始化*/public void initFrame() {
//        JFrame jf = new JFrame(); --因为此类继承了JFrame,因此下面的方法可以直接调用//设置窗体大小setSize(514, 595);//设置窗体关闭模式:关闭窗口时,结束程序setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);//设置窗体标题setTitle("石头迷阵单机版V1.0");//设置窗体永在最上层setAlwaysOnTop(true);//设置窗体居中setLocationRelativeTo(null);//设置取消默认布局setLayout(null);}/*** 初始化数据(随机打乱石头)*/public void initData() {Random r = new Random();//1、遍历二维数组,获取每一个元素for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {//2、随机获取 (x坐, y坐标),找到其中一个数int x = r.nextInt(4);//x坐标int y = r.nextInt(4);//y坐标//3、将当前遍历到的元素,和随机获取到的元素做交换int temp = data[i][j];data[i][j] = data[x][y];data[x][y] = temp;}}//寻找0号元素的位置lo:for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if (data[i][j] == 0) {row = i;col = j;break lo;}}}}/*** 此方法用于绘制游戏的界面*/public void paintView() {//每次绘制之前,都清空之前绘制的界面super.getContentPane().removeAll();//加载胜利图片资源,添加到窗体中if (victory()){JLabel victoryJl = new JLabel(new ImageIcon("C:\\Users\\MSZ\\Desktop\\java_test\\dev\\image\\victory.jpg"));victoryJl.setBounds(124, 230, 266, 100);getContentPane().add(victoryJl);}//加载重新开始按钮if (count > 0){JButton jb = new JButton("重新开始");jb.setBounds(350, 10, 100, 20);jb.setFocusable(false);//取消焦点jb.addActionListener(new AbstractAction() {@Overridepublic void actionPerformed(ActionEvent e) {//统计步数归0count = 0;//重新初始化数据initData();//重新绘制游戏界面paintView();}});getContentPane().add(jb);}//加载记录步数组件JLabel stepJl = new JLabel("步数:" + count);stepJl.setBounds(50, 10, 100, 20);getContentPane().add(stepJl);for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {JLabel jl = new JLabel(new ImageIcon("C:\\Users\\MSZ\\Desktop\\java_test\\dev\\image\\" + data[i][j] + ".jpg"));//设置图片对象大小jl.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);//将图片对象塞进窗体getContentPane().add(jl);}}//加载背景图JLabel background = new JLabel(new ImageIcon("C:\\Users\\MSZ\\Desktop\\java_test\\dev\\image\\background.jpg"));//设置图片对象大小background.setBounds(26, 30, 450, 484);//将图片对象塞进窗体super.getContentPane().add(background);//刷新super.getContentPane().repaint();}/*** 按下键盘时出发事件** @param e*/@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();move(keyCode);//判断是否胜利victory();//每次移动之后,都重新绘制游戏界面paintView();}/*** 此方法用于处理移动业务** @param keyCode*/private void move(int keyCode) {//如果游戏胜利了,则不允许操作if (victory()){return;}int temp = data[row][col];//0号元素if (keyCode == 37 && col < 3) {
//            System.out.println("左移动业务...");//左移动时,空白块和右边的数做交换data[row][col] = data[row][col + 1];data[row][col + 1] = temp;//记录0号元素的列坐标也要随之改变col++;count++;} else if (keyCode == 38 && row < 3) {
//            System.out.println("上移动业务...");//上移动时,空白块和下边的数做交换data[row][col] = data[row + 1][col];data[row + 1][col] = temp;//记录0号元素的列坐标也要随之改变row++;count++;} else if (keyCode == 39 && col > 0) {
//            System.out.println("右移动业务...");//右移动时,空白块和左边的数做交换data[row][col] = data[row][col - 1];data[row][col - 1] = temp;//记录0号元素的列坐标也要随之改变col--;count++;} else if (keyCode == 40 && row > 0) {
//            System.out.println("下移动业务...");//下移动时,空白块和上边的数做交换data[row][col] = data[row - 1][col];data[row - 1][col] = temp;//记录0号元素的列坐标也要随之改变row--;count++;}else if (keyCode == 90){//z键//触发作弊器data = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};count++;}
//        System.out.println(row + "," + col);}/*** 判断游戏是否胜利* @return*/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;}//-------------------------------------@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyReleased(KeyEvent e) {}//-------------------------------------
}

界面图片已放在资源里,可下载。

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

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

相关文章

【设计模式之模板方法模式 -- C++】

模板方法模式 – 抽象父类&#xff0c;子类实现 模板方法设计模式是一种行为设计模式&#xff0c;它在父类中定义了一个操作的算法的骨架&#xff0c;而将一些步骤延迟到子类中实现。这样&#xff0c;可以在不改变算法结构的前提下&#xff0c;重新定义算法的某些特定步骤。模…

vue3父组件获取子组件实例(2024-06-22)

vue3获取子组件实例 在Vue 3中&#xff0c;可以使用ref来获取子组件的实例。首先&#xff0c;在父组件中需要引入ref&#xff0c;然后在模板中通过ref属性为子组件设置一个引用名称。之后&#xff0c;可以在父组件的setup函数中使用refAPI来访问子组件实例。 以下是一个简单的…

取代煤气灶,新能源电燃灶真有那么牛吗

在当今社会&#xff0c;能源问题日益凸显&#xff0c;能源危机的警钟不断敲响。与此同时&#xff0c;人们对于生活品质和安全环保的要求也越来越高。在这样的背景下&#xff0c;一种号称能取代燃气灶和电磁炉的新能源电燃灶——华火电燃灶进入了人们的视野。 华火电燃灶的出现似…

【区分vue2和vue3下的element UI Empty 空状态组件,分别详细介绍属性,事件,方法如何使用,并举例】

在 Element UI&#xff08;为 Vue 2 设计&#xff09;和 Element Plus&#xff08;为 Vue 3 设计&#xff09;中&#xff0c;Empty&#xff08;空状态&#xff09;组件通常用于在数据为空或没有内容时向用户展示一种占位提示。然而&#xff0c;需要注意的是&#xff0c;Element…

SpringBoot整合justauth实现多种方式的第三方登陆

目录 0.准备工作 1.引入依赖 2.yml文件 3. Controller代码 4.效果 参考 0.准备工作 你需要获取三方登陆的client-id和client-secret 以github为例 申请地址&#xff1a;Sign in to GitHub GitHub 1.引入依赖 <?xml version"1.0" encoding"UTF-8&quo…

Gflags的使用

目录 1. gflags 安装 2. gflags 使用 2.1 基本使用方法 2.2 基本使用实例 2.3 放入配置文件中 3. 融入cmakelists中使用 在实际工程代码开发中&#xff0c;发现gflags很好用&#xff0c;可以在运行 1. gflags 安装 gflags的安装使用apt-get install命令安装即可 sudo …

【SCAU数据挖掘】数据挖掘期末总复习题库简答题及解析——下

1.从某超市顾客中随机抽取5名&#xff0c;他们的购物篮数据的二元0/1表示如下&#xff1a; 顾客号 面包 牛奶 尿布 啤酒 鸡蛋 可乐 1 1 1 0 0 0 0 2 1 0 1 1 1 0 3 0 1 1 1 0 1 4 1 1 1 1 0 0 5 1 1 1 0 0 1 某学生依据这些数据做…

Spring Security6 设置免登录接口地址

1. 在SecurityFilterChain中设置免登录接口地址。如果定义了多个SecurityFilterChain&#xff0c;并且前面的SecurityFilterChain里使用了anyRequest().authenticated()&#xff0c;后面的免登录可能会失效。 Configuration EnableWebSecurity public class SecurityConfig {B…

Linux常用命令(16)—awk命令(有相关截图)

写在前面&#xff1a; 最近在学习Linux命令&#xff0c;记录一下学习Linux常用命令的过程&#xff0c;方便以后复习。仅供参考&#xff0c;若有不当的地方&#xff0c;恳请指正。如果对你有帮助&#xff0c;欢迎点赞&#xff0c;关注&#xff0c;收藏&#xff0c;评论&#xf…

tessy 编译错误总结

目录 1,tessy 单元测试 TDE 界面 数据无法填充:the test object interface is incomplete 2,tessy 编译报错:单元测试时,普通桩函数内容相关异常场景 3,tessy 编译报错:模块分析后 头文件 找不到 4,tessy 集成测试:SCE界面component函数太多 5,tessy 编译报错:函…

Java 10新特性介绍

Java 10是Java平台的一个重要更新&#xff0c;它引入了多项新特性和改进。以下是一些主要的新特性&#xff1a; 局部变量类型推断&#xff08;var关键字&#xff09; Java 10允许使用var关键字来声明局部变量&#xff0c;而无需显式指定变量的类型。编译器会根据变量赋值的上下…

non_blocking=True 与 torch.cuda.synchronize()

需要注意的是&#xff1a;GPU和CPU之间是异步执行的&#xff0c;CPU向GPU下达指令以后会立刻执行之后的代码&#xff0c;CPU不会等待GPU执行完成 一、non_blockingTrue 目的&#xff1a;压缩gpu的效果&#xff0c;避免CPU与GPU设备数据传输时间开销带来的计算效率低下 在 P…

Android获取控件宽高的几种方式

第一种方式&#xff1a;在需要时获取&#xff0c;如控件点击时再获取 button.setOnClickListener(new View.OnClickListener() { Override public void onClick(View v) { getTextWidthAndHeight(); } }); 第二种方式&#xff1a;重写onWindowFocusChanged()方法 Overr…

【SQL】varchar 与 char 的区别

在 SQL 中&#xff0c;VARCHAR 和 CHAR 是用于存储字符串类型数据的两种数据类型&#xff0c;但它们在存储方式和性能上有显著的区别。 CHAR 定义: CHAR 是一种固定长度的字符串数据类型。长度: 你需要在定义表结构时指定长度&#xff0c;例如 CHAR(10)。存储方式: 无论实际存…

【机器学习】机器学习赋能交通出行:智能化实践与创新应用探索

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f4d2;1. 引言&#x1f4d9;2. 交通流量预测与优化&#x1f31e;数据准备&#x1f319;模型训练与预测⭐评估模型与优化 &#x…

jsonpath_解析例子代码

# _*_ coding : utf-8 _*_ # Time : 2023-11-05 13:23 # Author : haowen # File : jsonpath_解析_淘票票 # Project : py练习 import urllib.request url https://dianying.taobao.com/cityAction.json?activityId&_ksTS1699161894273_112&jsoncallbackjsonp113&…

网页抓取单词关联

在当今数字化的时代&#xff0c;数据的获取与处理成为了众多企业和开发者关注的焦点。API 服务的出现&#xff0c;为我们打开了高效、便捷获取和利用数据的新大门。接下来&#xff0c;为您介绍几款独具特色的 API 服务&#xff0c;它们将为您的业务和开发工作带来前所未有的便利…

ABB机械手3HAC024518-001电机振动过大维修方案

【ABB机械臂伺服电机维修方案】 1. 更换轴承 如果检查发现轴承磨损&#xff0c;我们需要更换新的轴承。请选择与原轴承型号相同的产品&#xff0c;以确保电机正常运行。 2. 重新平衡转子 如果ABB机械手3HAC024518-001电机转子不平衡&#xff0c;我们需要重新平衡转子。这可以通…

棉花叶子病害分类数据集3601张6类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;3601 分类类别数&#xff1a;6 类别名称:[“aphids”,“army_worm”,“bact…

小熊文件工具箱免费版

小熊文件工具箱是一款基于本地离线操作的一系列工具的合集&#xff0c;最大特点是各种批量任务的执行&#xff0c;包含了智能证件照&#xff0c;自动抠图&#xff0c;直播录制&#xff0c;九宫格切图&#xff0c;拼图&#xff0c;视频格式转换及压缩&#xff0c;zip压缩解压缩&…