前言

明哥教学案例,使用javase部分技术实现,电脑恶搞关机程序,特此记录,方便学生查阅学习。

一、项目最终效果截图

二、项目实现代码

GameFrame类

package com.mg;import javax.swing.*;/*** 类名:GameFrame* 包名:com.mg* 创建时间:2020/6/23 17:26* 创建人: 明哥* 描述:**/
public class GameFrame extends JFrame {private static final long serialVersionUID = 1L;GamePanel panel;/*** GameFrame构造方法*/public GameFrame() {// 设置窗体标题setTitle("数字连连消");// 设置窗体位置和大小setBounds(100, 100, 515, 520);// 设置窗体不能改变大小setResizable(false);// 设置窗体居中显示setLocationRelativeTo(null);// 设置窗体关闭即退出setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);panel = new GamePanel();add(panel);// 最后显示窗体setVisible(true);}/*** 启动游戏*/public void start() {panel.start();}
}

GamePanel类

package com.mg;import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.Timer;/*** 类名:GamePanel* 包名:com.mg* 创建时间:2020/6/23 15:33* 创建人: 明哥* 描述: 游戏布局 游戏的核心逻辑代码**/
public class GamePanel extends JPanel {private static final long serialVersionUID = 2L;private static final int sx = 50;// 左边距private static final int sy = 50;// 上边距private static final int w = 40; // 小方格宽高private static final int rw = 400; // 网格总宽高private int pj = 0, pi = 0; // 记录两个点击选中的按钮,第一个被点击的按钮坐标private int cc = 0;// 被点击选中的按钮个数private int[][] map;// 存放游戏数据的二维数组private boolean isEnd = false; // 游戏结束标志private JButton[][] btnMap; // 存放按钮的二维数组,与map对应private int score; // 记录分数private JButton restart; // 重新开始按钮private Timer timer; // 定时器private int timestamp; // 时间戳public GamePanel() {// 设置布局为不使用预设的布局setLayout(null);}/*** 开始游戏*/public void start() {// 创建游戏数据地图map = MapTool.createMap();btnMap = new JButton[10][10];score = 0;timestamp = 0;isEnd = false;// 创建按钮,设置按钮属性,监听事件,并添加到按钮数组和窗体中for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[i].length; j++) {JButton btn = new JButton(map[i][j] + "");btn.setBounds(sx + (j * w) + 2, sy + (i * w) + 2, w - 2, w - 2);btn.setForeground(Color.RED);btn.setFont(new Font("Arial", 0, 30));btn.setBackground(Color.WHITE);btn.setBorder(BorderFactory.createRaisedBevelBorder());btn.setFocusPainted(false);btn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// 如果游戏结束,返回,不执行后面的代码if (isEnd) {return;}for (int i = 0; i < btnMap.length; i++) {for (int j = 0; j < btnMap[i].length; j++) {if (e.getSource().equals(btnMap[i][j])) {// 被选中的方格个数增加一个cc++;compare(j, i);}}}}});btnMap[i][j] = btn;this.add(btn);}}if (restart != null) {restart.setVisible(false);this.remove(restart);restart = null;}repaint();// 定时器,用来刷新时间timer = new Timer(1000, new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {timestamp++;repaint();}});timer.start();}/*** 判断是否游戏结束* 1、判断二维数组map中的所有元素是否均为0, 全部为0返回true表示游戏结束* 2、有不为0的,判断二维数组map中是否还有重复值,没有重复值返回true表示游戏结束* 否则返回false游戏继续** @param map 二维数组,元素为int类型* @return*/public boolean isEnd(int[][] map) {int count_0 = 0;int count = 0;HashSet<Integer> hashSet = new HashSet<Integer>();for (int[] ms : map) {for (int m : ms) {count++;if (m != 0) {hashSet.add(m);} else {count_0++;}}}for (int[] ms : map) {for (int m : ms) {if (m != 0) {if (hashSet.size() + count_0 == count) {return true;}return false;}}}return true;}/*** 重载JPanel父类的paintComponent方法,用来绘制网格,以及游戏结束等*/@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);try {// 获取分钟int min = timestamp / 60;// 获取秒数int sec = timestamp % 60;// 判断是否结束游戏if (isEnd) {// 设置画笔颜色为红色g.setColor(Color.RED);// 设置字体 微软雅黑 加粗 62号g.setFont(new Font("微软雅黑", 0, 62));// 绘制GAME OVER字样g.drawString("游戏结束", 60, 150);// 设置字体 微软雅黑 加粗 40号g.setFont(new Font("微软雅黑", 0, 40));// 绘制得分g.drawString("得分:" + score, 80, 230);// 绘制用时g.drawString("用时:" + String.format("%02d", min) + ":" + String.format("%02d", sec), 80, 280);} else {// 设置字体 微软雅黑 加粗 20号g.setFont(new Font("微软雅黑", Font.BOLD, 20));// 设置画笔颜色为黑色g.setColor(Color.BLACK);// 绘制时间显示框g.fillRect(100, 8, 80, 30);// 绘制分数显示框g.fillRect(400, 8, 50, 30);// 设置画笔颜色为红色g.setColor(Color.RED);// 绘制时间提示标签g.drawString("时间:", 50, 30);// 绘制时间g.drawString(String.format("%02d", min) + ":" + String.format("%02d", sec), 110, 30);// 绘制分数提示标签g.drawString("分数:", 350, 30);// 绘制分数g.drawString(String.format("%03d", score) + "", 405, 30);// 绘制外层矩形框g.drawRect(sx, sy, rw, rw);// 绘制水平10个,垂直10个方格。 即水平方向9条线,垂直方向9条线, 外围四周4条线已经画过了,不需要再画。 同时内部64个方格填写数字。for (int i = 1; i < 10; i++) {// 绘制第i条竖直线g.drawLine(sx + (i * w), sy, sx + (i * w), sy + rw);// 绘制第i条水平线g.drawLine(sx, sy + (i * w), sx + rw, sy + (i * w));}}} catch (Exception e) {e.printStackTrace();}}/*** 绘制按钮显示和隐藏** @param i* @param j*/private void drawButton(int i, int j) {if (map[i][j] != 0) {btnMap[i][j].setVisible(true);} else {btnMap[i][j].setVisible(false);}}/*** 比较两次点击的按钮对应的数字** @param cj* @param ci*/private void compare(int cj, int ci) {/*** 如果cc是1,表示当前一共选中了一个方格,用pj,pi来记住这个方格的位置; 否则,表示现在选中的这个方格要与之前选中的方案比较,决定是否要删除*/if (cc == 1) {pj = cj;pi = ci;printMap(ci, cj);// 将所点击的方格背景设置为灰色btnMap[ci][cj].setBackground(Color.LIGHT_GRAY);drawButton(ci, cj);} else {// 此时,cc肯定是大于1的,表示要比较两个方格的值是否相同printMap(ci, cj);map = MapTool.removed(map, pi, pj, ci, cj);// 让MapTool类的remove方法去判断上一次所选的(pj,pi)处的方格值与本次选择的(cj,ci)处的方格值是否可以消掉// 处理第一个方格btnMap[ci][cj].setBackground(Color.WHITE);drawButton(ci, cj);// 处理第二个方格btnMap[pi][pj].setBackground(Color.WHITE);drawButton(pi, pj);cc = 0;// 将cc的值复位if (map[pi][pj] == map[ci][cj]) {score += 10;}isEnd = isEnd(map);// 游戏结束if (isEnd) {// 关闭定时器timer.stop();// 隐藏剩余的按钮for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[i].length; j++) {if (map[i][j] != 0) {btnMap[i][j].setVisible(false);}}}// 创建添加重新开始按钮restart = new JButton("重新开始");restart.setBackground(Color.WHITE);restart.setBounds(180, 350, 120, 40);restart.setBorder(BorderFactory.createRaisedBevelBorder());restart.setFocusPainted(false);restart.setForeground(Color.RED);restart.setFont(new Font("微软雅黑", 0, 20));restart.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {start();}});this.add(restart);repaint();}}repaint();}/*** 打印网格数据** @param ci* @param cj*/private void printMap(int ci, int cj) {if (ci == pi && cj == pj) {System.out.println("ci:" + ci + ", cj:" + cj);} else {System.out.println("ci:" + ci + ", cj:" + cj + ", pi:" + pi + ", pj:" + pj);}for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[i].length; j++) {if (ci == pi && cj == pj) {System.out.print(((ci == i && cj == j) ? "[" + map[i][j] + "]" : " " + map[i][j] + " ") + "  ");} else {System.out.print(((ci == i && cj == j || pi == i && pj == j) ? "[" + map[i][j] + "]" : " " + map[i][j] + " ")+ "  ");}}System.out.println();}}
}

MapTool类

package com.mg;import java.util.Random;/*** 类名:MapTool* 包名:com.mg* 创建时间:2020/6/23 15:21* 创建人: 明哥* 描述:  游戏规则 ,点击选中两个相同的数字即可消除这两个数字,没有过多的复杂判断* MapTool.java 类用于生产数字和判断选中的两个数字是否相同**/
public class MapTool {public static int[][] createMap() {int[][] map = new int[10][10];Random rand = new Random();for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[i].length; j++) {map[i][j] = rand.nextInt(9) + 1;}}return map;}public static int[][] removed(int[][] map, int pi, int pj, int ci, int cj) {if (map[pi][pj] == map[ci][cj] && (pj != cj || pi != ci)) {System.out.println("消除:map[" + ci + "][" + cj + "],map[" + pi + "][" + pj + "]");map[pi][pj] = 0;map[ci][cj] = 0;}return map;}
}

