完整项目下载

运行结果


知识点

  1. 利用面向对象的思想实现——一个食物对象、一个蛇对象、一个游戏总控对象。
  2. 在使用××.prototype= {}重写原型对象的时候,一定要加上一句constructor:该对象。不然会造成实例化出来的实例的constructor为object。
    Food.prototype = {constructor: Food,
    };
    
  3. 在underscore中,使用_.random(a,b)即可获得a-b中的一个随机数。
  4. 在求食物的随机位置的时候,用到了panel.clientHeight/this.height - 1) * this.height。
    原理是使用盒子的高度/小球的高度,可以算得最多放多少个小球。因为要控制小球不能超过边界,所以总数量要减去1,数量×高度即为随机位置的最大值。
  5. 在蛇对象中,用body数组存放蛇身体每一个部分对象。蛇的绘制过程就是遍历body,在面板上绘制。
  6. 蛇的移动分为两部分。
    ① 蛇节移动到前一个蛇节的位置。直到蛇头后一个蛇节移动到蛇头的位置。
    ② 根据direction判断蛇头如何移动。
    注意:在游戏绘制的过程中,界面的每一次绘制都要删除之前的绘制,不然会叠加到一起。
  7. 在蛇的闭包中建一个局部数组,存储蛇对象,可以更加方便的删除操作。
  8. 只有在原型对象中的方法和属性,外界是可以调用的。
  9. 蛇的移动(动画)必然需要定时器协助。定时器的时间,即象征着刷新速度,也就是难度。
  10. this所在的函数在哪一个对象中,this就指向谁。单独写一个函数的时候,如果调用之前对象的this,需要备份指针(将对象的this赋值给另一个变量)。
  11. JavaScript原生的键盘按下事件(keydown) 中,事件有一个keyCode属性,其值代表按下的键。其中:37—left、38—top、39—right、40—bottom。
  12. 边界控制。通过判断蛇头与最大X和Y的关系,判断是否碰到边界。
  13. confirm()方法用于显示一个带有指定消息和确认及取消按钮的对话框。
  14. window.location.reload(); 重新加载当前文档
  15. window.close() 方法用于关闭浏览器窗口。
  16. 与食物的碰撞检测:如果蛇头和食物坐标重叠,将蛇尾添加到body中。并重新绘制一个食物点,将之前的食物删掉。

代码

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title></title><style>#panel {width: 800px;height: 600px;background: skyblue;position: relative;margin: 60px auto;border-radius: 10px;border: 5px solid orange;overflow: hidden;}</style>
</head>
<body><div id="panel"></div>
<script src="js/UnderScore.js"></script>
<script src="js/Foods.js"></script>
<script src="js/Snake.js"></script>
<script src="js/Game.js"></script>
<script>var panel = document.getElementById('panel');var game = new Game(panel);game.render();game.run();
</script>
</body>
</html>

Food.js

(function (window) {// 全局指针var self; // 记录当前游戏对象/*** 构造函数-游戏* @param panel* @constructor*/function Game(panel) {this.food = new Food({});this.snake = new Snake({});this.panel = panel;// 赋值self = this;}Game.prototype = {constructor: Game,/*** 初始化*/render: function () {// 1.把蛇和食物对象,渲染到面板上this.food.render(this.panel);this.snake.render(this.panel);},run: function () {// 1.蛇跑起来snakeMove();// 2.方向控制dirControl();}};/*** 蛇开始移动*/function snakeMove() {var timerId = setInterval(function () {// 1. 蛇开始移动和绘制self.snake.move(self.food, self.panel);self.snake.render(self.panel);// 2. 边界控制var maxX = self.panel.clientWidth / self.snake.width;var maxY = self.panel.clientHeight / self.snake.height;var headX = self.snake.body[0].x;var headY = self.snake.body[0].y;console.log(self.panel.clientWidth, self.snake.width, self.snake.body[0].x);// 2.1 水平方向控制if (headX < 0 || headX >= maxX) {clearInterval(timerId);if(confirm('很遗憾,您输了!再来一次?')){window.location.reload();}else {window.close();}}// 2.2 垂直方向控制if (headY < 0 || headY >= maxY) {clearInterval(timerId);if(confirm('很遗憾,您输了!再来一次?')){window.location.reload();}else {window.close();}}}, 100);}/*** 方向控制*/function dirControl() {document.addEventListener('keydown', function (e) {console.log(e['keyCode']);/*37 - left38 - top39 - right40 - bottom*/switch (e['keyCode']) {case 37:self.snake.direction = 'left';break;case 38:self.snake.direction = 'top';break;case 39:self.snake.direction = 'right';break;case 40:self.snake.direction = 'bottom';break;}}, false);}window.Game = Game;
})(window);

