数字连连消

  • 效果图
  • 下面开始代码
    • 首先是```MapTool.java```,用于产生数字和判断选中的两个数字是否相同
    • 然后是```GamePanel.java```,游戏布局,游戏核心逻辑代码
    • 下面是```GameFrame.java```,定义游戏窗体
    • 最后是```Main.java```,游戏程序的入口

游戏规则很简单,点击选中两个相同的数字即可消除这两个数字,没有做复杂的判断。

效果图


下面开始代码

首先是MapTool.java,用于产生数字和判断选中的两个数字是否相同

package com.feonix;import java.util.Random;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;}}

然后是GamePanel.java,游戏布局,游戏核心逻辑代码

package com.feonix;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;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方法,用来绘制网格,以及Game Over等*/@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("GAME OVER", 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();}}
}

下面是GameFrame.java,定义游戏窗体

package com.feonix;import javax.swing.JFrame;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();}
}

最后是Main.java,游戏程序的入口

package com.feonix;public class Main {public static void main(String[] args) {new GameFrame().start();}
}

简单的Java小游戏 -- 数字连连消相关推荐

  1. 做一个简单的java小游戏--单机版五子棋

    做一个简单的java小游戏–单机版五子棋 学了java有一段时间了,今天就来搞一个简单的单机版五子棋游戏. 实现功能:那必须能进行基础的输赢判断.还有重新开始的功能,悔棋的功能,先手设置的功能和退出的 ...

  2. 做一个简单的java小游戏--贪吃蛇

    做一个简单的java小游戏–贪吃蛇 贪吃蛇游戏博客链接:(方法一样,语言不一样) c++贪吃蛇:https://blog.csdn.net/weixin_46791942/article/detail ...

  3. java小游戏课程设计消消乐_快速编程java:消消乐A1版,状态编程

    一年前做的项目.代码是公开的. 多个版本的俄罗斯方块.消消乐代码 https://blog.csdn.net/weixin_42644456/article/details/90178306 这里有网 ...

  4. 《游戏学习》教你上手一个简单的java小游戏《打纸飞机》附源码

    源码下载地址: https://download.csdn.net/download/weixin_40986713/20701376 项目结构目录 部分代码展示 import java.awt.Fo ...

  5. Java小游戏:冒险岛

    一个简单的Java小游戏:冒险岛 截图 操作说明: 项目地址

  6. JAVA简单实现扫雷小游戏

    JAVA简单实现扫雷小游戏 这两天学校外面来人教java基础,学习一下,自己试着做了一个扫雷小游戏,记录一下子学习过程.(我觉得自己不是很懂类和对象,基础没怎么看),敲出来的代码结构混乱,希望路过的大 ...

  7. java完成九宫格数独_简单实现java数独游戏

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 打算把javaFx需要的组件装好以后直接用javaFx的,但似乎eclipse的版本不对,安装了也不能用... 数独代码是在之 ...

  8. java小游戏——飞翔的小鸟(java初学作品)

    注:学习了java基础后,做出来的一个小作品,可以用来巩固学习 概述: 飞翔的小鸟能够作为Java基础的收官之作,包涵了Java很多的基础知识,在学习完Java基础后,尝试编写一些东西,能够起到很好的 ...

  9. 猜生日 Java小游戏

    猜生日 Java小游戏 最近看到一个很有趣的小游戏: 询问朋友5个问题,找到他出生在一个月的哪一天.每个问题都是询问他的生日是否是5个数字集合中的一个. 这5个集合分别是: set1:1 3 5 7 ...

  10. 10款Java小游戏(详解+源码)

    开源Java小游戏 前言 下面就给大家介绍十几个开源的Java小游戏,供大家学习交流.资源都下载好共享到我的交流群了,需要的在群内自取853665602不收取任何资源费,毕竟开源才是我们的宗旨. [群 ...

最新文章

  1. Java语言概述与简单程序
  2. 第九章:路由网关(Zuul)的使用
  3. vs debug 模式生成的exe 另一台电脑_C++利用spdlog生成日志
  4. 计算机组成测试题目及答案,计算机组成原理期中测试试卷一(含题目和答案)
  5. 通过阿里云容器镜像服务海外服务器构建spark-operator镜像
  6. 【MySQL】MySQL出现Waiting for table metadata lock的原因、解决方法
  7. android root权限函数,android 4.4下app永久获取root权限的方法
  8. 测试面试题集-3.生活物品测试:行李箱、电梯、洗衣机
  9. 骨牌覆盖问题 KxM
  10. struts中采用注解配置Action
  11. c语言连接mysql_0基础掌握Django框架(14)MySQL相关软件
  12. Hyper-V虚拟机启动报错:IDE/ATAPI 帐户没有足够的权限
  13. 苏宁小店门店数量一年锐减428家 张近东之子张康阳为实控人
  14. Mina中的多项式承诺方案
  15. matlab中acos得到的弧度范围,C语言acos()函数:求余弦值为 x 的弧度数
  16. appcrash事件怎么解决?三种方法教你
  17. mysql集群数据一致性校验
  18. AI插画师:生成对抗网络
  19. 亚马逊云科技为全球的可持续发展进程做出贡献
  20. 利用background-position 制作图片爆炸的效果

热门文章

  1. 搜狗收录方法之搜狗推送接口实现
  2. WEEK5 周记 作业——差分数组_TT的魔法猫
  3. 201621123068 Week03-面向对象入门
  4. IDEA必用插件 - 变量名中文转英文API注释翻译:Translation
  5. diamond mysql_TDDL动态数据源Diamond配置
  6. 关于windows虚拟桌面使用及录屏
  7. android imageloader 路径,Android中的Universal-Image-Loader的使用
  8. 红米k30s 至尊纪念版本看闪存型号 硬盘型号
  9. java 校验银行卡号_Java之——基于Luhn算法的银行卡卡号的格式校验
  10. 2014手游渠道分成比例汇总