功能实现

搭建页面

放一个容器盛放游戏场景 div#map,设置样式

#map {width: 800px;height: 600px;background-color: #ccc;position: relative;
}

分析对象

  • 游戏对象
  • 蛇对象
  • 食物对象

创建食物对象

  • Food

    • 属性

      • x
      • y
      • width
      • height
      • color
    • 方法

      • render 随机创建一个食物对象,并输出到map上
  • 创建Food的构造函数,并设置属性

var position = 'absolute';
var elements = [];
function Food(x, y, width, height, color) {this.x = x || 0;this.y = y || 0;// 食物的宽度和高度(像素)this.width = width || 20;this.height = height || 20;// 食物的颜色this.color = color || 'green';
}
  • 通过原型设置render方法,实现随机产生食物对象,并渲染到map上
Food.prototype.render = function (map) {// 随机食物的位置,map.宽度/food.宽度,总共有多少分food的宽度,随机一下。然后再乘以food的宽度this.x = parseInt(Math.random() * map.offsetWidth / this.width) * this.width;this.y = parseInt(Math.random() * map.offsetHeight / this.height) * this.height;// 动态创建食物对应的divvar div = document.createElement('div');map.appendChild(div);div.style.position = position;div.style.left = this.x + 'px';div.style.top = this.y + 'px';div.style.width = this.width + 'px';div.style.height = this.height + 'px';div.style.backgroundColor = this.color;elements.push(div);
}
  • 通过自调用函数,进行封装,通过window暴露Food对象
window.Food = Food;

创建蛇对象

  • Snake

  • 属性

    • width 蛇节的宽度 默认20
    • height 蛇节的高度 默认20
    • body 数组,蛇的头部和身体,第一个位置是蛇头
    • direction 蛇运动的方向 默认right 可以是 left top bottom
  • 方法

    • render 把蛇渲染到map上
  • Snake构造函数

var position = 'absolute';
var elements = [];
function Snake(width, height, direction) {// 设置每一个蛇节的宽度this.width = width || 20;this.height = height || 20;// 蛇的每一部分, 第一部分是蛇头this.body = [{x: 3, y: 2, color: 'red'},{x: 2, y: 2, color: 'red'},{x: 1, y: 2, color: 'red'}];this.direction = direction || 'right';
}
  • render方法
Snake.prototype.render = function(map) {for(var i = 0; i < this.body.length; i++) {var obj = this.body[i];var div = document.createElement('div');map.appendChild(div);div.style.left = obj.x * this.width + 'px';div.style.top = obj.y * this.height + 'px';div.style.position = position;div.style.backgroundColor = obj.color;div.style.width = this.width + 'px';div.style.height = this.height + 'px';}
}
  • 在自调用函数中暴露Snake对象
window.Snake = Snake;

创建游戏对象

游戏对象,用来管理游戏中的所有对象和开始游戏

  • Game

    • 属性

      • food

      • snake

      • map

    • 方法

      • start 开始游戏(绘制所有游戏对象)
  • 构造函数

function Game(map) {this.food = new Food();this.snake = new Snake();this.map = map;
}
  • 开始游戏,渲染食物对象和蛇对象
Game.prototype.start = function () {this.food.render(this.map);this.snake.render(this.map);
}

游戏的逻辑

写蛇的move方法

  • 在蛇对象(snake.js)中,在Snake的原型上新增move方法
  1. 让蛇移动起来,把蛇身体的每一部分往前移动一下
  2. 蛇头部分根据不同的方向决定 往哪里移动
Snake.prototype.move = function (food, map) {// 让蛇身体的每一部分往前移动一下var i = this.body.length - 1;for(; i > 0; i--) {this.body[i].x = this.body[i - 1].x;this.body[i].y = this.body[i - 1].y;}// 根据移动的方向,决定蛇头如何处理switch(this.direction) {case 'left': this.body[0].x -= 1;break;case 'right':this.body[0].x += 1;break;case 'top':this.body[0].y -= 1;break;case 'bottom':this.body[0].y += 1;break;}
}
  • 在game中测试
this.snake.move(this.food, this.map);
this.snake.render(this.map);

