加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

纯JS 吖真版连连看

(2011-12-01 19:37:57)
标签:

连连看

吖真

计时

计分

拐弯匹配

javascript

连接路线

随机

dom

递归

it

分类: Javascript

在家已经一段时间,所谓的病去如抽丝正是如此,郁闷到我想哭,只能在家继续当“啃老族”。
在写了前面一些底层接口后,我尝试去写一些比较切合实际的东西,写了一个射击游戏,我酝酿着看改良下再发,还有下面将介绍的:连连看。

 

你可以通过连接,下载源代码试玩:《吖真连连看数字版》、《吖真连连看表情版

数字版就是连连看的点击项是数字,表情版就是用以我自己为原型设计的一套表情包作为点击项,支持现代标准浏览器(不支持IE,我懒哈,等下个游戏再写IE兼容,欢迎关注)。

 

在写的时候还没有家里还没拉网线,构思的算法都是全部自己手写的,甚至连规则都不是很清楚(不怎么玩连连看但他老大喜欢玩的人路过)这几天拉了网线,上网查了下资料规则,发现匹配思路基本是一样,但是实现的方式不同,下面一步步的介绍:

 

整体界面套了射击游戏的框架(这话有点费,射击那个我又没发出来额...)1个操作界面跟3个控制按钮:开始,暂停,重开,顾名思义,当点击开始,才绑定元素的事件监听函数,倒计时开始;点暂停弹出一个遮罩层;重开则初始化游戏,重新随机生成元素、计分、计时。时间默认60秒倒计时,绝对充足,消除一对icon就1分。

 

界面宽高各10个icon宽,数字版每个ICON宽为40px,吖真版为60px,本来是挤满的50对元素,则100个,这样要完全匹配所有元素很难,所以换成现在布局,提高匹配率,从而增加游戏的可玩性。

 

里面的关键点有如下几个:

 

1、随机数的产生

每个元素只能出现两次,并且位置随机放置。这个是在createGame()里面实现的,temArray用于存放随机数,memoryArray用于存放随机数的出现次数,用一个length为36循环产生随机数,当随机数出现次数等于2时,就continue并把当前循环变量i减1,控制在length内,否则就添加到temArray里面,并且对应的出现次数要加1,这样一套循环下来就可以得到18对随机数;然后生成一个元素节点,设置对应的定位,添加到文本树上即可。

 

2、起点终点

逻辑获取关系我是这样分析的:

当起点为空或者起点终点都不为空的情况下,就获取点击元素为起点;

当终点为空并且点击元素不等于起点的情况下,就获取点击元素为终点。

 

3、匹配检测

1)直线检测

先判断起点终点是否在同一直线上,有横竖两种,因为我是0-100方格,刚好每行10个,所以才能用这个方法,

 0, 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

...

垂直方向上个位数都是一致的,水平方向十位数都是一致的,这个是巧合,应用不到实际项目上,因为这样js跟html的耦合度太高,假如每行15个,就没辙了,正确的做法应该是用一个二维数组映射,这样就算它增加多少行,每行增加多少个都无所谓,扩展性就强了很多。如果你看这文章是为了直接照搬,那是不能满足你的,不过算法思路还是异曲同工,可以将十位数对应转换成坐标的Y值,个位数转换成坐标的X值,或者是这样的数组array[y][x],所以感兴趣的话还是可以继续看下去。

 

通过垂直方向上个位数都是一致的,水平方向十位数都是一致的来判断是否处于同一直线,如果在同一直线,则通过一个循环,检测起点与终点之间是否存在障碍物,一旦检测到有其它元素阻挡,则返回false,否则返回true;

 

2)一次拐弯检测 reach

一次拐弯检测可以拆分成两次直线检测;中间一个拐点,比如:

 

21,22,23,24,25

31,32,33,34,35

41,42,43,44,45

 

