java可以开发游戏吗(分享十款经典游戏的Java版本)
小庄 游戏资讯 2022-09-08 16:08:47 · 热度999

周末无聊,用 Java 写了一个扫雷程序,说起来,这个应该是在学校的时候,写会比较好玩,毕竟自己实现一个小游戏,还是比较好玩的。说实话,扫雷程序里面核心的东西,只有点击的时候,去触发更新数据这一步。

Swing 是过时了,但是好玩不会过时,不喜勿喷

 

源码的地址:
https://github.com/Damaer/Game/tree/main/SweepMine

下面讲讲里面的设计:

BFS

数据结构设计

在这个程序里面,为了方便,使用了全局的数据类 Data 类来维护整个游戏的数据,直接设置为静态变量,也就是一次只能有一个游戏窗口运行,否则会有数据安全问题。(仅仅是为了方便)

有以下的数据(部分代码):

public class Data { // 游戏状态 public static Status status = Status.LOADING; // 雷区大小 public static int size = 16; // 雷的数量 public static int numOfMine = 0; // 表示是否有雷,1:有,0没有 public static int[][] maps = null; // 是否被访问 public static boolean[][] visited = null; // 周边雷的数量 public static int[][] nums = null; // 是否被标记 public static boolean[][] flags = null; // 上次被访问的块坐标 public static Point lastVisitedPoint = null; // 困难模式 private static DifficultModeEnum mode; ... }

需要维护的数据如下:

  • 游戏状态:是否开始,结束,成功,失败等等

  • 模式:简单,中等或者困难,这个会影响自动生成的雷的数量

  • 雷区的大小:16*16的小方块

  • 雷的数量:与模式选择有关,是个随机数

  • 标识每个方块是否有雷:最基础的数据,生成之后需要同步更新这个数据

  • 标识每个方块是否被扫过:默认没有扫过

  • 每个方块周边类雷的数量:生成的时候同步计算该结果,不想每次点击后再计算,毕竟是个不会更新的数据,一劳永逸

  • 标识方块是否被标记:扫雷的时候我们使用小旗子标记方块,表示这里是雷,标识完所有的雷的时候,成功

  • 上次访问的方块坐标:这个其实可以不记录,但是为了表示爆炸效果,与其他的雷展示不一样,故而记录下来

视图与数据分开

尽量遵循一个原则,视图与数据或者数据变更分开,方便维护。我们知道 Java 里面是用 Swing 来画图形界面,这个东西确实难画,视图写得比较复杂但是画不出什么东西。

 

视图与数据分开,也是几乎所有框架的优秀特点,主要是方便维护,如果视图和数据糅合在一起,更新数据,还要操作视图,那就会比较乱。(当然我写的是粗糙版本,只是简单区分了一下)

在这个扫雷程序里面基本都是点击事件,触发了数据变更,数据变更后,调用视图刷新,视图渲染的逻辑与数据变更的逻辑分开维护。

每个小方块都添加了点击事件, Data.visit(x, y) 是数据刷新, repaintBlocks() 是刷新视图,具体的代码就不放了,有兴趣可以 Github 看看源代码:

new MouseListener() { @Override public void mouseClicked(MouseEvent e) { if (Data.status == Status.GOING) { int c = e.getButton(); // 得到按下的鼠标键 Block block = (Block) e.getComponent(); int x = block.getPoint_x(); int y = block.getPoint_y(); if (c == MouseEvent.BUTTON1) { Data.visit(x, y); } else if (c == MouseEvent.BUTTON3) {// 推断是鼠标右键按下 if (!Data.visited[x][y]) { Data.flags[x][y] = !Data.flags[x][y]; } } } repaintBlocks(); } }

这里很遗憾的一点是每个方块里面还有一个背景的``url`没有抽取出来,这个是变化的数据,不应该放在视图里面:

小庄
0
0