玩过微信“天天爱消除”游戏的人都应该了解这类游戏,尤其这类游戏常常受到许多妹子的喜欢,所以我还是花了周末一天的时间做做这个游戏。
我的这个游戏当然没有微信里的效果那么炫酷,只是完成了消除游戏一些核心的逻辑,包括消失、补全、交换这些。
仔细算下来,这好像已经是我的第7款小游戏了,这又让我开始憧憬大游戏的到来。
算了,反正小时候玩过那么多小游戏,先把那些记忆中的游戏写完再说。
这款游戏还是延续canvas的方案,主要的逻辑还是在判断消失和补全的部分,
核心代码如下:
[code] /** * 检查下落补缺的方块 */ checkDropBlock: function() { var len = 0, hasFade = false; for(var i = 0; i < span.x; i++) { hasFade = false; for(var j = span.y - 1; j >= 0; j--) { var m = matrix[j][i]; if(!hasFade && m.opacity <= 0) { //垂直方向从下往上找,当找到第一个消失的方块时记录位置, //后面就不用再记录了 hasFade = true; len = j; } else if(hasFade && m.opacity > 0) { //遇到有效的方块则往下移动 matrix[len][i] = this.clone(m); matrix[j][i].opacity = 0; len--; } //当到达最顶部时,不够的选择随机的方块补充上,以此填满 if(j === 0 && m.opacity <= 0) { while(len >= 0) { matrix[len][i] = this.getRandomBlock(); len--; } } } } } /** * 检查需要消失渐变的方块 * @param x 结束的x坐标 * @param y 结束的y坐标 * @param len 消失方块连续长度 * @param direct 方向 * @returns {boolean} true-有消失的,false-无消失的 */ checkFadeBlock: function(x, y, len, direct) { if(len >= 3) { //长度大于等于3才会消失 while(len > 0) { var m = direct === 'x' ? matrix[y][x-len] : matrix[y-len][x]; //依次往前排,打上tag m.fade = 1; len--; } return true; } return false; }, /** * 检测两个方块是否相邻 * @param x1 方块1x坐标 * @param y1 方块1y坐标 * @param x2 方块2x坐标 * @param y2 方块2y坐标 * @returns {boolean} true-相邻,false-不相邻 */ checkNearBlock: function(x1, y1 ,x2 ,y2) { return (x1 - x2 === 1 && y1 - y2 === 0) || (x1 - x2 === -1 && y1 - y2 === 0) || (x1 - x2 === 0 && y1 - y2 === 1) || (x1 - x2 === 0 && y1 - y2 === -1); }, /** * 全局检查是否有3个及3个以上连续相同的方块 * @returns {boolean} true-有,false-没有 */ checkSameBlock: function() { var len = 0, color, opacity, ret = false; for(var i = 0; i < span.y; i++) { len = 0; //从左边第一个开始标记 color = matrix[i][0].color; opacity = matrix[i][0].opacity; for(var j = 0; j < span.x; j++) { var m = matrix[i][j]; if(m.opacity > 0 && opacity > 0 && m.color === color) { //如果方块有效,并且颜色等于上个方块的颜色,则len加1 len++; if(j === span.x-1 && this.checkFadeBlock(j+1, i, len, 'x')) { //最右边时直接检查 ret = true; } } else { //如果满足消失的要求在打上tag if(this.checkFadeBlock(j, i, len, 'x')) { ret = true; } //如果一旦出现无效或者颜色不等于上个方块的颜色,则充值len和颜色 len = 1; color = m.color; opacity = m.opacity; } } } //同上 for(i = 0; i < span.x; i++) { len = 0; color = matrix[0][i].color; opacity = matrix[0][i].opacity; for(j = 0; j < span.y; j++) { var mm = matrix[j][i]; if(mm.opacity > 0 && opacity > 0 && mm.color === color) { len++; if(j === span.y-1 && this.checkFadeBlock(i, j+1, len, 'y')) { ret = true; } } else { if(this.checkFadeBlock(i, j, len, 'y')) { ret = true; } len = 1; color = mm.color; opacity = mm.opacity; } } } if(ret && !animating) { //如果满足条件并且不处于动画中,则开启渐变消失动画 animating = true; this.createFadeBlock(); } return ret; } /** * 创建渐变消失动画 */ createFadeBlock: function() { fadeTimer && clearTimeout(fadeTimer); var flag = false; for(var i = 0; i < span.y; i++) { for(var j = 0; j < span.x; j++) { var m = matrix[i][j]; if(m.fade === 1) { //标记消失的才执行动画 flag = true; m.opacity -= 0.1; if(m.opacity <= 0) { //完全透明了了则可以结束动画了 m.fade = 0; m.opacity = 0; m.color = Color.bg; flag = false; } } } } if(flag) { fadeTimer = setTimeout(function() { elimination.createFadeBlock(); }, 10); } else { fadeTimer && clearTimeout(fadeTimer); animating = false; //随时都要检查是否要补齐空缺的方块 this.checkDropBlock(); //检查相同的方块 this.checkSameBlock(); } } /** * 开始后的点击事件回调 * @param e */ startedClickHandler: function(e) { var x = e.offsetX, y = e.offsetY, size = Config.size; x = Math.floor(x / size); y = Math.floor(y / size); var m = matrix[y][x]; if(m.selected === 0) { //未有选中状态 for(var i = 0; i < span.y; i++) { for (var j = 0; j < span.x; j++) { var mm = matrix[i][j]; if(mm.selected === 1 && this.checkNearBlock(x, y, j, i)) { //如果两个方块都被选中并且相邻才交换眼色 var color = mm.color; mm.color = m.color; m.color = color; if(!this.checkSameBlock()) { //如果交换没有消失的方块,则不能交换,直接还原 var tColor = mm.color; mm.color = m.color; m.color = tColor; } } mm.selected = +(i === y && j === x); } } } else { //已选中的话则去掉选中状态 m.selected = 0; } } [/code]
demos地址是:http://xiechengxiong.com/xui/demos/elimination/ (只能在手机上玩哦)
扫扫更健康:
别忘了光顾我的博客首页:http://xiechengxiong.com/