- 画布对象Canvas,用来标记蛇运动场所;
- 蛇对象Snake,用来显示一条蛇;
- 蛇的食物Food;
- 记分牌对象Scoreboard;
- 贪吃蛇游戏对象SnakeGame;
画布Canvas对象。
首先画布如下形式:
那么该对象具有属性为canvas所规定的四面墙,也就是snake运动范围的四个边界,以此定义为northWall(北)、eastWall(东)、southWall(南)、westWall(西);
同时canvas对象应该具有两个方法,分别为:展示该画布的方法draw()及判断某快砖属于那面墙的方法whichWallForBrick(vBrick)。
实现如下:
function Canvas() { this.northWall = new Array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19);// 北 this.eastWall = new Array(20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, 360, 380);// 东 this.southWall = new Array(382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399);// 南 this.westWall = new Array(21, 41, 61, 81, 101, 121, 141, 161, 181, 201, 221, 241, 261, 281, 301, 321, 341, 361, 381);// 西 } Canvas.prototype.whichWallForBrick = function(vBrick) { if (this.northWall.indexOf(vBrick) != -1) { return 'N'; } if (this.southWall.indexOf(vBrick) != -1) { return 'S'; } if (this.westWall.indexOf(vBrick) != -1) { return 'W'; } if (this.eastWall.indexOf(vBrick) != -1) { return 'E'; } return false;// 不属于任何一面墙 }; Canvas.prototype.draw = function() { var oDiv_canvas = document.getElementById("canvas"); if (oDiv_canvas == null) { oDiv_canvas = createElement("div", "canvas", null); } var oFragment = document.createDocumentFragment();// 创建文档碎片 for ( var i = 1; i <= 400; i++) { var oSpan = createElement("span", i, i); oFragment.appendChild(oSpan); } oDiv_canvas.appendChild(oFragment); document.body.appendChild(oDiv_canvas); };
Snake对象:
针对上图不难看出,定义一条snake需要制定该snake的head(图中绿色部分)及tail(图中灰色部分);snake的长度也就snake身体的所占span格子的个数.
因此一条snake具有属性:head(蛇头)、tail(蛇尾)、body(身体)及direction(蛇的前进方向)
snake应该具有的方法为:移动并且找到食物moveAndFindFood(oFood)、判断是否走出了canvas的方法isHitWall(oCanvas)以及在canvas上展示snake的方法draw()
实现如下:
function Snake(head, tail, direction) { this.head = head;// 头 this.tail = tail;// 尾 this.direction = direction;// 方向 this.body = new Array(tail, head);// 按顺序依次存入蛇尾--蛇头 } Snake.prototype.moveAndFindFood = function(oFood) { switch (this.direction) { case "up": this.head -= 20;// 蛇头朝北走20 break; case "down": this.head += 20;// 蛇头朝南走20 break; case "left": this.head -= 1;// 蛇头朝西走20 break; case "right": this.head += 1;// 蛇头朝东走20 break; default: break; } this.body.push(this.head);// 重新设则蛇头位 if (oFood.iNo == this.head) {// 遇到食物 oFood.bEat = true;// 食物已经被吃 } else { this.body.shift();// 移除数组的第一个元素也就是蛇尾 this.tail = this.body[0];// 将数组的第一个元素设置为蛇尾 } }; // 撞墙判断 Snake.prototype.isHitWall = function(oCanvas) { // 小于1或大于400为游戏地图块状区域编号;如果蛇的头部与身体上的其他区域有重复,则说明蛇将自己吃了 if (this.head < 1 || this.head > 400 || this.body.sameItem(this.head) > 1) { return true; } // 蛇头当前位于画布的东边缘上并且蛇头后的位置[body.slice(-2,-1)取数组的倒数第二个元素]也位于画布的西边缘上,在游戏中是不运行的。定义为撞到西墙 if (oCanvas.whichWallForBrick(this.head) == 'E' && oCanvas.whichWallForBrick(this.body.slice(-2, -1)) == 'W') { return true; } // 蛇头当前位于画布的西边缘上并且蛇头后的位置[body.slice(-2,-1)取数组的倒数第二个元素]也位于画布的东边缘上,在游戏中是不运行的。定义为撞到东墙 if (oCanvas.whichWallForBrick(this.head) == 'W' && oCanvas.whichWallForBrick(this.body.slice(-2, -1)) == 'E') { return true; } return false; }; Snake.prototype.draw = function() { for ( var i = 0; i < this.body.length; i++) { if (this.body[i] == this.head) { document.getElementById(this.body[i]).style.background = "green"; } else if (this.body[i] == this.tail) { document.getElementById(this.body[i]).style.background = "gray"; } else { document.getElementById(this.body[i]).style.background = "red"; } } };
Food对象:
图中的黄色即为snake's food;
Food对象很简单具有属性:iNo(食物位置编号)、iRank(食物等级)、bEat(是否被吃掉)及aColor(食物颜色);
方法为:productionFoodForSnake(oSnake)(生产食物)
实现如下:
function Food() { this.iNo; this.iRank = 1;// 食物等级;分四个等级,从小到大0,1,2,3,4 this.bEat = true;// 默认没有食物 this.aColor = new Array("orange", "blue", "red", "#000000"); if (typeof Food.__initialized == "undefined") {// 动态原型方法 // 生产食物 Food.prototype.productionFoodForSnake = function(oSnake) { this.iRank = RandomEventUtils.getIntRandomNumFromOneToN(4); do { this.iNo = RandomEventUtils.getIntRandomNumFromOneToN(20 * 20); // 当该随机数不属于snake's body时跳出循环 } while (oSnake.body.indexOf(this.iNo) != -1); this.bEat = false; document.getElementById(this.iNo).style.background = this.aColor[this.iRank - 1]; }; // 清理剩余食物 Food.__initialized = true; } }
至此,一些基本的准备工作就已经就绪了,下面我们将创建游戏对象,以便控制snake的移动及一些记分工作。javascript 贪吃蛇(二)