食物对象

 (function () {
//map:所在的父盒子,obj自身的一些属都具有默认值
function Food(map, obj) {
obj = obj || {}; //没有则使用默认值
this.width = obj.width || 20;
this.height = obj.height || 20;
this.top = obj.top || 0;
this.left = obj.left || 0;
this.backgroundColor = obj.backgroundColor || 'green';
this.divArr = [];//存储$("div")的数组
this.map = map;
}
//在页面上用div渲染这个食物
Food.prototype.render = function () {
this.divArr.push($('<div></div>'));
this.divArr[this.divArr.length - 1].css({
'width': this.width,
'height': this.height,
'position': 'absolute',
'backgroundColor': this.backgroundColor,
}).appendTo(this.map);
}
//随机生成食物的位置,必须传入snake对象作为参数
Food.prototype.random = function (snake) {
var maxX = this.map.width() / this.width - 1;//地图的最大坐标 20px一格
var maxY = this.map.height() / this.height - 1;
var x = tools.getRandom(0, maxX); //随机生成x坐标和y坐标 工具对象的方法(在下面贴出 有点画蛇添足)
var y = tools.getRandom(0, maxY);
//遍历蛇对象的节点,如果随机生成的食物坐标与蛇节点重叠再次随机食物坐标
for (var i = 0; i < snake.snakeNode.length; i++) {
if (x == snake.snakeNode[i].left && y == snake.snakeNode[i].top) {
x = tools.getRandom(0, maxX);
y = tools.getRandom(0, maxY);
i = 0;//再次随机食物坐标后,重置i 再次遍历
}
}
this.left = x;
this.top = y;
//在页面上改变食物的left,top
this.divArr[this.divArr.length - 1].css({
'left': this.left * this.width,
'top': this.top * this.height
});
}
window.Food = Food;
})()

  工具对象

 (function(){
var tools = {
getRandom:function(min,max){
return Math.floor(Math.random()*(max - min +1)+min);
}
}
window.tools = tools;
})()