Main类

package com.mg;/*** 类名:Main* 包名:com.mg* 创建时间:2020/6/23 17:41* 创建人: 明哥* 描述:**/
public class Main {public static void main(String[] args) {new GameFrame().start();}
}

Java实现数字消消乐游戏项目相关推荐

  1. java开心消消乐代码_Vue实现开心消消乐游戏算法

    摘要:这篇Vue栏目下的"Vue实现开心消消乐游戏算法",介绍的技术点是"开心消消乐.Vue.开心.游戏.算法.实现",希望对大家开发技术学习和问题解决有帮助. ...

  2. java开心消消乐代码_Java小项目之:教你做开心消消乐!

    Java小项目之:教你做个开心消消乐! 今天给大家带来的小项目是开心消消乐(连连看),还是一样的惯例.操作简单,适合java初学者练手.想看其他java小项目的朋友可以关注我,我会持续更新,也可以私信 ...

  3. java开心消消乐代码_Java小项目之:教你做个开心消消乐!

    Java小项目之:教你做个开心消消乐! 今天给大家带来的小项目是开心消消乐(连连看),还是一样的惯例.操作简单,适合java初学者练手.想看其他java小项目的朋友可以关注我,我会持续更新,也可以私信 ...

  4. JAVA实现简单消消乐游戏

    [消消乐游戏]游戏规则: 输入一个只包含英文字母的字符串,字符串中的两个字母如果相邻且相同,就可以消除. 在字符串上反复执行消除的动作,直到无法继续消除为止,此时游戏结束. 输出最终得到的字符串长度. ...

  5. 数字方块消消乐html5游戏,数字方块消消乐

    数字方块消消乐,是将三消游戏和数字相结合的版本.玩家用户在游戏中,消除的对象更具有难点.需要你将方块上的数字凑成2048,才能正式完成各种消除要求,从而得到海量的奖励,赢取丰富的红包现金收益哦. 数字 ...

  6. Java web编写的消消乐游戏 完整源码、下载即可以运行

    今天为大家分享一个java web编写的学生选课系统,目前系统功能已经完善,后续会进一步完善.整个系统界面漂亮,有完整得源码,希望大家可以喜欢.喜欢的帮忙点赞和关注.一起编程.一起进步. 开发环境 开 ...

  7. Python儿童数字消消乐游戏源代码,小朋友认数字游戏源代码

    Python儿童数字消消乐源代码,小朋友认数字游戏源代码,通过消消乐游戏的方式来让小朋友来学习数字,让孩子在玩中学数字 完整代码下载地址:Python儿童数字消消乐游戏源代码 核心代码 import ...

  8. java开心消消乐代码_今晚请屏住呼吸,开心消消乐拍电影了!

    一眨眼 村长已经和大家在一起六年啦 在这些日子里 我们在一起慢慢长大 有些人褪去稚嫩,步入社会 有些人在外打拼,为梦想奋斗 有些人功成名就,却遗失幸福 ...... 但无论你是哪一种 还记得让你最开心 ...

  9. 成语消消乐java代码_成语消消看-4399成语消消看-成语消消看答案大全

    成语消消看65 文过饰非.无疾而终.大浪淘沙.因地制宜.飞龙在天.人山人海 微信成语消消看65关答案 惺惺相惜,飞龙在天,大浪淘沙,分崩离析,文过饰非 因地制宜,无疾而终,婀娜妩媚,人山人海,极乐世界 ...

