jQuery实现贪吃蛇小游戏(附源码下载)(2)

function Food(){ this.pos = null; // 随机产生Food坐标点,避开蛇身 this.Create = function(){ if(this.pos){ this.handleDot(false, this.pos, 'food'); } let isOk = true; while(isOk){ let x = parseInt(Math.random()*settings.pannelSize), y = parseInt(Math.random()*settings.pannelSize); if(!$('.td_'+x+'_'+y).hasClass('body')){ isOk = false; let pos = new Position(x, y); this.handleDot(true, pos, 'food'); this.pos = pos; } } }; // 画点 this.handleDot = function(flag, dot, className){ if(flag){ $('.td_'+dot.X+'_'+dot.Y).addClass(className); } else { $('.td_'+dot.X+'_'+dot.Y).removeClass(className); } }; }

既然食物有了坐标点这个属性,那么我们什么时候给他赋值呢?我们知道Food是随机产生的,因此我们定义了一个Create函数用来产生Food的坐标点。但是产生的坐标点又不能在蛇的身体上,所以通过一个while循环来产生坐标点,如果坐标点正确了,就终止循环。此外为了方便我们统一处理坐标点的样式,因此定义了一个handleDot函数。

主咖–蛇

终于到了我们的主咖,蛇。首先定义一下蛇基本的属性,最重要的肯定是蛇的body属性,每次移动时,都需要对这个数组进行一些操作。其次是蛇的方向,我们给它一个默认向下的方向。然后是食物,在蛇的构造函数中我们传入食物对象,在后续移动时需要判断是否吃到食物。

function Snake(myFood){ // 蛇的身体 this.body = []; // 蛇的方向 this.dir = Direction.DOWN; // 蛇的食物 this.food = myFood; // 创造蛇身 this.Create = function(){ let isOk = true; while(isOk){ let x = parseInt(Math.random()*(settings.pannelSize-2))+1, y = parseInt(Math.random()*(settings.pannelSize-2))+1; console.log(x,y) if(!$('.td_'+x+'_'+y).hasClass('food')){ isOk = false; let pos = new Position(x, y); this.handleDot(true, pos, 'body') this.body.push(pos); } } }; this.handleDot = function(flag, dot, className){ if(flag){ $('.td_'+dot.X+'_'+dot.Y).addClass(className); } else { $('.td_'+dot.X+'_'+dot.Y).removeClass(className); } }; }

移动函数处理

下面对蛇移动的过程进行处理,由于我们每次都采用添头去尾的方式移动,因此我们每次只需要关注蛇的头和尾。我们约定数组的第一个元素是头,最后一个元素是尾。

this.Move = function(){ let oldHead = Object.assign(new Position(), this.body[0]), oldTail = Object.assign(new Position(), this.body[this.body.length - 1]), newHead = Object.assign(new Position(), oldHead); switch(this.dir){ case Direction.UP: newHead.X = newHead.X - 1; break; case Direction.DOWN: newHead.X = newHead.X + 1; break; case Direction.LEFT: newHead.Y = newHead.Y - 1; break; case Direction.RIGHT: newHead.Y = newHead.Y + 1; break; default: break; } // 数组添头 this.body.unshift(newHead); // 数组去尾 this.body.pop(); };

检测函数处理

这样我们对蛇身数组就处理完了。但是我们还需要对新的头(newHead)进行一些碰撞检测,判断新头部的位置上是否有其他东西(碰撞检测)。

// 食物检测 this.eatFood = function(){ let newHead = this.body[0]; if(newHead.X == this.food.pos.X&&newHead.Y == this.food.pos.Y){ return true; } else { return false; } }; // 边界检测 this.konckWall = function(){ let newHead = this.body[0]; if(newHead.X == -1 || newHead.Y == -1 || newHead.X == settings.pannelSize || newHead.Y == settings.pannelSize ){ return true; } else { return false; } }; // 蛇身检测 this.konckBody = function(){ let newHead = this.body[0], flag = false; this.body.map(function(elem, index){ if(index == 0) return; if(elem.X == newHead.X && elem.Y == newHead.Y){ flag = true; } }); return flag; };

重新绘制

因此我们需要对Move函数进行一些扩充:

this.Move = function(){ // ...数组操作 if(this.eatFood()){ this.body.push(oldTail); this.food.Create(); this.rePaint(true, newHead, oldTail); } else if(this.konckWall() || this.konckBody()) { this.Over(); } else { this.rePaint(false, newHead, oldTail); } }; this.Over = function(){ clearInterval(settings.workThread); console.log('Game Over'); }; this.rePaint = function(isEatFood, newHead, oldTail){ if(isEatFood){ // 加头 this.handleDot(true, newHead, 'body'); } else { // 加头 this.handleDot(true, newHead, 'body'); // 去尾 this.handleDot(false, oldTail, 'body'); } };

因为在Move函数处理数组的后我们的蛇身还没有重新绘制,因此我们很巧妙地判断如果是吃到食物的情况,在数组中就把原来的尾部添加上,这样就达到了吃食物的效果。同时我们定义一个rePaint函数进行页面的重绘。

jQuery实现贪吃蛇小游戏(附源码下载)

游戏控制器

我们的“幕布”、“演员”和“动作指导”都已经到位,那么,我们现在就需要一个“摄影机”进行拍摄,让它们都开始“干活”。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzwpz.html