js实现简单贪吃蛇游戏

时间:2021-05-26

本文实例为大家分享了js实现简单贪吃蛇游戏的具体代码,供大家参考,具体内容如下

上下左右键控制方向使贪吃蛇吃葡萄
吃5个葡萄,游戏结束时左上角为总得分。

运行结果:

界面和css代码这里就不加赘述了,主要贴js代码(加了注释):

var config = { width: 20, //一个格子的宽度 height: 20, //一个格子的高度 tr: 30, //行数 td: 30 //列数}var snake = null, //Snake的实例 food = null, //Food的实例 game = null; //游戏的实例//我们把蛇移动的整个区域设置成一个具有30列30行的网格坐标//方块(格子)坐标位置/**0,0 (0,0)20,0 (1,0)40,0 (2,0)*/function Square(x, y, className) { this.x = x*config.width; this.y = y*config.height; this.className = className; this.contentDom = document.createElement('div');//该位置的方块对应的DOM元素 this.contentDom.className = this.className; this.parent = document.getElementsByClassName("innerSnake")[0];}Square.prototype.create = function() { //创建方块并添加到页面 this.contentDom.style.position = 'absolute'; this.contentDom.style.width = config.width + 'px'; this.contentDom.style.height = config.height + 'px'; this.contentDom.style.left = this.x + 'px'; this.contentDom.style.top = this.y + 'px'; this.parent.appendChild(this.contentDom);};Square.prototype.remove = function() { //移除方块 this.parent.removeChild(this.contentDom);};//蛇function Snake() { this.head = null; //蛇头 this.tail = null; //蛇尾 this.pos = []; //二维数组,存储蛇身上每个节点(方块) this.directionKey = { //存储蛇走的方向 left: { //往左走 x: -1, //横坐标减1,一个坐标表示一个格子 y: 0, //纵坐标不变 rotate: 90 }, right: { //往右走 x: 1, y: 0, rotate: -90 }, up: { //往上走 x: 0, y: -1, rotate: 180 }, down: { //往下走 x: 0, y: 1, rotate: 0 //蛇头图片方向,顺时针为正 } }}Snake.prototype.init = function() { //初始化蛇 //蛇头 var snakeHead = new Square(2,0,"head"); snakeHead.create(); //将蛇头添加到界面 this.head = snakeHead; //存储蛇头信息 this.pos.push([2,0]); //存储蛇头坐标 //蛇的第1节身体 var snakeBody1 = new Square(1,0,"body"); snakeBody1.create(); //将蛇的第一节身体添加到界面 this.pos.push([1,0]); //蛇的尾巴 var snakeTail = new Square(0,0,"body"); snakeTail.create(); //将蛇尾添加到界面 this.tail = snakeTail; //存储蛇尾信息 this.pos.push([0,0]); //形成链表关系 snakeHead.prev = null; //蛇头的前面没有元素,指向null snakeHead.next = snakeBody1; //蛇头的后面有一节身体,其.next指针指向后面那节身体 snakeBody1.prev = snakeHead; //蛇的第一节身体,.prev指向前面的蛇头snakeHead snakeBody1.next = snakeTail; //蛇的第一节身体,.next指向后面的身体,此时是蛇尾snakeTail snakeTail.prev = snakeBody1; //蛇尾,.prev指向前面的蛇身体snakeBody1 snakeTail.next = null; //蛇尾后面没有元素,指向Null //初始蛇的走向,后面想改变蛇的走向即改变this.direction this.direction = this.directionKey.right; //默认向右走};//获取蛇头下一个位置对应的元素,根据元素做下一个动作Snake.prototype.getNextPos = function() { var nextPos = [ //获取蛇头走的下一个点的坐标 this.head.x / config.width + this.direction.x, this.head.y / config.height + this.direction.y ]; //判断下一个点是自己or食物or围墙or无障碍? var self = false; //设置下一个点是否是自己 this.pos.forEach(function(val) { //val即二位数组中的一个坐标 if(val.toString() === nextPos.toString()) { //下一个坐标等于蛇全部身体的一个,即下一个点是自己 self = true; } }); if(self) { // console.log('撞到自己了!'); this.collide.end.call(this); //game over return; } else if(nextPos[0] < 0 || nextPos[1] < 0 || nextPos[0] > config.td-1 || nextPos[1] > config.tr-1) { // console.log('撞到墙壁了!'); this.collide.end.call(this); //game over return; } else if (food && food.pos[0] === nextPos[0] && food.pos[1] === nextPos[1]) { console.log('撞到食物了!'); this.collide.eat.call(this); } else { // console.log('啥都没遇到!'); this.collide.move.call(this, false); //注意:.call(this)重新设置this指向,使其指向当前实例对象Snake } };//处理碰撞后的事件Snake.prototype.collide = { move: function(isEat) { //isEat 是否吃了食物,不是则删除蛇尾 var x = this.head.x / config.width + this.direction.x, y = this.head.y / config.height + this.direction.y; //声明一个新身体 var newBody = new Square(this.head.x/config.width, this.head.y/config.height, "body"); //更新链表关系 newBody.next = this.head.next; newBody.next.prev = newBody; newBody.prev = null; this.head.remove(); //删除旧蛇头 newBody.create(); //添加蛇身体,替代在旧蛇头位置 //声明一个新蛇头(下一个走的点) var newHead = new Square(x, y, "head"); //更新链表关系 newHead.prev = null; newHead.next = newBody; newBody.prev = newHead; this.pos.unshift([x, y]); //更新蛇节点的坐标this.pos this.head = newHead; //更新this.head的信息 newHead.contentDom.style.transform = `rotate(${this.direction.rotate}deg)` newHead.create(); //添加蛇头 //删除蛇尾:吃食物则不删 if(!isEat) { //没有吃食物,删除蛇尾 this.tail.remove(); this.tail = this.tail.prev; this.pos.pop(); //更新蛇节点坐标 } // console.log(this.pos); //打印数组,验证 }, eat: function() { this.collide.move.call(this, true); //传参true,表示此时为吃操作 food.remove(); //删除被吃掉的食物 game.score ++; //记录分数 createFood(); //此时再随机产生一个食物 }, end: function() { console.log('end'); game.gameOver(); }}snake = new Snake();//创建食物function createFood() { var x = null, y = null; var include = true; //表示食物的位置是否在蛇身上 var random = function(max, min) { //产生一个随机数 return Math.floor(Math.random()*(max - min + 1)) }; while(include) { x = random(config.tr - 1, 0); y = random(config.td - 1, 0); snake.pos.forEach(function(val) { if(x != val[0] && y != val[1]) { include = false; } }); } //生成食物 food = new Square(x, y, "food"); food.pos = [x, y]; //记录食物坐标 food.create();}//游戏逻辑function Game() { this.score = 0; //分数 this.timer = null; //计时器}Game.prototype.init = function() { snake.init(); // snake.getNextPos(); //获取下一个点坐标 createFood(); document.onkeydown = function(event) { if(event.which == 37 && snake.direction != snake.directionKey.right) { //鼠标左键,蛇不能是正在往右走 snake.direction = snake.directionKey.left; } else if (event.which == 38 && snake.direction != snake.directionKey.down) { //鼠标上键 snake.direction = snake.directionKey.up; } else if (event.which == 39 && snake.direction != snake.directionKey.left) { //鼠标右键 snake.direction = snake.directionKey.right; } else if (event.which == 40 && snake.direction != snake.directionKey.up) { //鼠标下键 snake.direction = snake.directionKey.down; } } this.start();};game = new Game();//开始游戏Game.prototype.start = function() { this.timer = setInterval(function() { snake.getNextPos(); //获取下一个坐标点,做下一步动作 }, 200);};//游戏结束Game.prototype.gameOver = function() { console.log("gameOver"); clearInterval(this.timer); var gameOver = document.querySelector('.gameOver'); var gameScore = document.querySelector('.gameOver .score'); gameOver.style.display = 'block'; //显示游戏结束界面 gameScore.innerHTML = `${this.score}`; //将分数记入该界面};//开启游戏function startGame() { var startBtn = document.querySelector('.btn button'); var snakeWrap = document.querySelector('.snakeWrap'); startBtn.onclick = function() { startBtn.parentNode.style.display = 'none'; //隐藏开始游戏界面 snakeWrap.style.display = 'block'; //显示进入游戏的界面 game.init(); }}startGame();

主要用到链表数据结构

更多有趣的经典小游戏实现专题,也分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

java经典小游戏汇总

javascript经典小游戏汇总

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章