Snake.js

(function (window) {// 食物数组var snakeArr = [];var remove = function() {for (var i = snakeArr.length - 1; i >= 0; i--) {// 1.删除divsnakeArr[i].remove();// 2.删除数组中的元素snakeArr.splice(i, 1);}};/*** 构造函数-蛇* @param {Object}options* @constructor*/function Snake(options) {options = options || {};// 1.蛇节的大小this.width = options.width || 20;this.height = options.height || 20;// 2.蛇移动的方向this.direction = options.direction || 'right';// 3.蛇的身体和蛇头 (坐标基数、颜色)this.body = [{x: 2, y: 0, color: 'purple'},{x: 1, y: 0, color: 'red'},{x: 0, y: 0, color: 'red'}];}Snake.prototype = {constructor: Snake,/*** 绘制小蛇*/render: function (panel) {// 1. 先删除remove();// 2. 把每一个蛇节渲染到地图上for (var i = 0, len = this.body.length; i < len; i++) {// 蛇节var object = this.body[i];var div = document.createElement('div');// 设置样式div.style.position = 'absolute';div.style.width = this.width + 'px';div.style.height = this.height + 'px';div.style.left = object.x * this.width + 'px';div.style.top = object.y * this.height + 'px';div.style.borderRadius = this.width / 2 + 'px';div.style.backgroundColor = object.color;panel.appendChild(div);// 记录当前蛇snakeArr.push(div);}},/*** 移动小蛇*/move: function (food, panel) {// 1. 控制蛇的身体移动(当前蛇节 到 上一个蛇节的位置)for (var i = this.body.length - 1; i > 0; i--) {this.body[i].x = this.body[i - 1].x;this.body[i].y = this.body[i - 1].y;}// 2. 控制蛇头的移动// 2.1 判断蛇移动的方向var head = this.body[0];switch(this.direction) {case 'right':head.x += 1;break;case 'left':head.x -= 1;break;case 'top':head.y -= 1;break;case 'bottom':head.y += 1;break;}// 3. 判断蛇头是否和食物的坐标重合var headX = head.x * this.width;var headY = head.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});// 4. 随机在面板上重新生成食物food.render(panel);}}};// 暴露构造函数给外部window.Snake = Snake;
})(window);

Game.js

(function (window) {// 全局指针var self; // 记录当前游戏对象/*** 构造函数-游戏* @param panel* @constructor*/function Game(panel) {this.food = new Food({});this.snake = new Snake({});this.panel = panel;// 赋值self = this;}Game.prototype = {constructor: Game,/*** 初始化*/render: function () {// 1.把蛇和食物对象,渲染到面板上this.food.render(this.panel);this.snake.render(this.panel);},run: function () {// 1.蛇跑起来snakeMove();// 2.方向控制dirControl();}};/*** 蛇开始移动*/function snakeMove() {var timerId = setInterval(function () {// 1. 蛇开始移动和绘制self.snake.move(self.food, self.panel);self.snake.render(self.panel);// 2. 边界控制var maxX = self.panel.clientWidth / self.snake.width;var maxY = self.panel.clientHeight / self.snake.height;var headX = self.snake.body[0].x;var headY = self.snake.body[0].y;console.log(self.panel.clientWidth, self.snake.width, self.snake.body[0].x);// 2.1 水平方向控制if (headX < 0 || headX >= maxX) {clearInterval(timerId);if(confirm('很遗憾,您输了!再来一次?')){window.location.reload();}else {window.close();}}// 2.2 垂直方向控制if (headY < 0 || headY >= maxY) {clearInterval(timerId);if(confirm('很遗憾,您输了!再来一次?')){window.location.reload();}else {window.close();}}}, 100);}/*** 方向控制*/function dirControl() {document.addEventListener('keydown', function (e) {console.log(e['keyCode']);/*37 - left38 - top39 - right40 - bottom*/switch (e['keyCode']) {case 37:self.snake.direction = 'left';break;case 38:self.snake.direction = 'top';break;case 39:self.snake.direction = 'right';break;case 40:self.snake.direction = 'bottom';break;}}, false);}window.Game = Game;
})(window);

