JavaScript消除游戏实现思路讲解

之前讲解过一款JavaScript贪食蛇游戏详细的设计与实现,但是以那种方式进行描述 , 整篇文章会显得复杂冗长,除非深入细致的阅读和思考,否则文中内容并不容易理解。这次换一种方式讲解一款JavaScript消除游戏的设计,文章只描述游戏的实现思路,不涉及代码的细节, 具体的实现细节, 读者可以通过文末链接下载代码样例进行深入探究。

简单的消除游戏的实现并不涉及复杂的算法, 使用常规的前端编程思路即可实现游戏。 核心思路概括描述就是:「操纵一个对象数组,将数组的变化映射到html游戏界面上」

[[1,2,3,4,5,6]

[6,3,3,1,2,3]

[6,1,3,1,6,5]

[1,2,1,3,4,4]

[1,1,6,6,6,6]

[5,6,3,2,1,1]]

游戏的数据结构类似于上面示例中的二维数组, 其中标红的数组项便是符合消除要求的。示例中的结构经过简化,真实的游戏结构中每一个数组项并不是纯数字, 而是一个对象, 对象结构如下

此结构表示消除游戏每一格中的元素

id为元素的唯一标识符

num表示元素的种类, 如果是一个水果消除游戏,那么每个值代表一种水果

moveCount表示当符合消除规则的元素组被移除后,剩余的元素填充到被消除元素位置上时需要移动的单位数。

isNew表示元素是否是新生成的,游戏过程中每次被消除掉多少元素, 同样需要生成新的相同数量的元素

接下来描述游戏的逻辑操作,逻辑操作的接口如下

initBoard方法用来初始化表示游戏数据结构的二维数组, 数组中的项是前面描述的Grid对象, 对象中的num字段是随机生成的,代表不同类型的元素。当游戏开始或者当前游戏状态已没有可消除的元素而需要重新生成局面时,就会调用这个方法。

testContinuable方法用来测试游戏中两个元素互相之间交换位置后是否出现了满足消除要求的情况, 此方法不改变游戏的数据结构, 纯粹进行判断和测试。 当我们游戏时交换元素位置, 便会调用这个方法进行测试, 交换位置后是否满足消除需求。

continuable方法用来判断整个游戏局面中接下来是否出现了满足消除要求的情况, 换句话说, 它用来判断当前局面是否是死局。

remove方法用来移除满足消除要求的元素

fillGameBoard方法的作用是当移除满足消除需求的元素以后, 对游戏数据结构中剩余元素的状态进行修改。 如计算元素对象的moveCount值,因为当有元素被消除后 ,在被消除元素坐标上方的元素需要下移, 填充被消除元素的位置, 这个moveCount值就是用来表示元素到新的位置上需要移动几格。另外, 这个方法还需要生成与被消除元素相同个数的新元素,并把新元素的isNew属性设置为true, 这个属性在游戏界面的生成中需要用到,当被消除的元素的html元素被移掉后,游戏UI程序需要根据isNew属性判断是否生成新的html。

getFirstEmptyPos方法获得游戏结构中第一个空的位置, 当调用remove方法后, 被消除的元素的位置为被置为null, 此方法便是获取这些null所在的位置。

getPos方法便是根据游戏数组结构中元素的id来获得元素的位置

swapGrid方法用来交换两个元素的位置。

这些方法是实现游戏的基础, 游戏界面以外的部份都被封装在这些操作当中。 接下来我们讲解整个程序的执行过程, 流程如下

  1. 渲染界面前, 首先要做的就是调用initBoard方法把数据结构初始化好, 设置结构中每个元素的moveCount字段的值, 这个值 跟动画效果的播放密切相关, 每一个元素往下落到自己所在的位置的跨度就由这个值决定。
  2. 界面程序根据游戏数组结构生成相应的html
  3. 根据游戏结构中每个元素的moveCount值播放动画, 初始化消除游戏的第一屏, 并为游戏的UI交互绑定事件。
  4. 检查第一屏中是否有满足消除要求的元素, 如果有则调用removefillGameBoard自动执行消除,并播放过消除前到消除后的过渡动画。 完成这个操作后再一次检查是否有满足消除要求的元素, 如果有则再次重复上面这个过程,直到没有符合消除要求的元素为止。 如果没有,则表示已游戏准备就绪,用户可进行游戏。 在这里有一种例外的情况,当在游戏就绪的情况下,当前的局面却是个死局, 那么游戏的第一屏将注销掉, 程序自动初始化第二屏。
  5. 最后是游戏的操作过程。消除游戏操作本质上只是不断的交换结构中元素的位置, 并检查位置在交换后是否满足可消除的状态, 如果满足要求只需要调用remove方法和fillGameBoard方法消除符合要求的元素并改变元素的状态和生成新的元素项, 然后再播放过渡动画,这些动作组合在一起便是一个完整的游戏操作过程。