最新文章

  1. windows 域环境应用---VNC远程协助工具的使用
  2. 记一次zabbix启动不成功
  3. @property、@sythesize以及Ivar和@dynamic讲解(下)
  4. read write spinlock
  5. 详解Oracle DELETE和TRUNCATE 的区别
  6. 利用canvas来绘制一个会动的图画
  7. 使用面向对象技术创建高级 Web 应用程序
  8. 极简版ASP.NET Core学习路径及教程
  9. Silverlight 4 or 5 安装步骤
  10. VC2012换字体问题
  11. Chrom安装Axure插件浏览原型图
  12. php验证qq,php QQ第三方登录/OAuth2.0验证
  13. 【RuoYi-Vue-Plus】扩展笔记 01 - 集成 JavaMail 发送邮件(源码)
  14. 【机器学习】浅谈正规方程法梯度下降
  15. Comparable和Comparator接口
  16. 【码支付系统】无授权—个人免签约支付系统二维码收款即时到账源码 –
  17. uefi怎么念_UEFI是什么,看完您就全明白了
  18. 我的晋升答辩小结:测试拿什么证明自己的能力?
  19. 技术只是工作的一部分
  20. 安防智能视频平台EasyCVR后台界面流量统计显示问题的优化

热门文章

  1. 关于多重继承时继承顺序的一点体会
  2. 在王者荣耀角度下分析面向对象程序设计B中23种设计模式之组合模式
  3. 神经网络模型预测步骤_神经网络预测值范围
  4. 树梅派4使用Docker安装可道云
  5. 信息学奥赛系列教程:开发工具Dev C++安装
  6. 防封号的原理是什么?怎样做到防封号?
  7. SPI读写SD卡速度有多快?
  8. unity学习笔记-有关透明材质的一些问题记录
  9. MATLAB基础篇——微积分应用
  10. 支持多代理,多学校的JAVA智慧校园系统源码(SaaS+电子班牌APP)