H5游戏开发:消灭星星

2018/01/25 · HTML5 ·
游戏

原文出处: 凹凸实验室   

「消灭星星」是一款很经典的「消除类游戏」,它的玩法很简单:消除相连通的同色砖块。

金沙国际官网 1

消灭星星是个怎么样的游戏?

相关游戏: 消灭星星 发布时间:2018-03-13

在我们玩的所有游戏当中,消灭星星一定是最火爆的一款,不管是手机还是电脑上面,大家都在玩着这款小游戏,跟传统的那些棋牌类游戏相比,消灭星星的规则很少,而且都非常的简单,但就是这么简单的规则却充满了刺激性,这也是它会如此受到欢迎的原因之一了,那么,这么好玩的一款小游戏,新用户们又应该怎么快速的上手呢?

金沙国际官网 2

消灭星星的玩法真的是特别简单,只要把相同的星星全部点掉就可以了,相同的星星越多,点掉后所得到的分数也就越高,就是这么简单的一款游戏,却正好满足了年轻人们的需要。对于年轻人们来说,日常生活当中工作的压力巨大,好不容易放松下来,如果还继续玩些费脑的游戏,会让人感觉很累,消灭星星正好可以用来减压,而且它还有很多别的作用。

消灭星星还是很有名的战略性游戏,如果想在里面得到高分,就不能将图形一一进行消除,而是要先把它们都聚集在一起,只有聚集的相同星星多了,再一并进行消除,才会得到较高的分数,这也是它跟传统游戏最不一样的地方,在简单的同时也没有忘记增加动脑的部分,适量的增加反而会让消灭星星变的更加有意思。

另外,大家在玩消灭星星时,一定要保持一个良好的心态,因为这是一个需要反复的游戏,如果不能调整好心态,是没有办法得高分的,想要快速上手,就得学会如何调整自己的心态,心态如果崩了,在前期没有取得较高的分数,会对后期的通关产生很大影响,注意这点就知道前期的分数有多么重要了,知道了这些,相信大家对消灭星星也已经了解的差不多了。

上一篇:贪吃蛇的游戏玩法是怎么样的?
下一篇:魔法城堡连连看让你感受不一样的连连看

消灭星星游戏攻略,消灭星星高分技巧时间:2014-11-10

消灭星星好玩吗?消灭星星游戏特色介绍时间:2015-01-20

消灭星星中文版好玩吗?消灭星星中文版游戏介绍时间:2014-11-21

1. 游戏规则

「消灭星星」存在多个版本,不过它们的规则除了「关卡分值」有些出入外,其它的规则都是一样的。笔者介绍的版本的游戏规则整理如下:

金沙国际官网,1. 色砖分布

  • 10 x 10 的表格
  • 5种颜色 —— 红、绿、蓝,黄,紫
  • 每类色砖个数在指定区间内随机
  • 5类色砖在 10 x 10 表格中随机分布

2. 消除规则

两个或两个以上同色砖块相连通即是可被消除的砖块。

3. 分值规则

  • 消除总分值 = n * n * 5
  • 奖励总分值 = 2000 – n * n * 20

「n」表示砖块数量。上面是「总」分值的规则,还有「单」个砖块的分值规则:

  • 消除砖块得分值 = 10 * i + 5
  • 剩余砖块扣分值 = 40 * i + 20

「i」表示砖块的索引值(从 0
开始)。简单地说,单个砖块「得分值」和「扣分值」是一个等差数列。

4. 关卡分值

关卡分值 = 1000 + (level – 1) * 2000;「level」即当前关卡数。

5. 通关条件

  • 可消除色块不存在
  • 累计分值 >= 当前关卡分值

上面两个条件同时成立游戏才可以通关。

消灭星星是最近网上较为热门的一款游戏,我自己也是玩的不亦乐乎,每天都在玩,经验日积月累。接下来我将会为大家分享一些我玩消灭星星的一些攻略,其中也有不少的高分技巧,小伙伴有需要的快来跟随小编一起看看吧。