snake对象

 (function () {
//map:所在的父盒子,obj自身的一些属都具有默认值
function Snake(map, obj) {
obj = obj || {}; //没有则使用默认值
this.width = obj.width || 20;
this.height = obj.height || 20;
this.divArr = []; //存储组成蛇的div盒子
this.map = map;
this.directionCode = obj.directionCode || 39;
this.snakeNode = [{ //初始蛇的节点
left: 2,
top: 4,
background: 'red'
}, {
left: 1,
top: 4,
background: 'blue'
}, {
left: 0,
top: 4,
background: 'blue'
}]
}
//在页面上用div渲染蛇
Snake.prototype.render = function () {
//遍历蛇的节点(snakeNode)
for (var i = 0, len = this.snakeNode.length; i < len; i++) {
this.divArr.push($('<div></div>'));//生成div,将div记录在蛇的divArr中
this.divArr[this.divArr.length - 1].css({
'width': this.width,
'height': this.height,
'position': 'absolute',
'left': this.snakeNode[i].left * this.width,
'top': this.snakeNode[i].top * this.height,
'backgroundColor': this.snakeNode[i].background
}).appendTo(this.map);
}
}
//根据蛇的方向(directionCode)改变蛇的节点(snakeNode)的坐标
//思路是蛇最后的节点移动到前一个节点位置,直到蛇头根据方向移动一格
//37 38 39 40 是上下左右的按键码,65 68 83 87 是WASD的键码
//需要参数 定时器的标记(在游戏对象中生成)
Snake.prototype.move = function (timgerId) {
//蛇身体
for (var i = this.snakeNode.length - 1; i > 0; i--) {
this.snakeNode[i].left = this.snakeNode[i - 1].left;
this.snakeNode[i].top = this.snakeNode[i - 1].top;
}
//蛇头
switch (this.directionCode) {
case 39:
this.snakeNode[0].left += 1;
break;
case 37:
this.snakeNode[0].left -= 1;
break;
case 38:
this.snakeNode[0].top -= 1;
break;
case 40:
this.snakeNode[0].top += 1;
break;
case 68:
this.snakeNode[0].left += 1;
break;
case 65:
this.snakeNode[0].left -= 1;
break;
case 87:
this.snakeNode[0].top -= 1;
break;
case 83:
this.snakeNode[0].top += 1;
break;
default:
break;
}
//获取地图的最大坐标,如果蛇头的坐标越界则提示游戏结束
var maxX = this.map.width() / this.width;
var maxY = this.map.height() / this.height;
var snakeHeadX = this.snakeNode[0].left;
var snakeHeadY = this.snakeNode[0].top;
if (snakeHeadX < 0 || snakeHeadX >= maxX || snakeHeadY < 0 || snakeHeadY >= maxY) {
clearInterval(timgerId);//清除定时器,游戏结束
alert('Game Over');
} }
//根据蛇的节点(snakeNode)改变存储在divArr中的div的坐标
//感觉删除div 重新生成div 可能会消耗浏览器性能
Snake.prototype.change = function () {
for (var i = 0, len = this.divArr.length; i < len; i++) {
this.divArr[i].css({
'left': this.snakeNode[i].left * this.width,
'top': this.snakeNode[i].top * this.height,
'backgroundColor': this.snakeNode[i].background
})
}
}
//snake的eat方法,需要参数 食物对象 定时器的标记
Snake.prototype.eat = function (food, timgerId) {
//判断蛇头与食物坐标是否重合
var a = this.snakeNode[0].left == food.left;
var b = this.snakeNode[0].top == food.top;
//判断蛇头与蛇身坐标是否重合
for (var i = this.snakeNode.length - 1; i > 0; i--) {
var c = this.snakeNode[0].left == this.snakeNode[i].left;
var d = this.snakeNode[0].top == this.snakeNode[i].top;
if (c && d) {//蛇吃到自己了
clearInterval(timgerId);
alert('Game Over');
}
}
//当蛇头与食物坐标重合
if (a && b) {
//food.divArr[food.divArr.length - 1]代表最新生成的食物div
//将这个div记录在蛇的divArr中,在蛇节点(snakeNode)中追加一个与之对应的节点
//在蛇移动时 改变节点坐标,然后根据节点坐标 改变这个div的坐标
this.divArr.push(food.divArr[food.divArr.length - 1]);
this.snakeNode.push({
background: 'blue',
left: 0,
top: 0
});
food.render(); //重新生成食物
food.random(this);//随机坐标
}
}
window.Snake = Snake;
})();

  游戏对象

 (function () {
var that; //存储生成的游戏对象,因为定时器中的this指向window
var kCode = 39; //默认值与蛇的方向相同,存储临时方向按键码,因为在蛇移动之前时方向键可以被按多次
function Game(map) {
this.map = map;
this.snake = new Snake(this.map); //生成snake(蛇)对象
this.food = new Food(this.map);//生成food(食物)对象
that = this; //记录自己
this.timgerId = null; //记录定时器(让蛇移动的定时器)
}
//通过原型添加一个开始的方法
Game.prototype.star = function () {
this.food.render(); //生成(渲染)食物
this.food.random(this.snake);//随机食物的坐标,参数为snake对象,防止食物在蛇节点(snakeNode)上
this.snake.render();//生成(渲染)蛇
kDown(); //开启(onkeydown),记录用户的所按的键码
runSnake(); //开启定时器,使蛇移动
} function kDown() {
$(window).on('keydown', function (e) {
kCode = e.keyCode;//记录用户的所按的键码
})
}
//一个函数,参数 code 临时按键码,用来判断蛇的方向,让蛇无法掉头(方向不能直接从上变下)
function changingDirectionSuddenly(code) {
var b = code == 37 || code == 38 || code == 39 || code == 40 || code == 68 || code == 65 || code == 87 || code == 83;
if (b) {
if ((that.snake.directionCode === 39 || that.snake.directionCode == 68) && code !== 37 && code !== 65) {
that.snake.directionCode = code;
}
if ((that.snake.directionCode === 37 || that.snake.directionCode == 65) && code !== 39 && code !== 68) {
that.snake.directionCode = code;
}
if ((that.snake.directionCode === 38 || that.snake.directionCode == 87) && code !== 40 && code !== 83) {
that.snake.directionCode = code;
}
if ((that.snake.directionCode === 40 || that.snake.directionCode == 83) && code !== 38 && code !== 87) {
that.snake.directionCode = code;
}
}
return that.snake.directionCode;
}
//蛇移动
function runSnake() {
//记录定时器,开启定时器让蛇连续移动
that.timgerId = setInterval(function () {
//在蛇移动时判断方向。
// 如果在用户按下时判断方向,会导致连续按键使蛇掉头(先按左再按下,表现为掉头)
changingDirectionSuddenly(kCode);
// that.snake.eat(that.food, that.timgerId);//调用蛇的eat方法判断蛇是否吃到啥
// //先吃还是先移动呢?好像没啥区别
that.snake.move(that.timgerId);//调用蛇的move方法移动蛇节点一个
that.snake.change();//调用蛇的change方法改变构成蛇的div的坐标
that.snake.eat(that.food, that.timgerId);
}, 300)
} window.Game = Game;
})()

  main

 (function () {
var game = new Game($('#box'));
game.star();
})();

  HTML

 <!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
