上节中讲了如何寻路,在和朋友们讨论时都反应有时走的不太对,绕远路了,其实代码主要是大方向的判断 比如目标在右上,那应该是先右还是先上 这个并没有做处理,如果这个做了处理,效果会更好一些,但也难免会走弯路。 贪心就是这样,不是最优,接近最优。也希望其他的同学有意见的可以讨论下。我这也只是个人想法。
既然可以走动了,那就可以判断是否可以消除同样颜色的行、列或斜线了。只要>=5个同样的色球,就清除他们,并且可以继续移动。如果不可以清除,那就再增加3个球。
clearLine: function (x1, y1, color, isClick) { if (this.isEmpty(x1, y1)) { if (isClick) game.ready.flyin(); return; }; //给定一个坐标,看是否有满足的line可以被消除 //4根线 一 | / \ var current = this.getBubble(x1, y1); if (!current.color) { console.log(current); } var arr1, arr2, arr3, arr4; arr1 = this.bubbles[y1];//横线很简单,就是数组的一项,现成的 arr2 = []; for (var y = 0; y < game.cellCount; y++) arr2.push(this.getBubble(x1, y));//竖线就是一列。 arr3 = [current]; arr4 = [current]; for (var i = 1; i < game.cellCount ; i++) { if (x1 - i >= 0 && y1 - i >= 0)//\斜线的上半部分... arr3.unshift(this.getBubble(x1 - i, y1 - i)); if (x1 + i < game.cellCount && y1 + i < game.cellCount)//\斜线的下半部分 arr3.push(this.getBubble(x1 + i, y1 + i)); if (x1 - i >= 0 && y1 + i < game.cellCount)// /斜线的下半部分 arr4.push(this.getBubble(x1 - i, y1 + i)); if (x1 + i < game.cellCount && y1 - i >= 0)// /斜线的上班部分 arr4.unshift(this.getBubble(x1 + i, y1 - i)); } var line1 = getLine(arr1); var line2 = getLine(arr2); var line3 = getLine(arr3); var line4 = getLine(arr4); var line = line1.concat(line2).concat(line3).concat(line4); if (line.length < 5) { if (isClick) game.ready.flyin(); return; } else { var me = this; var i = 0; game.play("clearline", function () { if (i == line.length) { game.score.addScore(line.length); game.stop("clearline"); me.isMoving = false; //game.ready.flyin(); return; } me.isMoving = true; var p = line[i]; me.setBubble(p.x, p.y, null); i++; }, 100); } function getLine(bubbles) { var line = []; for (var i = 0; i < bubbles.length; i++) { var b = bubbles[i]; if (b.color == color) { line.push({ "x": b.x, "y": b.y }); } else { if (line.length < 5) line = []; else return line; } } if (line.length < 5) return []; return line; } },
大家可以看看代码,主要有两点 1、或许需要处理的 横竖斜线 4个数组,然后看这4个数组是否有连续的。判断是否连续只需要一个状态数组来维持就可以了。
由于考虑到同时消除多行的情况,所以要把连续的line 连接在一起,并在结算得分时考虑奖励。
isClick参数主要用于判断是否是用户点击进行消行的还是新泡泡飞入产生的。 如果达不到消行条件并且是飞入的,那就不能再调用飞入了,否则死循环了。
满足的消行代码也比较简单,就是播放一个消行动画,其实这个动画真心没劲,要想设计好些可以做个渐变偏移消除。 现在我发现起初没有设计一个数组来维护状态有些不太明智,因为还有奖励的星星和炸弹要绘制,挺麻烦的。。 那么,把积分显示出来吧。 这样就可以先试玩起来了:)
game.score = { basic: 0, operate: 0, star1: 0, star2: 0, boom: 0, draw: function () { var startX = game.cellWidth * 10 + game.map.startX; var startY = game.map.startY; var ctx = game.ctx; ctx.save(); ctx.translate(startX, startY); ctx.clearRect(0, 0, 150, 400); ctx.strokeStyle = "#456"; //ctx.strokeRect(0, 0, 150, 200); ctx.font = "24px 微软雅黑"; ctx.fillStyle = "#fefefe"; ctx.fillText("score:" + (this.basic * 5 + this.star1 * 8 + this.star2 * 10 + this.boom * 20), 0, 30); ctx.stroke(); ctx.restore(); }, addScore: function (length) { switch (length) { case 5: this.basic++; break; case 6: this.star1++; break; case 7: this.star2++; break; default: this.boom++; break; } this.draw(); console.log(this.score); }, };
第三节在设计里谈到了 百搭星和炸弹,我太懒了,不打算讲了,因为这些处理也没有什么复杂的,HTML5 Canvas的的基础学习也算可以了。后面应该学一些更深入的东西,比如如何处理性能、物体碰撞、运动学神马的。。。
现在游戏应该还有bug,大家可以看看代码发现吧,这个系列就到这了,谢谢大家。
试玩地址:http://zhengliangjun.sinaapp.com/colorline.html
源码下载:http://download.csdn.net/download/maddemon/4154990