相思资源网 Design By www.200059.com

本文为大家分享了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
 */

cc.Class({
 extends: cc.Component,

 properties: {},

 onLoad() {},

 /**
 * @param {*} cellColor
 */
 setCellColor(cellColor = new cc.color(255, 255, 255, 255)) {
 this.node.getChildByName('color').color = cellColor;
 },

 /**
 * @param {*} cellSize
 */
 setCellPos(cellSize = new cc.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
 */

cc.Class({
 extends: cc.Component,

 properties: {
 step: [cc.Node],
 startToggle: cc.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) {
 cc.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 cc.color(120, 120, 120, 255);
var foodColor = new cc.color(254, 168, 23, 255);
var snakeColor = new cc.color(243, 60, 66, 255);

cc.Class({
 extends: cc.Component,

 properties: {
 // 棋盘
 node_grid: cc.Node,
 // 分数
 lab_score: cc.Label,
 // 最好分数
 lab_best: cc.Label,

 // 开始
 node_start: cc.Node,
 // 新人引导
 node_guide: cc.Node,
 // 结束
 node_over: cc.Node,

 // 基础类
 cellPrefab: cc.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 cc.NodePool();
 let initCount = this.rowCount * this.colCount;
 for (let i = 0; i < initCount; i++) {
 let cell = cc.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 {
 // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
 cell = cc.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 (!cc.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 = cc.sys.localStorage.getItem('best');
 if (this._best) {
 if (this._best < this._score) {
 this._best = this._score;
 cc.sys.localStorage.setItem('best', this._best);
 }
 } else {
 this._best = this._score;
 cc.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(
 cc.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(cc.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) {
 cc.log('更改为 向 右 移动');
 return { x: 1, y: 0 };
 } else {
 cc.log('更改为 向 左 移动');
 return { x: -1, y: 0 };
 }
 }
 // 获取竖向 方向
 function getPortrait(touchPos) {
 if (touchPos.y > 0) {
 cc.log('更改为 向 上 移动');
 return { x: 0, y: 1 };
 } else {
 cc.log('更改为 向 下 移动');
 return { x: 0, y: -1 };
 }
 }

 if (getABS(this._direction) === 1) {
 cc.log('蛇 正在移动');
 if (this._direction.y === 1) {
 cc.log('蛇 正在向 上 移动');
 return getLandscape(touchPos);
 } else if (this._direction.y === -1) {
 cc.log('蛇 正在向 下 移动');
 return getLandscape(touchPos);
 } else if (this._direction.x === -1) {
 cc.log('蛇 正在向 左 移动');
 return getPortrait(touchPos);
 } else if (this._direction.x === 1) {
 cc.log('蛇 正在向 右 移动');
 return getPortrait(touchPos);
 }
 } else {
 cc.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);
 }
 },
});

完整代码:js贪吃蛇游戏

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

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

java经典小游戏汇总

javascript经典小游戏汇总

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

标签:
js,贪吃蛇

相思资源网 Design By www.200059.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
相思资源网 Design By www.200059.com

评论“javascript贪吃蛇游戏设计与实现”

暂无javascript贪吃蛇游戏设计与实现的评论...

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?