</head> <body>
<div id="box">
</div>
</body>
<script src="js/jquery-1.12.2.js"></script>
<script src="js/tools.js"></script>
<script src="js/food.js"></script>
<script src="js/snake.js"></script>
<script src="js/game.js"></script>
<script src="js/main.js"></script> </html>

  CSS

 #box{
width: 200px;
height: 160px;
margin: 0 auto;
background-image: url(../images/ditu.jpg);//一个正方形图片,没有也不影响
/* background-color: #3c3c3c; */
position: relative;
overflow: hidden;
}

js面向对象案例 贪吃蛇的更多相关文章

  1. JS高级---案例贪吃蛇,把封装的函数移动到js文件中

    案例贪吃蛇,把封装的函数移动到js文件中 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  2. 原生js写的贪吃蛇网页版游戏特效

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...

  3. 20行JS代码实现贪吃蛇

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 用js写一个贪吃蛇小游戏

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. JavaScript 面向对象思想 贪吃蛇游戏

    js代码: 游戏的对象 ,食物,蛇 ,游戏控制思路如下 (完整代码在https://github.com/774044859yf/ObjectSnakeGame下载) var snake = { aS ...

  6. Unity初级案例——贪吃蛇

    using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; ...

  7. canvas原生js写的贪吃蛇

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 不小心用js重做了一遍贪吃蛇

    贪吃蛇游戏想必没人会感到陌生,这个游戏的js版本在网上也是一搜一大把,今天我要介绍的仍然是如何用js做一个贪吃蛇游戏,但在关键一步,蛇的运动的实现上略有不同. 贪吃蛇的js版本通常用连续的方块元素来实 ...

  9. js版贪吃蛇

    之前没有写博客的习惯,这是我的第一个博客,有些的不好的地方,希望大家多多提意见 js版的贪吃蛇相对比较简单,废话不多说直接上代码,有需要注意的地方我会标红,github源码地址https://gith ...

随机推荐

  1. Keras vs. PyTorch in Transfer Learning

    We perform image classification, one of the computer vision tasks deep learning shines at. As traini ...

  2. Flutter与Android混合开发及Platform Channel的使用

    相对于单独开发Flutter应用,混合开发对于线上项目更具有实际意义,可以把风险控制到最低,也可以进行实战上线.所以介绍 集成已有项目 混合开发涉及原生Native和Flutter进行通信传输,还有插 ...

  3. csv注入漏洞原理&&实战

    前言  为了找工作,巩固巩固知识.本文会介绍 csv 注入漏洞的原理,最后给出一个示例.  正文 在 csv 文件 和 xlsx 文件中的每一项的值如果是 =, @, +, - 就会被 excel 识 ...

  4. 精华阅读第 12 期 | 最新 App Store 审核指南与10大被拒理由?

    很多时候,我们对技术的追求是没有止境的,我们需要不断的学习,进步,再学习,再进步!本文系移动精英开发俱乐部的第12期文章推荐阅读整理,其中涉及到了 Android 数据库框架,架构设计中的循环引用,同 ...

  5. js判断状态

    '<input type="radio" class="danxuan" name="danxuan" code="'||v ...

  6. Linux zip命令详解

    zip常见命令参数 Usage: zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list] The ...

  7. 安装ubuntu server时可能会需要的配置

    1.修改源 笔者比较习惯用163的源,配置如下: sudo vi /etc/apt/sources.list 163源为: deb http://mirrors.163.com/ubuntu/ pre ...

  8. CSS3新特性2D、3D效果讲解

    希望这篇博客可以对你有所帮助,如果有什么技术上的问题,希望我们可以做进一步的交流,如果你觉得我哪里阐述的不正确或者你有更好的更透彻的理解,也可以联系我,我在这里随时等着你. 对于css/html是每个 ...

  9. Day4 MySql触发器视图索引以及设计优化

    触发器 MySQL包含对触发器的支持.触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行. 通过事件触发,不能传参 语法 CREA ...

  10. robotframwork接口测试(五)—接口分层测试粗解

    个人小结,仅供参考. 接口测试很简单,但是很重要. 可以写代码,也可以用工具进行测试.工具说说就很多了,简单介绍一下我目前用过的几个能够测试接口的工具, Burpsuite:这类偏请求攻击类软件 Fi ...