经典游戏介绍
“消灭星星”真好玩儿!只要把颜色相同的连起来消掉就好了呀~这游戏还有好几个版本,玩法都差不多,只是分数可能会有点不同。就是说两颗或更多同样颜色的砖连在一起就行了。
MVC模式应用
[ 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 ]
今天咱们聊的这个「消灭星星」,其实就是用了个现在挺火的名叫MVC(模型-视图-控制器)的框架。先说说Model,它可是整个游戏的核心~主要就是管着星星砖块的数据和状态那些大事儿。然后聊聊View,它的工作就是把画面画出来,加上动画效果啥的,还可以跟着Model的变更新动。不过要讲谁写的代码最多?那当然得数View!相比之下,Model和Controller就轻松很多哩。
砖块分布规律
是不是也爱玩儿“消灭星星’呀?无论哪个版本,每个排块间总是差不多的差异,这种现象我们叫它”波动均分”。不过传统办法可不大一样,我来给你好好说说这个”波动均分算法”!
// 波动均分色砖 waveaverage(5, 4, 4).forEach( // tiles 即色墙数组 (count, clr) => tiles.concat(generateTiles(count, clr)); ); // 打散色砖 shuffle(tiles);
砖块操作与得分
大家都明白,就是要把所有颜色一样的方块串成链子一起消除掉呀。但记得,消方块时别忘了记分这里有个轻松记分小套路:“消除一块得几分?= 10 x (消的数量-1)+5”。简单?
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; } } } }
优化算法
为解决扫描整个数组太慢的空洞清理难题,我想了个法子:先找出空洞位置,再在排除砖块时顺便处理掉,这样就省去了整体检查墙面的麻烦。就是利用”列集”记下墙边和空洞的地方,这个小技巧让填补空洞变得更快更有效!
最大得分计算
想拿到“无法消除的矩阵”高分?就跟玩跳棋似的,多试试不一样的走法呗,总会找到最优解的那步。别嫌烦,每次进关之前看看有没有“根本没法消”的情况,那时就要果断重新开始喽!
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; } } }
技术实现与挑战
写代码时,别忘了UI友好度!还有得搞清楚如何加载资源、添加动态效果等。View可是个大头菜,它关系着模型的变化。只要模型有所变动,我们的View也必须要动起来才行。一开始的时候,Control还直接让模型和View粘在一块儿了。
结语与展望
function deleteTile(tile) { // 标记空洞 markHollow(tile.index); // 删除砖块逻辑 ... }
“消灭星星”这款小游戏真的挺好玩滴,老少都喜欢。其实只要了解这个游戏规则和算术后,就能领悟到数学和科技美丽之处。而且我觉得,设计师们为了保证质量所做的努力都体现在里头。可能未来还有新的创新与突破,让我们在享受原有的乐趣之余也会感到惊艳哟~
。
评论0