《消灭星星》是一款比较经典的游戏,就是吃分然后过关,每局有个分数线,每局都会累计分数。

消灭星星中文版好玩吗?今天小编为大家带来的就是消灭星星中文版游戏介绍。

2. MVC 设计模式

笔者这次又是使用了 MVC
模式来写「消灭星星」。星星「砖块」的数据结构与各种状态由 Model
实现,游戏的核心在 Model 中完成;View 映射 Model
的变化并做出对应的行为,它的任务主要是展示动画;用户与游戏的交互由
Control 完成。

从逻辑规划上看,Model 很重而View 与 Control
很轻,不过,从代码量上看,View 很重而 Model 与 Control 相对很轻。

很多人都在玩消灭星星,但是我想问:你们真的会玩吗?消灭星星看起来和常规游戏差不多,但是你有所不知的是这里面的学问可大着呢。一开始玩消灭星星时,我都是乱点,看到哪里集齐了两个以上颜色的方块,我就会去点,几次下来,我都发现每次都冲不过第二关,第一关有时候还是勉勉强强达到分数通过的。幸好后面我发现了其中的规律和一些高分的技巧。

《消灭星星》也可叫做《流行之星》且英文名为pop star,在2009年由Brian
Baek开发且发行商是掌游天下。可在ios系统和安卓系统上还有电脑PC上运行,可在App
Store或是安卓各大应用商店下载安装运行。

消灭星星中文版是一款妇孺孩童,不分国籍,不分地域,不论职业,人人都可以快速学会并且能够玩很好的手机游戏。如果你足够观察你身边的一切,你会发现买菜的阿姨在玩儿,买水果的小伙在玩儿,幼儿园的小孩子在玩,上小学上初中上高中的孩子都在玩,你甚至会惊呼公交车上的老嗲嗲也在玩,社区里的老??也在玩,老一辈们的技术并不比妹坨和伢子差。

3. Model

10 x 10 的表格用长度为 100 的数组可完美映射游戏的星星「砖块」。

[ R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G,
G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y,
Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R,
R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B,
B, Y, Y, P, P ]

1
2
3
4
5
6
7
8
9
10
11
12
[
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P
]

R – 红色,G – 绿色,B – 蓝色,Y – 黄色,P – 紫色。Model
的核心任务是以下四个:

  • 生成砖墙
  • 消除砖块 (生成砖块分值)
  • 夯实砖墙
  • 清除残砖 (生成奖励分值)

第一:尽量集齐多个相同颜色的方块一起消灭。我们在玩的时候,可以将一些散块的方块消除,让相同颜色的方块尽量都团聚到一起,然后再一起消除,这样得到的分数会比较高,而且还有奖励。

《消灭星星》的构造其实很简单,ios版本的和安卓版本的不同,ios版本的点开图标即可看到四个可点击的选项,只需点击NEW
GAME即可开始游戏。安卓版本的只有三个可点击的选项,也是只需点击NEW
GAME即可开始游戏。
安卓版本的和ios版本的每一关的目标分都是一样的就是界面不同而已。

然而,消灭星星中文版是一款以分数为闯关条件的益智手游,如果累积分数没有达到目标分数那么都得重新来。每一关都有一百个星星,这一百个星星由五种不同的颜色组成,同时消掉相同颜色的星星越多获得的分数越高,当没有同一颜色的星星在一起时,游戏结束。此时,剩下的星星个数少于十个就可以得到意外的分数加成也就是奖励,剩下的星星越少奖励分越多,奖励分数的上限为两千,下限是三百八十。

3.1 生成砖墙

砖墙分两步生成:

  • 色砖数量分配
  • 打散色砖

理论上,可以将 100 个格子可以均分到 5
类颜色,不过笔者玩过的「消灭星星」都不使用均分策略。通过分析几款「消灭星星」,其实可以发现一个规律
—— 「色砖之间的数量差在一个固定的区间内」。

如果把传统意义上的均分称作「完全均分」,那么「消灭星星」的分配是一种在均分线上下波动的「不完全均分」。