以上便是整个消除游戏大致的实现思路, 具体的细节, 还需要一行一行的啃完样例所有代码才能理解。附上样例代码的下载地址

http://pan.baidu.com/s/1bo7IrHd

游戏是针对PC端浏览器设计, 执行消除的交互操作需要使用鼠标点击两个相邻的格子,因此,并不是很人性化, 但这个示例是为了实现消除功能而开发的, 更关注的是代码的逻辑, 所以没有交互操作上下功夫, 如果有同学觉得不好玩, 那也在情理之中。

最后,阅读完这篇文章和样例中的代码后的同学, 如果能自己徒手实现一下, 相信对于前端水平会有一定程度上的提高, 毕竟实现游戏比实现其它前端效果难度相对要高。 如果有兴趣, 请务必尝试。

原文发布于微信公众号 - 带你撸出一手好代码(gh_afab56b37671)

原文发表时间:2017-03-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python区块链

人工智能实现程序员“防”BOSS?刷脸就发短信,8行代码人脸报警

如今一个攻城狮就能搞定人脸的深度进修算法,这要多感激打动国外开源框架,虽然达不到旷世face++和诸多人脸公司的深度,可是实际应用已经没有太大压力。下图就是te...

479120
来自专栏青玉伏案

代码重构(四):条件表达式重构规则

继续更新有关重构的博客,前三篇是关于类、函数和数据的重构的博客,内容还算比较充实吧。今天继续更新,本篇博客的主题是关于条件表达式的重构规则。有时候在实现比较复杂...

21190
来自专栏韩伟的专栏

基于对象和面向对象

“基于对象”是“面向对象”一次动态化变迁,它依赖于现代语言的动态特性,让方法和属性统一起来;用组合取代继承;以函数对象查找取代多态的方法调用。这些变化让面向对象...

1.5K00
来自专栏web编程技术分享

来谈谈JAVA面向对象 - 继续说多态~

30550
来自专栏后端沉思录

回调函数

什么是回调函数,上面的问题说的是不是很空洞,不是太形象,下面是知乎上的一位网友给的答案:

42220
来自专栏Python小屋

微课系列(四):Python中map对象的几种用法和注意事项

在Python中,map、filter、enumerate、zip、reversed等对象除了惰性求值之外,还有个共同的特点是“其中的元素只能使用一次”,这一点...

9620
来自专栏王亚昌的专栏

C++多线程编程学习二 [类中封装互斥量的设计]

      之前我也提到过,如果一个类的数据成员中在多线程环境中可能会被竞争使用时,一定要在类中解决这个问题,而不是在代码编写过程中在每次使用时去申请或释放,这...

9510
来自专栏青玉伏案

代码重构(五):继承关系重构规则

陆陆续续的发表了多篇关于重构的文章了,还是那句话,重构是一个项目迭代开发中必不可少的一个阶段。其实重构伴随着你的项目的整个阶段。在前几篇关于重构的文章中我们谈到...

22260
来自专栏互联网杂技

基础JavaScript装逼指南

本文秉承着 你看不懂是你sb,我写的代码就要牛逼 的理念来介绍一些js的装逼技巧。 下面的技巧,后三个,请谨慎用于团队项目中(主要考虑到可读性的问题),不然,l...

36650
来自专栏C/C++基础

C++0x 通用属性

C++在不断的发展,但每一阶段的C++标准提供的功能都很难完全满足现实需求,于是为了弥补标准的不足或者扩增特性应用场景所需的特性,各大C++编译器厂商多多少少在...

13720

扫码关注云+社区

领取腾讯云代金券