我想检测从25到41是否可通,可以分解为25到21,21到41是否可通 或者 25到45,45到41是否可通,存在两个拐点21跟45。拐点的获取可以是 终点的个位+起点的十位×10,也可以是 终点的十位×10+起点的个位,当然在检测可通的同时,该拐点还应该是不存在的。

 

3)二次拐弯检测 reach2

这个本来我是写在同一个检测函数一次拐弯检测的下方,但是调用的时候出现了连续多个二次检测递归的现象,变得很慢,而且也不对,所以才拆开来,这样调用上一个函数就不会产生二次递归现象;

 

二次等于一次加一,这就是我实现二次拐弯检测的原理。先判断起点在直线方向上是否有一点可及但它不存在,再在这点上面进行与终点的一次拐弯检测,如果可及则起点与终点二次拐弯可及。比如:

 

21,22,232425

31,32,33,34,35

414243,44,45

 

25为起点,41为终点,红色数字表示该元素不存在,黑色数字表示该元素存在;

 

检测25到41可及,那么就水平方向向左 检测是否有一点可及但它不存在,于是检测到24,对24到41进行reach检测,结果是false,于是继续向左得到23,对23进行reach检测,发现23到43,43到41满足一次拐弯检测,返回true,于是25到41满足二次拐弯检测可通。

 

这个是向左的情况,还有向右、上、下,对元素进行4个方向的检测判断,如果上面24是黑色存在的话,那么就直接进入下一个方向的判断,因为道路已经死了。

 

4、路线生成 pathList

我在做这个的时候,跟我高中一个死党哥们聊天,他说他进排公司项目也在做连连看,不过他是AS的,我问他有没有做连线,他说这是必须的。所以我加了这个路线连线效果上去,因为js没有drawline之类的函数,所以只能生成一块块的方格代替,至于生成一条线也不是不可能,毕竟还是那句话:事在人为。可以做6张图片,40×40透明形式,4个拐弯图片+2个直线,就可以实现,拐弯的时候判断拐的方向,比如上面24-23-33这段,是向左再向下,这样就可以确定是哪个拐弯图片,这个我懒,说下想法,源代码里面没去实现哈。

 

路线中起点终点在点击的时候加入即可,pathList为3个则说明路径一次拐弯,中间拐了一次加了一个点;pathList长度至多为4,因为至多就是二次拐弯,2个拐点+起点+终点。

然后第一个元素到第二个元素,第二到第三,第三到第四逐步生成方块连接起来,拐点出可能生成两次,做一个重复判断检测,重复了就不要生成即可。

当生成路线后停留0.5秒,然后就清楚掉生成的路线块,同时清空pathList数组,重新记录路线,并再次生成。

 

5、其它

1)检测匹配,本来我是这样判断两点是否相等可及的

if(parseInt(Element1.innerHTML)==parseInt(Element2.innerHTML)&&(reach(srcObj,desObj)||reach2(srcObj,desObj))){}

逻辑上没错,但是后来想了一下,觉得应该拆开成这样的形式

if(parseInt(Element1.innerHTML)==parseInt(Element2.innerHTML)){

   if(reach(srcObj,desObj)||reach2(srcObj,desObj)){}

}

我是这样认为的,判断数值相等很快,但是检测是否可及需要一定时间,如果按照上面来写的话,需要判断相等与可及之后进入if里面执行语句,如果拆开了,那么如果不等直接跳过,就不用判断可及,这样就会相对快了很多。

 

2)倒计时

游戏开始就运行一个setInterval,时间间隔1000毫秒,即是1秒,刷新时间框里面的数字,当时间框里面的时候为0,并且还有剩余项没有点击完成的时候,你就输了。

 

3)计分

消除一对连连项就一分,在消除的时候顺便加上去的,意思意思。 

 

4)图片

这个纯属多余,只是跟你说你,可以弄18个60x60的图片替换掉我的图片,弄一个以自己为主题的连连看哈。 

 

 

 

近日将写一些比较实际的关于幻灯片的纯js模块,有兴趣的可以关注下我的博客,大家一起学习交流。

 

 

 

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有