食物对象

 (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. ERP 实施执行力提高的障碍,看看你中了几招?

    据统计,在国内 ERP 实施的成功率非常低,成功实施实现系统集成的只占10%-20%:没有实现系统集成或实现部分集成的只有30%-40%:而失败的却占50%,并且在实施成功的10%-20%中大多为外资 ...

  2. 杀死进程-LeetCode-582

    英文版 582. Kill ProcessGiven n processes, each process has a unique PID (process id) and its PPID (par ...

  3. python学习笔记之——python模块

    1.python模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python ...

  4. DNS隧道实战&&cobaltstrike利用dns隧道

    前言 使用 dns 隧道进行 tcp 通信. 正文 首先配置域名 配置一个 A 记录指向我们的 vps, 然后配置几个 ns 记录,指向刚刚设置的 A 记录 然后在服务端安装 wget https:/ ...

  5. Pig数据类型

    基本类型 int.long.float.double.chararray.bytearray.datatime.boolean.biginteger.bigdecimal 复杂类型 map.tuple ...

  6. logminer系列文章一(logminer的使用)

    转自 http://blog.itpub.net/26613085/viewspace-1064008/ 1.安装logminer以及生成logminer数据字典所需要的包(需使用sys用户) [or ...

  7. HBase 负载均衡

    HBase 可以根据当前集群的负载以region为单位进行rebalance.在HMaster中,后台会起一个线程定期检查是否需要进行rebalance,线程叫做BalancerChore.线程每隔  ...

  8. The operation names in the portType match the method names in the SEI or Web service implementation class.

    The Endpoint validation failed to validate due to the following errors: :: Invalid Endpoint Interfac ...

  9. win10 虚拟机 hyper-v 安装 centos 7

    一.win 10 企业版 自带虚拟机 hyper-v 1.控制面板-->程序和功能-->启用或关闭Windows功能 勾上 hyper-v 确定就ok了 2.安装成功后会发现在 左下角“开 ...

  10. 绕过CDN查找网站真实IP方法收集

    方法1很简单,使用各种多地 ping 的服务,查看对应 IP 地址是否唯一,如果不唯一多半是使用了CDN, 多地 Ping 网站有: http://ping.chinaz.com/ http://pi ...