简单的Java小游戏 -- 数字连连消

   日期:2020-05-20     浏览:139    评论:0    
核心提示:数字连连消效果图下面开始代码首先是```MapTool.java```,用于产生数字和判断选中的两个数字是否相同然后是```GamePanel.java```,游戏布局,游戏核心逻辑代码下面是```GameFrame.java```,定义游戏窗体最后是```Main.java```,游戏程序的入口游戏规则很简单,点击选中两个相同的数字即可消除这两个数字,没有做复杂的判断。效果图下面开始代码首先是MapTool.java,用于产生数字和判断选中的两个数字是否相同package com.feojava

数字连连消

  • 效果图
  • 下面开始代码
    • 首先是```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() {
					@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();
	}

	
	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;
	}

	
	@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();
		}
	}

	
	private void drawButton(int i, int j) {
		if (map[i][j] != 0) {
			btnMap[i][j].setVisible(true);
		} else {
			btnMap[i][j].setVisible(false);
		}
	}

	
	private void compare(int cj, int ci) {
		
		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();
	}

	
	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;
	
	
	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();
	}
}

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服