javascript贪吃蛇游戏设计与实现
网络编程 2021-07-04 14:06www.168986.cn编程入门
这篇文章主要为大家详细介绍了javascript贪吃蛇游戏设计与实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文为大家分享了javascript实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下
效果图
设计
贪吃蛇游戏是一款休闲益智类游戏。既简单又耐玩。该游戏通过控制蛇头方向吃蛋,从而使得蛇变得越来越长。
玩法
点击屏幕控制蛇的移动方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,游戏胜利。
设计
需要创建一个棋盘,然后需要生成一条贪吃蛇,接着随机生成食物。每当蛇吃到食物的时候,随机生成新的食物,蛇头吃到自己的身体的时候游戏结束。
棋盘设计
元素 行数,列数,基础细胞(可表现为空,食物,蛇身体);
属性 创建棋盘,清空棋盘;
基础细胞设计
属性 重设颜色,重设大小;
食物
需求 需要在棋盘剩余空白位置随机位置生成食物;
贪吃蛇
元素 位置集合(数组),移动速率,移动方向
需求 初始随机生成只有一节的贪吃蛇,定时器函数(根据移动方向求得下一个要移动到的位置,需要注意的是到达边界后进行特殊处理。判断下个位置是否为蛇本身,如果是蛇就吃到自己,游戏结束。接着将下个位置添加到蛇位置集合内,判断下个位置 是否与食物相同,如果相同,则重现生成新的食物,否则移除蛇尾)。
方向控制
本游戏使用点击屏幕,控制蛇移动方向。
实现
cell.js
/ @Author: ls @Date: 2020-09-01 18:23:09 @LastEditTime: 2020-09-16 14:23:37 @LastEditors: Please set LastEditors @Description: 基础细胞类 @FilePath: \snake\assets\cell.js / .Class({ extends: .Component, properties: {}, onLoad() {}, / @param {} cellColor / setCellColor(cellColor = new .color(255, 255, 255, 255)) { this.node.getChildByName('color').color = cellColor; }, / @param {} cellSize / setCellPos(cellSize = new .v2(20, 20)) { this.node.width = cellSize.x; this.node.height = cellSize.y; }, });
guideCtrl.js
/ @Author: ls @Date: 2020-09-03 18:09:18 @LastEditTime: 2020-09-14 08:55:47 @LastEditors: Please set LastEditors @Description: 引导类 @FilePath: \snake\assets\guideCtrl.js / .Class({ extends: .Component, properties: { step: [.Node], startToggle: .Toggle, }, onLoad() { this.startGuide(); this.startToggle.isChecked = false; }, / 开始引导 / startGuide() { if (!this.step.length) { this.node.destroy(); return; } for (let index = 0, length = this.step.length; index < length; index++) { this.step[index].active = false; } this._step = 0; this.step[0].active = true; }, / 下一个引导页面 / nextGuide() { this._step++; if (this._step < this.step.length - 1) { this.step[this._step].active = true; this.step[this._step - 1].active = false; if (this._step === this.step.length - 2) { this.step[this._step + 1].active = true; } } else { this.node.active = false; } }, callback: function (toggle) { .sys.localStorage.setItem('isStart', toggle.isChecked); }, });
gameCtrl.js
/ @Author: ls @Date: 2020-09-01 15:44:33 @LastEditTime: 2020-09-16 14:23:18 @LastEditors: Please set LastEditors @Description: 游戏导演类 @FilePath: \snake\assets\gameController.js / var noneColor = new .color(120, 120, 120, 255); var foodColor = new .color(254, 168, 23, 255); var snakeColor = new .color(243, 60, 66, 255); .Class({ extends: .Component, properties: { // 棋盘 node_grid: .Node, // 分数 lab_score: .Label, // 最好分数 lab_best: .Label, // 开始 node_start: .Node, // 新人引导 node_guide: .Node, // 结束 node_over: .Node, // 基础类 cellPrefab: .Prefab, // 移动速度 mSpeed: 5, // 列数 colCount: 30, // 行数 rowCount: 30, }, onLoad() { // 初始化方向 // 静止、上、下、左、右 // (0,0)、(0,1)、(0,-1)、(-1,0)、(1,0) this._direction = { x: 0, y: 0 }; // 初始化细胞大小 this._cellSize = { x: 10, y: 10 }; this._map = []; this.initCellPool(); this.onCreateMap(); // 显示开始游戏界面 this.showStartGame(); }, / 初始化细胞对象池 / initCellPool() { this.cellPool = new .NodePool(); let initCount = this.rowCount this.colCount; for (let i = 0; i < initCount; i++) { let cell = .instantiate(this.cellPrefab); // 创建节点 this.cellPool.put(cell); // 通过 put 接口放入对象池 } }, / 创建地图 / onCreateMap() { this._map = []; let node_bg = this.node_grid.getChildByName('background'); this._cellSize = { x: node_bg.width / this.rowCount, y: node_bg.height / this.colCount }; for (var y = 0; y < this.colCount; y++) { for (let x = 0; x < this.rowCount; x++) { var obj = {}; obj.x = x; obj.y = y; obj.node = this.createCell(node_bg, x, y); this._map.push(obj); } } }, / 从对象池请求对象 @param {} parentNode / createCell: function (parentNode, x, y) { let cell = null; if (this.cellPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象 cell = this.cellPool.get(); } else { // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 .instantiate 重新创建 cell = .instantiate(this.cellPrefab); } cell.getComponent('cell').setCellPos(this._cellSize); cell.x = this._cellSize.x x; cell.y = this._cellSize.y y; cell.parent = parentNode; return cell; }, / 还原地图 / clearMap() { for (let index = 0, length = this._map.length; index < length; index++) { this._map[index].node.getComponent('cell').setCellColor(noneColor); } }, / 显示开始界面 / showStartGame() { this.node_over.active = false; this.node_start.active = true; }, / 显示结束界面 / showOverGame() { this.node_start.active = false; this.node_over.active = true; }, / 游戏开始 / startGame() { this.node_guide.active = false; this.node_over.active = false; this.node_start.active = false; this.lab_score.node.active = true; this.lab_best.node.active = true; this.node_grid.active = true; // 是否进入界面 if (!.sys.localStorage.getItem('isStart')) { this.node_guide.active = true; } this._score = 0; // 更新最高分数 this.updateBest(); this._canControl = true; this._direction = { x: 1, y: 0 }; this._snakeGrid = []; this._foodGrid = {}; // 初始化触摸事件 this.openTouchEvent(); this.clearMap(); this.onCreateSnake(); this.onCreateFood(); // 开启移动 this.schedule(this.move, 1 / this.mSpeed); }, / 更新分数 / updateBest() { this._best = .sys.localStorage.getItem('best'); if (this._best) { if (this._best < this._score) { this._best = this._score; .sys.localStorage.setItem('best', this._best); } } else { this._best = this._score; .sys.localStorage.setItem('best', this._best); } this.lab_best.string = this._best; }, / 游戏结束 / gameOver() { // 是否能控制 蛇改变移动方向 this._canControl = false; this.unschedule(this.move); this.closeTouchEvent(); this.clearMap(); this.showOverGame(); }, / 创建蛇 / onCreateSnake() { let x = ~~(Math.random() this.rowCount); let y = ~~(Math.random() this.colCount); for (let index = 0, length = this._map.length; index < length; index++) { if (this._map[index].x === x && this._map[index].y === y) { this._map[index].node.getComponent('cell').setCellColor(snakeColor); this._snakeGrid.push(this._map[index]); } } }, / 创建食物 / onCreateFood() { if (this._map.length !== this._snakeGrid.length) { let r = ~~(Math.random() (this._map.length - this._snakeGrid.length)); let subGrid = []; for (let i = 0; i < this._map.length; i++) { subGrid.push(this._map[i]); } for (let m = 0; m < subGrid.length; m++) { for (let n = 0; n < this._snakeGrid.length; n++) { if (subGrid[m].x === this._snakeGrid[n].x && subGrid[m].y === this._snakeGrid[n].y) { subGrid.splice(m, 1); if (m > 0) { m--; } } } } for (let index = 0; index < subGrid.length; index++) { if (index === r) { this._foodGrid = subGrid[index]; this._foodGrid.node.getComponent('cell').setCellColor(foodColor); // 增加分数 this._score++; this.lab_score.string = this._score; } } } }, / 打开触摸 / openTouchEvent() { var self = this; this.node.on( .Node.EventType.TOUCH_START, function (touch) { if (self._canControl) { self._canControl = false; let touchPos = self.node.convertToNodeSpaceAR(touch.getLocation()); self._direction = self.getTouchDirection(touchPos); this.scheduleOnce(function () { self._canControl = true; }, 1 / this.mSpeed); } }, this ); }, / 关闭触摸 / closeTouchEvent() { this.node.off(.Node.EventType.TOUCH_START, this); }, / 获取选择的方向 @param { 触摸位置} touchPos / getTouchDirection(touchPos) { // 获取向量长度 function getABS(pos) { return Math.sqrt(pos.x pos.x + pos.y pos.y); } // 获取横向 方向 function getLandscape(touchPos) { if (touchPos.x > 0) { .log('更改为 向 右 移动'); return { x: 1, y: 0 }; } else { .log('更改为 向 左 移动'); return { x: -1, y: 0 }; } } // 获取竖向 方向 function getPortrait(touchPos) { if (touchPos.y > 0) { .log('更改为 向 上 移动'); return { x: 0, y: 1 }; } else { .log('更改为 向 下 移动'); return { x: 0, y: -1 }; } } if (getABS(this._direction) === 1) { .log('蛇 正在移动'); if (this._direction.y === 1) { .log('蛇 正在向 上 移动'); return getLandscape(touchPos); } else if (this._direction.y === -1) { .log('蛇 正在向 下 移动'); return getLandscape(touchPos); } else if (this._direction.x === -1) { .log('蛇 正在向 左 移动'); return getPortrait(touchPos); } else if (this._direction.x === 1) { .log('蛇 正在向 右 移动'); return getPortrait(touchPos); } } else { .log('蛇 未开始 或 停止了移动。此时修改方向无效!'); } }, / 移动 / move() { let nextGrid = {}; nextGrid.x = this._snakeGrid[this._snakeGrid.length - 1].x + this._direction.x; nextGrid.y = this._snakeGrid[this._snakeGrid.length - 1].y + this._direction.y; if (this._direction.x === 1) { // 向右 if (nextGrid.x > this.colCount - 1) { nextGrid.x = 0; } } else if (this._direction.x === -1) { // 向左 if (nextGrid.x < 0) { nextGrid.x = this.colCount - 1; } } else if (this._direction.y === 1) { // 向上 if (nextGrid.y > this.rowCount - 1) { nextGrid.y = 0; } } else if (this._direction.y === -1) { // 向下 if (nextGrid.y < 0) { nextGrid.y = this.rowCount - 1; } } for (let m = 0, l = this._map.length; m < l; m++) { if (this._map[m].x === nextGrid.x && this._map[m].y === nextGrid.y) { nextGrid = this._map[m]; } } for (let n = 0, length = this._snakeGrid.length; n < length; n++) { if (nextGrid.x === this._snakeGrid[n].x && nextGrid.y === this._snakeGrid[n].y) { this.gameOver(); // return false; } } nextGrid.node.getComponent('cell').setCellColor(snakeColor); this._snakeGrid.push(nextGrid); if (nextGrid.x === this._foodGrid.x && nextGrid.y === this._foodGrid.y) { this.onCreateFood(); } else { let startGrid = this._snakeGrid.shift(); startGrid.node.getComponent('cell').setCellColor(noneColor); } }, });
完整代码
更多有趣的经典小游戏实现专题,分享给大家
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持狼蚁SEO。
上一篇:JavaScript 闭包的使用场景
下一篇:js实现简单的随机点名器
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程