实战JavaScript:实现贪吃蛇——面向对象练习相关推荐

  1. 原生JavaScript抒写——贪吃蛇小游戏

    原生JavaScript抒写--贪吃蛇小游戏 文章目录 原生JavaScript抒写--贪吃蛇小游戏 前言 一.需求分析 二.效果展示 三.具体逻辑代码分析 1.首先创建一个html文件,然后我们利用 ...

  2. 用JavaScript实现贪吃蛇游戏_艾孜尔江撰

    <!DOCTYPE html> <html><head><meta charset="utf-8" /><title>J ...

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

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

  4. javascript写贪吃蛇

    在简书上看到大白有褶子写的贪吃蛇,自己敲了一遍,用博客做个记录,以后再来看. <!DOCTYPE html> <html> <head><title>S ...

  5. JavaScript写贪吃蛇游戏,代码思路都有,想学的自己看

    JavaScript写一个贪吃蛇的游戏(附源码) javascript群内每日课题-今日课题:JavaScript写一个贪吃蛇的游戏 PS:最近群内很多伙伴想要做游戏学学,练练自己的JavaScrip ...

  6. html+JavaScript 实现贪吃蛇程序

    <!doctype html> <html> <head> <!-- 当前文档的字符集编码GBK,UTF-8,GB2312(GBK的子集)--> < ...

  7. c语言实战项目之一 贪吃蛇(源码免费开放)

    朋友们,经过我的c语言前十章的知识,大家应该已经入门了,我个人认为学习c语言最好的方法就是造轮子,写项目就是最好的提高方法,可以把我们学过的知识串联起来. 源码如下: #include<stdi ...

  8. javascript学习-贪吃蛇

    贪吃蛇的例子: 在此例子中,利用snake数组的第0个元素和direction对象中的x值和y值做加法,算出蛇的下一个位置.利用间隔函数,不停的修改类名来进行渲染操作,感觉是一个很灵活的例子. sty ...

  9. html5+JavaScript实现贪吃蛇游戏(可查看排行榜和个人历史记录)

    先看结果截图(界面很丑,但是主要是为了贪吃蛇游戏算法设计和历史记录.排行榜功能的实现,希望以后不被产品经理打,哈哈) 功能描述: 1.开始游戏页面之前输入玩家姓名 2.历史记录:可以查看之前自己玩过的 ...

  10. JavaScript实现贪吃蛇小游戏(网页单机版)

    文章目录 项目地址 项目介绍 游戏开始 游戏暂停 游戏模式 游戏死亡 重新开始 结尾 今天使用 JavaScript 实现了一个网页版的贪吃蛇小游戏. 项目地址 Github: https://git ...

最新文章

  1. 组合特征(二)tfidf(word+article)+lsa
  2. css伪类元素加在元素前,CSS伪类:before在元素之前 :after 在元素之后实例讲解
  3. 替换元素_80%的前端会答错的问题:lt;imggt;是什么元素?
  4. 139_Power BI之某制造企业HR相关数据年度复盘
  5. 【活动】师兄喊你来读博,优秀CV实验室推荐!
  6. 文本删除空行_Word的空行、空格、页眉线删不了?8秒一次性处理,教你删掉它们...
  7. Java 11 将至,除了 Oracle JDK 还有这些版本!
  8. 组策略下发URL地址时的问题
  9. 【网络】Padavan 路由器固件设置打印机服务器
  10. JDK7~13的新特性
  11. 可视化图布局算法浅析
  12. 微信、QQ可正常使用,但浏览器打不开网页解决办法
  13. 计算机断层扫描法原理,能谱计算机断层扫描成像的概念和基本原理.PDF
  14. 基于eBPF的开源工具Kindling之page-fault事件可观测性实现机制
  15. 养生之道?阴阳平衡也!
  16. 索引服务器(全文索引)的使用
  17. python编写赛车_90%的人说Python程序慢,5大神招让你的代码像赛车一样跑起来
  18. Windows10抽风系列:一、卡顿、字体显示丢失
  19. Mysql体系构架详解——内存
  20. C,数组声明、初始化,不初始化会如何?

热门文章

  1. 16.卷1(套接字联网API)---非阻塞式IO
  2. 6.Composer实现PHP中类的自动加载
  3. 9.UNIX 环境高级编程--进程关系
  4. 13.Serving Frontend Files
  5. 1. JavaScript Array 对象
  6. 58. Attribute item() 方法
  7. 15. Window clearTimeout() 方法
  8. php 还原mysql_PHP备份/还原MySQL数据库的代码
  9. 《数学之美》—简单之美-布尔代数和搜索引擎
  10. MongoDB:配置与安装