让蛇自己动起来

  • 私有方法

    什么是私有方法?不能被外部访问的方法
    如何创建私有方法?使用自调用函数包裹
    
  • 在game.js中 添加runSnake的私有方法,开启定时器调用蛇的move和render方法,让蛇动起来

  • 判断蛇是否撞墙

function runSnake() {var timerId = setInterval(function() {this.snake.move(this.food, this.map);// 在渲染前,删除之前的蛇this.snake.render(this.map);// 判断蛇是否撞墙var maxX = this.map.offsetWidth / this.snake.width;var maxY = this.map.offsetHeight / this.snake.height;var headX = this.snake.body[0].x;var headY = this.snake.body[0].y;if (headX < 0 || headX >= maxX) {clearInterval(timerId);alert('Game Over');}if (headY < 0 || headY >= maxY) {clearInterval(timerId);alert('Game Over');}}.bind(that), 150);
}
  • 在snake中添加删除蛇的私有方法,在render中调用
function remove() {// 删除渲染的蛇var i = elements.length - 1;for(; i >= 0; i--) {// 删除页面上渲染的蛇elements[i].parentNode.removeChild(elements[i]);// 删除elements数组中的元素elements.splice(i, 1);}
}
  • 在game中通过键盘控制蛇的移动方向
function bindKey() {document.addEventListener('keydown', function(e) {switch (e.keyCode) {case 37:// leftthis.snake.direction = 'left';break;case 38:// topthis.snake.direction = 'top';break;case 39:// rightthis.snake.direction = 'right';break;case 40:// bottomthis.snake.direction = 'bottom';break;}}.bind(that), false);
}
  • 在start方法中调用
bindKey();

判断蛇是否吃到食物

// 在Snake的move方法中// 在移动的过程中判断蛇是否吃到食物
// 如果蛇头和食物的位置重合代表吃到食物
// 食物的坐标是像素,蛇的坐标是几个宽度,进行转换
var headX = this.body[0].x * this.width;
var headY = this.body[0].y * this.height;
if (headX === food.x && headY === food.y) {// 吃到食物,往蛇节的最后加一节var last = this.body[this.body.length - 1];this.body.push({x: last.x,y: last.y,color: last.color})// 把现在的食物对象删除,并重新随机渲染一个食物对象food.render(map);
}

自调用函数的参数

(function (window, undefined) {var document = window.document;}(window, undefined))
  • 传入window对象

将来代码压缩的时候,可以把 function (window) 压缩成 function (w)

  • 传入undefined

在将来会看到别人写的代码中会把undefined作为函数的参数(当前案例没有使用)
因为在有的老版本的浏览器中 undefined可以被重新赋值,防止undefined 被重新赋值

整理代码

现在的代码结构清晰,谁出问题就找到对应的js文件即可。通过自调用函数,已经防止了变量命名污染的问题

但是,由于js文件数较多,需要在页面上引用,会产生文件依赖的问题(先引入那个js,再引入哪个js)
将来通过工具把js文件合并并压缩。现在手工合并js文件演示

  • 问题1
// 如果存在多个自调用函数要用分号分割,否则语法错误
// 下面代码会报错
(function () {}())(function () {}())
// 所以代码规范中会建议在自调用函数之前加上分号
// 下面代码没有问题
;(function () {}());(function () {}())
  • 问题2
// 当自调用函数 前面有函数声明时,会把自调用函数作为参数
// 所以建议自调用函数前,加上;
// 不加; 先执行'22',再执行'11'.  加上; 只执行'22'
var a = function () {alert('11');
};(function () {alert('22');
}())

面向对象游戏案例:贪吃蛇相关推荐

  1. 面向对象编程案例—贪吃蛇小游戏

    1. 搭建页面 放一个容器盛放游戏场景 div#map,设置样式 #map {width: 800px;height: 600px;background-color: #ccc;position: r ...

  2. 面向对象案例——贪吃蛇游戏

    最近项目上线,近一个星期没更博了,今天来写一个经典的游戏案例--贪吃蛇.在这个简单的案例里可以体会javaScript 面向对象开发相关模式,学习使用面向对象的方式分析问题. 1.功能实现 1.1 搭 ...

  3. 贪吃蛇面向对象c语言,面向对象案例——贪吃蛇游戏(示例代码)

    最近项目上线,近一个星期没更博了,今天来写一个经典的游戏案例--贪吃蛇.在这个简单的案例里可以体会javaScript 面向对象开发相关模式,学习使用面向对象的方式分析问题. 1.功能实现 1.1 搭 ...

  4. Web前端学习笔记——JavaScript之面向对象游戏案例:贪吃蛇

    面向对象游戏案例:贪吃蛇 案例相关源码以上传到 GitHub :https://github.com/lipengzhou/new-snake 案例介绍 游戏演示 在线演示地址:贪吃蛇 案例目标 游戏 ...

  5. JavaScript 面向对象游戏案例:贪吃蛇

    面向对象游戏案例:贪吃蛇 案例相关源码以上传到 GitHub :https://github.com/sunna1/snake 案例介绍 案例目标 游戏的目的是用来体会js高级语法的使用 不需要具备抽 ...

  6. canvas游戏篇 - 贪吃蛇

    截图如下: HTML 代码如下: <!DOCTYPE html> <html> <head><meta charset="UTF-8"&g ...

  7. python贪吃蛇源码_Python:游戏:贪吃蛇(附源码)

    Python:游戏:贪吃蛇(附源码) 发布时间:2018-09-05 09:59, 浏览次数:1295 , 标签: Python 贪吃蛇是个非常简单的游戏,适合练手. 首先分析一下这个游戏 1.蛇怎么 ...

  8. cocos creator开发微信小游戏(五)贪吃蛇大作战

    目录 小游戏介绍 小游戏cocos creator场景图 小游戏部分JS代码 开发中碰到的问题 工程及说明 小游戏介绍 贪吃蛇小游戏:贪吃蛇试玩(首次加载比较慢),类似贪吃蛇大作战的小游戏.当玩家的蛇 ...

  9. 贪吃蛇大作战代码java,贪吃蛇游戏,贪吃蛇java游戏代码讲解

    贪吃蛇游戏,贪吃蛇java游戏代码讲解 来源:互联网 作者:佚名 时间:2020-06-06 贪吃蛇源代码.txt这世界上除了我谁都没资格陪在你身边. 听着,我允许你喜欢我.除了白头偕老,我们... ...

  10. Python 游戏:贪吃蛇

    系列文章地址 Python 游戏:贪吃蛇 Python 游戏:扫雷 Python 游戏:300行代码实现俄罗斯方块 Python 游戏:五子棋之人机对战 文章目录 系列文章地址 一.游戏介绍 二.游戏 ...

最新文章

  1. 你是否能判断电机损毁风险?
  2. mysql 导入txt数据到数据表【原创】
  3. PM2.5检测 -- PMS7003 采集和 MQTT 传输
  4. 一篇关于兼容问题的基础总结
  5. 软件测试 -- alpha测试和beta测试的区别
  6. Flash 杂志《summer tree》 第六期发布
  7. java 看书浏览器官_JAVA读取文件流,设置浏览器下载或直接预览操作
  8. Innodb之监控Buffer pool Load progress
  9. sentos7查看网络配置_论各厂商设备之基础常用配置命令集
  10. Jquery 小技巧
  11. matlab编辑rayfile光源文件,rayfile网盘功能详解 rayfile网盘安装步骤及安装注意事项...
  12. laravel 模型里自定义属性_关于Laravel 7 的简单隐式路由模型绑定
  13. ios 从assets加载图片_iOS 使用Assets.xcassets添加启动图和Icon
  14. [转]优化MySQL数据库性能的八大“妙手”
  15. 【转载】六合一调试神器TTL转USB模块
  16. android GPS驱动
  17. 您全面了解“含胸拔背”吗?
  18. 大小写英文字母对应的ASCII值
  19. oracle常用笔记(二)
  20. 【解决方案】element show-password弹框关闭如何将小眼睛还原

热门文章

  1. 一道PL/SQL题:一列数字中随机找出几个使得和等于10
  2. 手机端虚拟键盘弹出使界面布局混乱解决方法
  3. 记录:如何使用java 发送qq邮件
  4. java的下载地址_java资源下载之官网地址
  5. Unix时间戳(Unix timestamp)及其他时间标准
  6. mysql中使用除法
  7. 关于word2016编辑的文本在word2007中打开排版会乱的解决办法
  8. “经济型”Win8.1 4G平板电脑
  9. JAVA 简单的货款计算器
  10. py2exe使用教程(一)——简单的示例