金沙国际官网 3

笔者把上面的「不完全均分」称作「波动均分」,算法的具体实现可以参见「波动均分算法」。

「打散色砖」其实就是将数组乱序的过程,笔者推荐使用「
费雪耶兹乱序算法」。

以下是伪代码的实现:

JavaScript

// 波动均分色砖 waveaverage(5, 4, 4).forEach( // tiles 即色墙数组
(count, clr) => tiles.concat(generateTiles(count, clr)); ); //
打散色砖 shuffle(tiles);

1
2
3
4
5
6
7
// 波动均分色砖
waveaverage(5, 4, 4).forEach(
// tiles 即色墙数组
(count, clr) => tiles.concat(generateTiles(count, clr));
);
// 打散色砖
shuffle(tiles);

第二:尽量不留下单独的方块。在玩的过程中,我们可以将落单的方块经过各种方法将其余其他方块搭在一起,然后消除,这样不仅分数更多,到游戏的最后,如果你完全没留下一个方块,都消除了,那你将得到1200分的奖励。

《消灭星星》是一款老少“通吃”的经典有趣的游戏,在地铁站里马路上都可以看见小朋友老奶奶都在玩。

在总成绩达到两万分,上一关和下一关等差数为四千,也就是说要在一个关卡内消灭星星的分数大于等于四千才能进入下一关,稍有不慎,前功尽弃,那么分数就会被清零,所以说这也是消灭星星最考智力的地方,也是最烦恼的地方。但是这些都不能影响大家对消灭星星中文版的喜爱,尽管如此大家依旧热爱它。的确,因为有了消灭星星大家的生活变得有味多了,即使一个人外出坐车,即使一个人做生意,但是有了这款游戏,老嗲嗲老??的生活不再那么枯燥无聊。但是我恳请各位手游的爱好者不要长时间的对着手机,让眼睛放松,不要为心灵的窗口蒙上白雾……

3.2 消除砖块

「消除砖块」的规则很简单 —— 相邻相连通相同色即可以消除

金沙国际官网 4
前两个组合符合「相邻相连通相同色即可以消除」,所以它们可以被消除;第三个组合虽然「相邻相同色」但是不「相连通」所以它不能被消除。

「消除砖块」的同时有一个重要的任务:生成砖块对应的分值。在「游戏规则」中,笔者已经提供了对应的数学公式:「消除砖块得分值
= 10 * i + 5」。

「消除砖块」算法实现如下:

JavaScript

