页游源码
点击放大

「消灭星星」是一款很经典的「消除类游戏」,它的玩法很简单:消除相连通的同色砖块。
!demo
「消灭星星」存在多个版本,不过它们的规则除了「关卡分值」有些出入外,其它的规则都是一样的。笔者介绍的版本的游戏规则整理如下:
1. 色砖分布
2. 消除规则
两个或两个以上同色砖块相连通即是可被消除的砖块。
3. 分值规则
「n」表示砖块数量。上面是「总」分值的规则,还有「单」个砖块的分值规则:
「i」表示砖块的索引值(从 0 开始)。简单地说,单个砖块「得分值」和「扣分值」是一个等差数列。
4. 关卡分值
关卡分值 = 1000 + (level - 1) * 2000;「level」即当前关卡数。
5. 通关条件
上面两个条件同时成立游戏才可以通关。
笔者这次又是使用了 MVC 模式来写「消灭星星」。星星「砖块」的数据结构与各种状态由 Model 实现,游戏的核心在 Model 中完成;View 映射 Model 的变化并做出对应的行为,它的任务主要是展示动画;用户与游戏的交互由 Control 完成。
从逻辑规划上看,Model 很重而View 与 Control 很轻,不过,从代码量上看,View 很重而 Model 与 Control 相对很轻。
10 x 10 的表格用长度为 100 的数组可完美映射游戏的星星「砖块」。
R - 红色,G - 绿色,B - 蓝色,Y - 黄色,P - 紫色。Model 的核心任务是以下四个:
砖墙分两步生成:
理论上,可以将 100 个格子可以均分到 5 类颜色,不过笔者玩过的「消灭星星」都不使用均分策略。通过分析几款「消灭星星」,其实可以发现一个规律 ------ 「色砖之间的数量差在一个固定的区间内」。
如果把传统意义上的均分称作「完全均分」,那么「消灭星星」的分配是一种在均分线上下波动的「不完全均分」。
!正余弦波线图
笔者把上面的「不完全均分」称作「波动均分」,算法的具体实现可以参见「波动均分算法」。
「打散色砖」其实就是将数组乱序的过程,笔者推荐使用「 费雪耶兹乱序算法」。
以下是伪代码的实现:
「消除砖块」的规则很简单 ------ 相邻相连通相同色即可以消除。
!连通图
前两个组合符合「相邻相连通相同色即可以消除」,所以它们可以被消除;第三个组合虽然「相邻相同色」但是不「相连通」所以它不能被消除。
「消除砖块」的同时有一个重要的任务:生成砖块对应的分值。在「游戏规则」中,笔者已经提供了对应的数学公式:「消除砖块得分值 = 10 * i + 5」。
「消除砖块」算法实现如下:
清除的算法使用「递归」逻辑上会清晰一些,不过「递归」在浏览器上容易「栈溢出」,所以笔者没有使用「递归」实现。
砖墙在消除了部分砖块后,会出现空洞,此时需要对墙体进行夯实:
| !向下夯实 | !向左夯实 | !先下再左夯实 |
| :----: | :----: | :----: |
| 向下夯实 | 向左夯实 | 向左下夯实(先下后左) |
一种快速的实现方案是,每次「消除砖块」后直接遍历砖墙数组(10x10数组)再把空洞夯实,伪代码表示如下:
But... 为了夯实一个空洞对一张大数组进行全量遍历并不是一种高效的算法。在笔者看来影响「墙体夯实」效率的因素有:
1. 定位空洞
2. 砖块移动(夯实)
扫描墙体数组的主要目的是「定位空洞」,但能否不扫描墙体数组直接「定位空洞」?
墙体的「空洞」是由于「消除砖块」造成的,换种说法 ------ 被消除的砖块留下来的坑位就是墙体的空洞。在「消除砖块」的同时标记空洞的位置,这样就无须全量扫描墙体数组,伪代码如下:
在上面的夯实动图,其实可以看到它的夯实过程如下:
1. 空洞上方的砖块向下移动
2. 空列右侧的砖块向左移动
墙体在「夯实」过程中,它的边界是实时在变化,如果「夯实」不按真实边界进行扫描,会产生多余的空白扫描:
!对比
如何记录墙体的边界?
把墙体拆分成一个个单独的列,那么列最顶部的空白格片段就是墙体的「空白」,而其余非顶部的空白格片段即墙体的「空洞」。
!列
笔者使用一组「列集合」来描述墙体的边界并记录墙体的空洞,它的模型如下:
这个模型可以描述墙体的三个细节:
砖块在消除后,映射到单个列上的空洞会有两种分布形态 ------ 连续与非连续。
!连续空格与非连续空格
「连续空洞」与「非连续空洞」的夯实过程如下:
!空洞压缩
其实「空列」放大于墙体上,也会有「空洞」类似的分布形态 ------ 连续与非连续。
!空洞压缩
它的夯实过程与空洞类似,这里就不赘述了。
上一小节提到了「描述墙体的边界并记录墙体的空洞」的「列集合」,笔者是直接使用这个「列集合」来消除残砖的,伪代码如下:
View 主要的功能有两个:
UI 管理主要是指「界面绘制」与「资源加载管理」,这两项功能比较常见本文就直接略过了。View 的重头戏是「映射 Model 的变化」并完成对应的动画。动画是复杂的,而映射的原理是简单的,如下伪代码:
Model 的砖块每次数据的更改都会通知到 View 的砖块,View 会根据对应的变化做对应的动作(动画)。
Control 要处理的事务比较多,如下:
初始化时,Control 把 Model 的砖块单向绑定到 View 的砖块了。如下:
「通关分值」与「判断通关条件」这对逻辑在本文的「游戏规则」中有相关介绍,这里不再赘述。
对外事件规划如下:
| name | detail |
| :-- | :-- |
| pass | 通关 |
| pause | 暂停 |
| resume | 恢复 |
| gameover | 游戏结束 |
用户交互 APIs 规划如下:
| name | type | deltail |
| :-- | :-- | :-- |
| init | method | 初始化游戏 |
| next | method | 进入下一关 |
| enter | method | 进入指定关卡 |
| pause | method | 暂停 |
| resume | method | 恢复 |
| destroy | method | 销毁游戏 |
在知乎有一个关于「消灭星星」的话题:popstar关卡是如何设计的?
这个话题在最后提出了一个问题 ------ 「无法消除和最大得分不满足过关条件的矩阵」。
!两个问题
「无法消除的矩阵」其实就是最大得分为0的矩阵,本质上是「最大得分不满足过关条件的矩阵」。
最大得分不满足过关条件的矩阵
求「矩阵」的最大得分是一个 「背包问题」,求解的算法不难:对当前矩阵用「递归」的形式把所有的消灭分支都执行一次,并取最高分值。但是 ja 的「递归」极易「栈溢出」导致算法无法执行。
其实在知乎的话题中提到一个解决方案:
> 网上查到有程序提出做个工具随机生成关卡,自动计算,把符合得分条件的关卡筛选出来
这个解决方案代价是昂贵的!笔者提供有源码并没有解决这个问题,而是用一个比较取巧的方法:进入游戏前检查是事为「无法消除矩阵」,如果是重新生成关卡矩阵。
注意:笔者使用的取巧方案并没有解决问题。
下面是本文介绍的「消灭星星」的线上 DEMO 的二维码:
!二维码
游戏的源码托管在:
感谢耐心阅读完本文章的读者。本文仅代表笔者的个人观点,如有不妥之处请不吝赐教。
如果对「H5游戏开发」感兴趣,欢迎关注我们的专栏。
开发语言:JavaScript
项目类型:消灭星星 H5 游戏
Star 数:305
这是一套消灭星星 H5 游戏,代码结构清晰,适合开发者学习游戏的客户端渲染、服务端逻辑、场景管理与资源加载。项目涵盖了游戏的核心玩法、界面交互、地图与角色系统等模块,对理解游戏开发的完整流程具有较高的参考价值。
从技术实现角度看,游戏项目的难点在于:游戏循环与状态管理、资源加载与渲染优化、客户端与服务端的协议同步、以及多平台适配。本项目在这些方面提供了可运行的实现,开发者可以在此基础上进行二次开发或学习研究。
1. 下载源码压缩包,解压到本地开发环境。
2. 根据项目类型准备对应的运行环境(Node.js / Go / C# / Unity / Godot 等)。
3. 按照 README 中的步骤配置依赖、数据库和配置文件。
4. 先启动服务端,再运行客户端,即可进入游戏进行测试。
注意:本项目仅供学习研究使用,请勿用于商业或非法用途。
对于想进入游戏开发领域的开发者来说,这套源码是一个很好的入门参考。通过阅读代码,可以学习到游戏的核心玩法实现、场景与资源管理、网络协议设计、以及渲染优化等关键技术点。
同时,项目中的代码组织方式和模块划分,也展示了游戏项目在工程化方面的实践经验,值得开发者深入研究和借鉴。理解一个完整游戏项目的架构,对后续开发其他类型游戏也很有帮助。
本资源来源于开源社区,仅供学习研究和技术交流使用,请勿用于任何商业或违法违规用途。使用本项目产生的一切后果由使用者自行承担。若涉及第三方权益,请联系删除。
| 资源标题 | popstar - 消灭星星 H5 游戏 |
| 所属分类 | 页游源码 |
| 发布作者 | admin |
| 发布时间 | 2026-10-05 21:07:47 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 138 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |