Java实现数字连连消

本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下

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

效果图

下面开始代码

首先是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() {
  @Override
  public 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() {
 @Override
 public 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等
 */
 @Override
 protected 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,表示当前一共选中了一个方格,用px,py来记住这个方格的位置; 否则,表示现在选中的这个方格要与之前选中的方案比较,决定是否要删除
 */
 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方法去判断上一次所选的(px,py)处的方格值与本次选择的(cx,cy)处的方格值是否可以消掉
 // 处理第一个方格
 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() {
  @Override
  public 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;

 /**
 * DrawSee构造方法
 */
 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();
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java连连看游戏菜单设计

    本文实例为大家分享了java连连看游戏菜单的具体实现代码,供大家参考,具体内容如下 先写GUI. 首先初始化框架,菜单,按钮,需要把菜单和按钮都添加在框架中.注意添加的顺序,首先要设置菜单,再设置框架,再设置按钮,如果交换了设置菜单和框架的顺序,会导致菜单显示不出,被框架挡住.对菜单设置了三个选项,第一个选项有五个下拉按键,用循环添加,第二个和第三个选项的下拉按键直接添加. GUI代码如下: package gui; import java.awt.Font; import javax.swin

  • java基于swing实现的连连看代码

    本文实例讲述了java基于swing实现连连看代码.分享给大家供大家参考. 主要功能代码如下: 复制代码 代码如下: package llkan; import javax.swing.*; import java.awt.*; import java.awt.event.*; /**  * 连连看游戏  * @author Administrator  *2014年10月17日  */ public class MainGame implements ActionListener {     

  • java实现连连看游戏

    本文实例为大家分享了java实现连连看游戏的具体代码,供大家参考,具体内容如下 代码会实现共享的,这个是截图 代码: package com.lr.bean; import java.util.Scanner; import java.util.Random; import com.lr.bean.Point; public class Link{ public static void main(String[] args){ Scanner sc=new Scanner(System.in);

  • java仿QQ连连看游戏

    关于这个项目,真的是花了很多心思在上面,从开始构思,到最后完成,真的是花了整整一个月.大概是11月初开始学java swing的时候有的想法,然后开始构思整个思路,相关算法讨论以及调试. 最开始先对连连看基础算法进行测试,就用一般的二维数组,然后就用控制台输入两个点的坐标进行删除,这一步就调试了我整整一个星期,基础算法搞完了 终于开始设计界面了,反正也不知道那时候花了多长时间才把界面给设计好,反正还设计的特别丑(至今也如此). 功能如下: 运行程序后有背景音乐 菜单栏有:重新开始,提示,炸弹,排

  • Java实现数字连连消

    本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下 游戏规则很简单,点击选中两个相同的数字即可消除这两个数字,没有做复杂的判断. 效果图 下面开始代码 首先是MapTool.java,用于产生数字和判断选中的两个数字是否相同 package com.feonix; import java.util.Random; public class MapTool { public static int[][] createMap() { int[][] map = ne

  • JAVA实现数字大写金额转换的方法

    本文实例讲述了JAVA实现数字大写金额转换的方法.分享给大家供大家参考.具体如下: 例子:实现将阿拉伯数字的金额转换成中文大写金额的形式,例如: ¥1011 → 壹仟零壹拾壹元整. 大写数字为:零.壹.贰.叁.肆.伍.陆.柒.捌.玖.拾.佰.仟.万.亿 import java.io.*; import java.lang.String; public class change { public static void main(String agrs[]) { //Money用于存放输入的金额数

  • Java实现数字转成英文的方法

    本文实例讲述了Java实现数字转成英文的方法.分享给大家供大家参考.具体分析如下: 英文数词,按3位3位区分 Hundred: 100 Thousand:1,000 Million: 1,000,000 Billion: 1,000,000,000 Trillion: 1,000,000,000,000 Quintillion: 1,000,000,000,000,000,000 Sextillion: 1,000,000,000,000,000,000,000 Nonillion: 1,000

  • Java去掉数字字符串开头的0三种方法(推荐)

    方式一: 例如:"0000123" (字符串必须全为数字) 处理过程: String tempStr = "0000123"; int result = Integer.parseInt(tempStr); result 结果:123 方式二: 例如:"0000123" 处理过程: String str = "0000123"; String newStr = str.replaceFirst("^0*",

  • 纯Java实现数字证书生成签名的简单实例

    package com.ylsoft.cert; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator;

  • Java中数字黑洞实现代码

    给定任一个各位数字不完全相同的4位正整数,如果我们先把4个数字按非递增排序,再按非递减排序,然后用第1个数字减第2个数字,将得到一个新的数字.一直重复这样做,我们很快会停在有"数字黑洞"之称的6174,这个神奇的数字也叫Kaprekar常数. 例,我们从6767开始,将得到 7766 - 6677 = 1089 9810 - 0189 = 9621 9621 - 1269 = 8352 8532 - 2358 = 6174 7641 - 1467 = 6174 现给定任意4位正整数,请

  • java实现数字转大写的方法

    java实现数字转大写的方法 说明: 将数字金额转大写,如下: public class Test { /** * @param args * add by zxx ,Nov 29, 2008 */ private static final char[] data = new char[] { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' }; private static final char[] units = new char[] { '

  • java实现数字转换人民币中文大写工具

    本文实例为大家分享了java实现数字转换人民币中文大写的具体代码,供大家参考,具体内容如下 业务场景: 1.在人事业务系统开发的报表打印文书时经常需要将人民币数值转换为大写, 所以用java写了一个通用的大写转换函数. 为了更加方便调用函数的参数使用字符串类型.例如:825.45 转换后:捌佰贰拾伍元肆角伍分 2.在人事业务系统中经常把日期用汉字大写表示,为了方便调用函数,也是使用字符串类型.例如:2018 转换后:二〇一八 下面为java代码 public class Data2Zh { fi

  • Java将数字金额转为大写中文金额

    本文实例为大家分享了Java将数字金额转为大写中文金额的具体代码,供大家参考,具体内容如下 前言: 输入数字金额参数,运行程序得到其对应的大写中文金额:例如:输入- 12.56,输出- 12.56:壹拾贰元伍角陆分:重点来了:本人亲测有效. 奉上代码: /** *@Title: ConvertUpMoney * @Description: 将数字金额转为大写汉字金额 * @date: 2019年6月18日 下午10:52:27 */ public class ConvertUpMoney { /

  • java金额数字转中文工具类详解

    本文实例为大家分享了java金额数字转中文工具类的具体代码,供大家参考,具体内容如下 java金额数字转中文工具类ConvertNum.java package light.mvc.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * 金额数字转中文工具类 * * @author ardo * */ public class Convert

随机推荐