function clean(tile) { let count = 1; let sameTiles =
searchSameTiles(tile); if(sameTiles.length > 0) { deleteTile(tile);
while(true) { let nextSameTiles = []; sameTiles.forEach(tile => {
nextSameTiles.push(…searchSameTiles(tile)); makeScore(++count * 10 +
5); // 标记当前分值 deleteTile(tile); // 删除砖块 }); //
清除完成,跳出循环 if(nextSameTiles.length === 0) break; else {
sameTiles = nextSameTiles; } } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function clean(tile) {
let count = 1;
let sameTiles = searchSameTiles(tile);
if(sameTiles.length > 0) {
deleteTile(tile);
while(true) {
let nextSameTiles = [];
sameTiles.forEach(tile => {
nextSameTiles.push(…searchSameTiles(tile));
makeScore(++count * 10 + 5); // 标记当前分值
deleteTile(tile); // 删除砖块
});
// 清除完成,跳出循环
if(nextSameTiles.length === 0) break;
else {
sameTiles = nextSameTiles;
}
}
}
}

清除的算法使用「递归」逻辑上会清晰一些,不过「递归」在浏览器上容易「栈溢出」,所以笔者没有使用「递归」实现。

第三:在游戏过程中,要先想再去点。我们消除方块前一定要多想,不能点了就点了,我们可以幻想着点完这个之后将会是什么局面,这个方块会落在哪个地方,那个方块会跟哪个方块重合。这些都是要经过我们深思熟虑的,只有经过此方法,我们才能对其更好的把握。

《消灭星星》第一关的目标分数是1000分,只需点击两个或者两个以上的星星即可获得分数,星星累积的越多分数越高,当然也没有时间限制可以慢慢思考。还有一个方法也可获得高分,就是剩下的星星越少最后奖励的分数越多,剩下的分数要在十个或十个以内才会得到奖励,如果没有剩下星星则奖励两千分之多,当然能达到这样高境界也是需要足够的运气和高深的技术。

以上就是消灭星星中文版游戏的相关介绍了,希望大家喜欢。

3.3 夯实砖墙

砖墙在消除了部分砖块后,会出现空洞,此时需要对墙体进行夯实:

向下夯实 向左夯实 向左下夯实(先下后左)

一种快速的实现方案是,每次「消除砖块」后直接遍历砖墙数组(10×10数组)再把空洞夯实,伪代码表示如下:

JavaScript

for(let row = 0; row < 10; ++row) { for(let col = 0; col < 10;
++col) { if(isEmpty(row, col)) { // 水平方向(向左)夯实
if(isEmptyCol(col)) { tampRow(col); } // 垂直方向(向下)夯实 else {
tampCol(col); } break; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for(let row = 0; row < 10; ++row) {
for(let col = 0; col < 10; ++col) {
if(isEmpty(row, col)) {
// 水平方向(向左)夯实
if(isEmptyCol(col)) {
tampRow(col);
}
// 垂直方向(向下)夯实
else {
tampCol(col);
}
break;
}
}
}

But…
为了夯实一个空洞对一张大数组进行全量遍历并不是一种高效的算法。在笔者看来影响「墙体夯实」效率的因素有:

  1. 定位空洞
  2. 砖块移动(夯实)

扫描墙体数组的主要目的是「定位空洞」,但能否不扫描墙体数组直接「定位空洞」?

墙体的「空洞」是由于「消除砖块」造成的,换种说法 ——
被消除的砖块留下来的坑位就是墙体的空洞。在「消除砖块」的同时标记空洞的位置,这样就无须全量扫描墙体数组,伪代码如下:

JavaScript

function deleteTile(tile) { // 标记空洞 markHollow(tile.index); //
删除砖块逻辑 … }

1
2
3
4
5
6
function deleteTile(tile) {
// 标记空洞
markHollow(tile.index);
// 删除砖块逻辑
}

在上面的夯实动图,其实可以看到它的夯实过程如下:

  1. 空洞上方的砖块向下移动
  2. 空列右侧的砖块向左移动

墙体在「夯实」过程中,它的边界是实时在变化,如果「夯实」不按真实边界进行扫描,会产生多余的空白扫描:

金沙国际官网 5

如何记录墙体的边界?
把墙体拆分成一个个单独的列,那么列最顶部的空白格片段就是墙体的「空白」,而其余非顶部的空白格片段即墙体的「空洞」。

金沙国际官网 6

笔者使用一组「列集合」来描述墙体的边界并记录墙体的空洞,它的模型如下:

JavaScript

/* @ count – 列砖块数 @ start – 顶部行索引 @ end – 底部行索引 @
pitCount – 坑数 @ topPit – 最顶部的坑 @ bottomPit – 最底部的坑 */ let
wall = [ {count, start, end, pitCount, topPit, bottomPit}, {count,
start, end, pitCount, topPit, bottomPit}, … ];

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
@ count – 列砖块数
@ start – 顶部行索引
@ end – 底部行索引
@ pitCount – 坑数
@ topPit – 最顶部的坑
@ bottomPit – 最底部的坑
*/
let wall = [
{count, start, end, pitCount, topPit, bottomPit},
{count, start, end, pitCount, topPit, bottomPit},
];

这个模型可以描述墙体的三个细节:

  • 空列
  • 列的连续空洞
  • 列的非连续空洞
JavaScript

// 空列 if(count === 0) { ... } // 连续空洞 else if(bottomPit -
topPit + 1 === pitCount) { ... } // 非连续空洞 else { ... }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-12">
12
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f3d2c2df29914802382-1" class="crayon-line">
// 空列
</div>
<div id="crayon-5b8f3d2c2df29914802382-2" class="crayon-line crayon-striped-line">
if(count === 0) { 
</div>
<div id="crayon-5b8f3d2c2df29914802382-3" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-4" class="crayon-line crayon-striped-line">
}
</div>
<div id="crayon-5b8f3d2c2df29914802382-5" class="crayon-line">
// 连续空洞
</div>
<div id="crayon-5b8f3d2c2df29914802382-6" class="crayon-line crayon-striped-line">
else if(bottomPit - topPit + 1 === pitCount) { 
</div>
<div id="crayon-5b8f3d2c2df29914802382-7" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-8" class="crayon-line crayon-striped-line">
}
</div>
<div id="crayon-5b8f3d2c2df29914802382-9" class="crayon-line">
// 非连续空洞
</div>
<div id="crayon-5b8f3d2c2df29914802382-10" class="crayon-line crayon-striped-line">
else {
</div>
<div id="crayon-5b8f3d2c2df29914802382-11" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-12" class="crayon-line crayon-striped-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>

砖块在消除后,映射到单个列上的空洞会有两种分布形态 —— 连续与非连续。

金沙国际官网 7

「连续空洞」与「非连续空洞」的夯实过程如下:

金沙国际官网 8

其实「空列」放大于墙体上,也会有「空洞」类似的分布形态 ——
连续与非连续。
金沙国际官网 9

它的夯实过程与空洞类似,这里就不赘述了。

上面就是小编给大家带来的消灭星星游戏攻略,这三个方法消灭星星的高分技巧小伙伴们都学会了吗?

其实想要一直长久过关玩《消灭星星》每局必须在三千到四千分左右才能保证不死一直玩下去,所以在玩每一关之前“下手”点星星之前都要好好思考一下再“下手”。

3.4 消除残砖

上一小节提到了「描述墙体的边界并记录墙体的空洞」的「列集合」,笔者是直接使用这个「列集合」来消除残砖的,伪代码如下:

JavaScript

function clearAll() { let count = 0; for(let col = 0, len =
this.wall.length; col < len; ++col) { let colInfo = this.wall[col];
for(let row = colInfo.start; row <= colInfo.end; ++row) { let tile =
this.grid[row * this.col + col]; tile.score = -20 – 40 * count++; //
标记奖励分数 tile.removed = true; } } }

1
2
3
4
5
6
7
8
9
10
11
function clearAll() {
let count = 0;
for(let col = 0, len = this.wall.length;  col < len; ++col) {
let colInfo = this.wall[col];
for(let row = colInfo.start; row <= colInfo.end; ++row) {
let tile = this.grid[row * this.col + col];
tile.score = -20 – 40 * count++; // 标记奖励分数
tile.removed = true;
}
}
}

4. View

View 主要的功能有两个:

  • UI 管理
  • 映射 Model 的变化(动画)

UI
管理主要是指「界面绘制」与「资源加载管理」,这两项功能比较常见本文就直接略过了。View
的重头戏是「映射 Model
的变化」并完成对应的动画。动画是复杂的,而映射的原理是简单的,如下伪代码:

JavaScript

update({originIndex, index, clr, removed, score}) { // 还没有
originIndex 或没有色值,直接不处理 if(originIndex === undefined || clr
=== undefined) return ; let tile = this.tiles[originIndex]; // tile
存在,判断颜色是否一样 if(tile.clr !== clr) { this.updateTileClr(tile,
clr); } // 当前索引变化 —– 表示位置也有变化 if(tile.index !== index)
{ this.updateTileIndex(tile, index); } // 设置分数 if(tile.score !==
score) { tile.score = score; } if(tile.removed !== removed) { //
移除或添加当前节点 true === removed ? this.bomb(tile) :
this.area.addChild(tile.sprite); tile.removed = removed; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
update({originIndex, index, clr, removed, score}) {
// 还没有 originIndex 或没有色值,直接不处理
if(originIndex === undefined || clr === undefined) return ;
let tile = this.tiles[originIndex];
// tile 存在,判断颜色是否一样
if(tile.clr !== clr) {
this.updateTileClr(tile, clr);
}
// 当前索引变化 —– 表示位置也有变化
if(tile.index !== index) {
this.updateTileIndex(tile, index);
}
// 设置分数
if(tile.score !== score) {
tile.score = score;
}
if(tile.removed !== removed) {
// 移除或添加当前节点
true === removed ? this.bomb(tile) : this.area.addChild(tile.sprite);
tile.removed = removed;
}
}

Model 的砖块每次数据的更改都会通知到 View 的砖块,View
会根据对应的变化做对应的动作(动画)。

5. Control

Control 要处理的事务比较多,如下:

  • 绑定 Model & View
  • 生成通关分值
  • 判断通关条件
  • 对外事件
  • 用户交互

初始化时,Control 把 Model 的砖块单向绑定到 View 的砖块了。如下:

Object.defineProperties(model.tile, { originIndex: { get() {…}, set(){
… view.update({originIndex}) } }, index: { get() {…}, set() { …
view.update({index}) } }, clr: { get() {…}, set() { …
view.update({clr}) } }, removed: { get() {…}, set() { …
view.update({removed}) } }, score: { get() {…}, set() { …
view.update({score}) } } })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Object.defineProperties(model.tile, {
    originIndex: {
        get() {…},
        set(){
            …
            view.update({originIndex})
        }
    },  
    index: {
        get() {…},
        set() {
            …
            view.update({index})
        }
    },
    clr: {
        get() {…},
        set() {
            …
            view.update({clr})
        }
    },
    removed: {
        get() {…},
        set() {
            …
            view.update({removed})
        }
    },  
    score: {
        get() {…},
        set() {
            …
            view.update({score})
        }
    }
})
 

「通关分值」与「判断通关条件」这对逻辑在本文的「游戏规则」中有相关介绍,这里不再赘述。

对外事件规划如下:

name detail
pass 通关
pause 暂停
resume 恢复
gameover 游戏结束

用户交互 APIs 规划如下:

name type deltail
init method 初始化游戏
next method 进入下一关
enter method 进入指定关卡
pause method 暂停
resume method 恢复
destroy method 销毁游戏

6. 问题

在知乎有一个关于「消灭星星」的话题:popstar关卡是如何设计的?

这个话题在最后提出了一个问题 ——
「无法消除和最大得分不满足过关条件的矩阵」

金沙国际官网 10

「无法消除的矩阵」其实就是最大得分为0的矩阵,本质上是「最大得分不满足过关条件的矩阵」。

最大得分不满足过关条件的矩阵
求「矩阵」的最大得分是一个
「背包问题」,求解的算法不难:对当前矩阵用「递归」的形式把所有的消灭分支都执行一次,并取最高分值。但是
javascript 的「递归」极易「栈溢出」导致算法无法执行。

其实在知乎的话题中提到一个解决方案:

网上查到有程序提出做个工具随机生成关卡,自动计算,把符合得分条件的关卡筛选出来

这个解决方案代价是昂贵的!笔者提供有源码并没有解决这个问题,而是用一个比较取巧的方法:进入游戏前检查是事为「无法消除矩阵」,如果是重新生成关卡矩阵

注意:笔者使用的取巧方案并没有解决问题。

7. 结语

下面是本文介绍的「消灭星星」的线上 DEMO 的二维码:

金沙国际官网 11

游戏的源码托管在:

感谢耐心阅读完本文章的读者。本文仅代表笔者的个人观点,如有不妥之处请不吝赐教。
如果对「H5游戏开发」感兴趣,欢迎关注我们的专栏。

参考资料

  • Knapsack problem
  • NP-completeness
  • popstar关卡是如何设计的?
  • 费雪耶兹乱序算法
  • 波动均分算法

    1 赞 收藏
    评论

金沙国际官网 12

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图