自学Java篇之JFrame创建《石头迷阵小游戏》

根据黑马程序员java教程自学完java基础,觉得石头迷阵小游戏案例具有一定的编程练习价值,记录之。

最终效果:

案例主要思想流程:

​ 主要是思想是创建一个4*4的二维数组data(初始化时打乱数组元素),存放石头编号,再根据编号(0,1,2…)进行imagelabel读取石头图片,组合展示到画板中。

​ 监听键盘上下左右间,根据键盘监听的数值进行if判断,将0编号的石头(即黑方块)根据上下左右对应的进行交换,即是对二维数组里的元素进行交换,交换一次就进行对二维数组展现一次(即刷新面板,重新展现一次石头,可以想成图片一帧帧切换)。

​ 根据移动到最后数组的元素等于胜利时的数组元素时,面板展示胜利图片,添加上步数统计,即监听键盘按了几次,以及重新开始按钮,即是对程序的重新运行,(打乱数组,重新展示。)

1、创建窗口完整框架:

​ 首先创建两个类,分别为MainFrame类和test类,前者用于游戏类的编写,后者用于运行游戏类代码。

MainFrame类:

package StonePuzzie;
import javax.swing.*;
import java.util.Random;
public class MainFrame extends JFrame {int[][] data = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};
//  MainFrame类创建自己构造方法:public  MainFrame(){//        1、数据初始化initData();
//        2、初始化窗体initFrame();
//        3、绘制窗体painView();
//        设置窗口可见setVisible(true);}/*** chushi初始化数据(随机打乱二维数据)*/public void initData(){/*创建rondom对象进行,随机生产x,y,用于确定data数组的下标,替换值,达到打乱数组顺序效果*/Random r = new Random();for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {int randomX = r.nextInt(4);int randomY = r.nextInt(4);int temp = data[i][j]; data[i][j] = data[randomX][randomY]; data[randomX][randomY] = temp;}}}/*** 用于初始化窗体*/public void initFrame(){setSize(514,595);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);setTitle("石头迷阵v1.0");setAlwaysOnTop(true);setLocationRelativeTo(null);setLayout(null);}/*** 用于绘制游戏界面*/public void painView(){for (int i=0;i<4;i++){for (int j=0;j<4;j++){System.out.println(data[i][j]);JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\"+data[i][j]+".png"));imageLabel.setBounds(50+100*j,90+100*i,100,100);getContentPane().add(imageLabel);}}JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));background.setBounds(26,30,450,484);getContentPane().add(background);super.getContentPane().repaint();}
}

test类:

package StonePuzzie;public class test {public static void main(String[] args) {//        调用执行构造方法
//        相当于: MainFrame mainFrame =new MainFrame();new MainFrame();}
}

这样就完成第一步,初始化窗口展示:

2、添加移动石头业务模块:

使用键盘上下左右键进行对石头的移动,就需要使用接口KeyListener,对键盘进行监听,所有MainFrame类需要实现接口,即implements KeyListener。再重写接口中的keyPressed,监听键盘按下的事件。方法中添加move方法的代码,用于移动石块。

前提是需要在数据初始化时,找到黑方块。”0“编号的数组下标。再进行对0编号进行move操作:

寻找0编号数组下标:

      int row;        // 0号元素行坐标位置int column;     // 0号元素列坐标位置//        用于确定0格子的位置for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if (data[i][j] == 0) {row = i;column = j;}}

编写move方法代码:

  private void move(int keyCode) {//左移动:if (keyCode == 37) {if (column == 3) {return;}// 空白块和右侧数据交换// data[row][column]  data[row][column+1]int temp = data[row][column];data[row][column] = data[row][column + 1];data[row][column + 1] = temp;column++;//            上移动:} else if (keyCode == 38) {if (row == 3) {return;}// 空白块和下面的数据交换// data[row][column] data[row+1][column]int temp = data[row][column];data[row][column] = data[row + 1][column];data[row + 1][column] = temp;row++;//            右移动} else if (keyCode == 39) {if (column == 0) {return;}// 空白块和左侧的数据交换// data[row][column] data[row][column-1]int temp = data[row][column];data[row][column] = data[row][column - 1];data[row][column - 1] = temp;column--;//            下移动:} else if (keyCode == 40) {if (row == 0) {return;}// 空白块和上面的数据交换// data[row][column] data[row-1][column]int temp = data[row][column];data[row][column] = data[row - 1][column];data[row - 1][column] = temp;row--;}

重写监听键盘接口实现方法:

    @Overridepublic void keyPressed(KeyEvent e) {//        获得键盘按下的键的键值。int keyCode = e.getKeyCode();System.out.println("键值为:");System.out.println(keyCode);
//        传入move方法:move(keyCode);
//        执行一次移动后需要进行重新绘制游戏界面:painView();}

3、添加判断胜利模块:

该模块的添加,应该在展示用于绘制界面的方法painView()中,每次移动后需要重新绘制界面时,需要进行一个判断,,看现在的数组是否等于胜利的数组win:,输出胜利的图片:

判断是否胜利返回布尔值true or false:

int[][] win = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};
/*** 判断游戏是否胜利*/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;}

中插入判断代码:

if(victory()){// 加载胜利图片资源, 添加到窗体中JLabel winLabel = new JLabel(new ImageIcon("D:\\image\\win.png"));winLabel.setBounds(124,230,266, 88);getContentPane().add(winLabel);}

4、添加记录步数和“重新游戏”模块:

该模块的记录步数,需要一开始定一个全局变量count,并且点击重新游戏的时候,count赋值为0,在move代码中,每进行一次移动,count++,最后在窗体展示的代码painView()中,创建一个窗体展示记录步数展示,再创建一个按钮,点击按钮后事件进行对游戏重新开始,重新初始化数组,count归为0。

记录步数:

int count;
JLabel scoreLabel = new JLabel("步数为:" + count);scoreLabel.setBounds(50,20,100,20);getContentPane().add(scoreLabel);

重新开始按钮:

     JButton btn = new JButton("重新游戏");btn.setBounds(350,20,100,20);getContentPane().add(btn);
//        取消按钮焦点。btn.setFocusable(false);btn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {count =0;initData();painView();}});

5、添加作弊器,一键“胜利“:

添加作弊器,主要是在键盘按键监听事件中,添加一个if判断,如果自己设定的按键,(比如z,键值为:90),然后在move代码中写入对数据data重新赋值为胜利时的win数组一样的数据

 else if (keyCode == 90) {// 触发作弊器data = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};}

6、整体代码:

MainFrame类:

package com.itheima.stonepuzzle;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 MainFrame extends JFrame implements KeyListener {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 column;     // 0号元素列坐标位置int count;      // 统计步数
//构造方法::public MainFrame() {// 窗体对象.addKeyListener(KeyListener实现类对象);this.addKeyListener(this);// this : 当前类对象// 1) 窗体对象// 2) KeyListener实现类对象// 初始化窗体initFrame();// 初始化数据initData();// 绘制游戏界面paintView();// 设置窗体可见setVisible(true);}/*** 初始化数据 (打乱二维数组)*/public void initData() {// 准备Random对象Random r = new Random();// 遍历二维数组, 获取到每一个元素for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {int randomX = r.nextInt(4);int randomY = r.nextInt(4);// data[i][j]// data[randomX][randomY]int temp = data[i][j];data[i][j] = data[randomX][randomY];data[randomX][randomY] = temp;}}
//        用于确定0格子的位置for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if (data[i][j] == 0) {row = i;column = j;}}}}/*** 此方法用于初始化窗体*/public void initFrame() {// 设置窗体大小setSize(514, 595);// 设置窗体关闭模式setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);// 设置窗体标题setTitle("石头迷阵单机版V1.0");// 设置窗体置顶setAlwaysOnTop(true);// 设置窗体居中setLocationRelativeTo(null);// 取消默认布局setLayout(null);}/*** 此方法用于绘制游戏界面*/public void paintView() {getContentPane().removeAll();if(victory()){// 加载胜利图片资源, 添加到窗体中JLabel winLabel = new JLabel(new ImageIcon("D:\\image\\win.png"));winLabel.setBounds(124,230,266, 88);getContentPane().add(winLabel);}JButton btn = new JButton("重新游戏");btn.setBounds(350,20,100,20);getContentPane().add(btn);btn.setFocusable(false);btn.addActionListener(e -> {count = 0;initData();paintView();});JLabel scoreLabel = new JLabel("步数为:" + count);scoreLabel.setBounds(50,20,100,20);getContentPane().add(scoreLabel);for (int i = 0; i < 4; i++) {// i = 0 1 2 3for (int j = 0; j < 4; j++) {// j = 0 1 2 3JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\" + data[i][j] + ".png"));imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);getContentPane().add(imageLabel);}}JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));background.setBounds(26, 30, 450, 484);getContentPane().add(background);getContentPane().repaint();}/*** 判断游戏是否胜利*/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;}/*** 此方法用于处理移动业务*/private void move(int keyCode) {if(victory()){return;}
//左移动:if (keyCode == 37) {if (column == 3) {return;}// 空白块和右侧数据交换// data[row][column]  data[row][column+1]int temp = data[row][column];data[row][column] = data[row][column + 1];data[row][column + 1] = temp;column++;count++;
//            上移动:} else if (keyCode == 38) {if (row == 3) {return;}// 空白块和下面的数据交换// data[row][column] data[row+1][column]int temp = data[row][column];data[row][column] = data[row + 1][column];data[row + 1][column] = temp;row++;count++;
//            右移动} else if (keyCode == 39) {if (column == 0) {return;}// 空白块和左侧的数据交换// data[row][column] data[row][column-1]int temp = data[row][column];data[row][column] = data[row][column - 1];data[row][column - 1] = temp;column--;count++;
//            下移动:} else if (keyCode == 40) {if (row == 0) {return;}// 空白块和上面的数据交换// data[row][column] data[row-1][column]int temp = data[row][column];data[row][column] = data[row - 1][column];data[row - 1][column] = temp;row--;count++;} else if (keyCode == 90) {// 触发作弊器data = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};}}@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();
//        System.out.println("键值:");
//        System.out.println(keyCode);move(keyCode);// 每一次移动之后, 都重新绘制游戏界面paintView();}// ----------------------------------------------------@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void keyTyped(KeyEvent e) {}// ----------------------------------------------------
}

test类运行。

最后:

创作分享不易,如果觉得对您有一定的帮助,请点个小小关注bo。

自学Java篇之JFrame创建《石头迷阵小游戏》相关推荐

  1. 黑马程序员_石头迷阵小游戏

    黑马程序员_石头迷阵小游戏 源代码 一些说明: 1)这些是我看b站黑马程序员的视频,自己手打的,想分享一下,如果有侵权啥的请联系我,马上删除 2)一些比较重要的我都有给注释 3)工具idea idk版 ...

  2. 基于Java的石头迷阵小游戏的设计与实现

    文章目录 1 搭建游戏主界面 1.1 用JFrame类来创建窗体 (知识点继承) 1.2 菜单制作JMenuBar 1.3 添加图片 1.4 代码 2 添加游戏功能 2.1 事件监听机制 2.2 设计 ...

  3. Java石头迷阵小游戏

    //测试类 import javax.swing.*;public class Test {public static void main(String[] args) {new MainFrame( ...

  4. 《石头迷阵》游戏业务数据设计、游戏功能制作、游戏界面绘制

    石头迷阵 JFrame类就是用来表示窗体的类 import javax.swing.*; public class App {public static void main(String[] args ...

  5. ***JAVA*和*Eclipse*开发一个换装小游戏**

    JAVA和Eclipse开发一个换装小游戏** 家有一女如有一宝,最近女朋友的少女心有点爆棚,作为一个计算机专业的人,我的情商简直是低到吓人,但是我还是想到了,亲自给女朋友做一个换装的小游戏,来满足女 ...

  6. java 300行代码 冒险闯关小游戏(代码+讲解)

     作为一个男孩子,从小就喜欢晚一些游戏.今天就用java写一个类似马里奥的冒险闯关小游戏,但这也不是一两天能完成的事情,我将会持续更新这个游戏(有什么好的介意也非常欢迎大家提出来,也能在我的基础上自己 ...

  7. qml自学笔记------自己写类似于劲舞团的按键小游戏(中)

    接上篇<qml自学笔记------自己写类似于劲舞团的按键小游戏(上)> 第三部分DisplayPart.qml 代码的其他部分都是渣,就这里花了点时间,整个小游戏就靠这个文件. 首先,屏 ...

  8. java游戏循环_利用Java循环语句实现攻击防御塔小游戏

    /* * 时间:2018-3-21 * 目的:practice * 内容:利用Java循环语句实现攻击防御塔小游戏 * 使用Java while语句实现一个英雄攻击防御塔的小程序,防御塔血量总计100 ...

  9. 用python+pygame写的宝石迷阵小游戏

    寒假的时候没什么意思,索性学了一个脚本语言,当初选定Python也是因为他很强大不仅可以像Ruby一样做网络,也可以像Perl做管理(可能这么比不太对哈~~),其实Python是门很简单的语言,大概一 ...

最新文章

  1. exit()、_Exit() 和 _exit() 函数的区别和联系
  2. jQuery就业课系列之.jQueryDOM
  3. 计算机工程师专用小工具,204个联想工程师专用小工具合集
  4. 多行溢出文字省略号显示(HTML、CSS)
  5. [译]JS闭包:For循环中的setTimeout
  6. 实战Node:幼教平台幼教资源部分实现
  7. chrome官网下载win64离线安装包
  8. 【Pygame实战】超有趣的泡泡游戏来袭——愿你童心不泯,永远快乐简单哦~
  9. (附源码)spring boot智能车APP毕业设计250623
  10. 微信小程序token使用(首页获取不到token)
  11. 李建忠「设计模式」笔记
  12. 台式机和台式计算机的区别,台式机和一体机区别是什么
  13. 《笨方法学习python3》练习12: Prompting People
  14. 【人工智能 AI 】当前世界人工智能领域发展最前沿的技术
  15. UWA学堂专栏推荐:Unity项目从Gamma转Linear颜色空间的经验分享
  16. 2020-10-03 Shell编程
  17. ASEMI整流桥KBPC3510,KBPC3510封装,KBPC3510应用
  18. win10更新不动_Win10推出今年最重磅更新!优化了游戏,而且可以“云”重装系统...
  19. 众安尊享e生·新全保通2017成人精选版60岁以后续保的保费清单
  20. 微信投票服务器在哪做,微信投票活动制作需要什么软件

热门文章

  1. 嵌入式 STM32 红外遥控
  2. 分辨率和清晰度的区别关系
  3. 基于Java的股票交易系统
  4. 英特尔的“尺子”,三星的“钉子”
  5. 从四大造字法看文字所承载的文化_古代汉语期末考试试题加答案
  6. 算法分析与设计-迭代法求解方程(组)的根(详解)
  7. 自己做了一款新浪博客自动访客工具
  8. 计算机一级文字处理公式,一级考试WPS2007:让公式中的文字变个颜色
  9. telnet 命令使用方法详解,telnet命令怎么用
  10. ​vm虚拟机的下载网址https://softwareupdate.vmware.com/cds​