<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
#map {
width: 400px;
height: 400px;
background-color: #ccc;
position: relative;
}
</style>
</head>
<body>
<!--画出地图设置属性-->
<!--1:地图-->
<!--1)地图的基本特征:宽,高,背景颜色-->
<!--2)小蛇和食物要在地图上面随机显示(位置是变化的),所以地图的定位是相对定位(标准流,占位置),食物和小蛇是绝对定位(脱离文档流,不占位置)-->
<!--父级(地图先占一块地方)子级(食物和蛇在地图里面随便折腾),口诀:子绝父相-->
<div id="map"></div>
<script src="../../common.js"></script>
<script>
// 自调用函数---食物的
//食物部分
//1:为什么要用自调用函数(一次性函数):因为比较安全,内部使用一次就作废(除非把他暴露给window对象),而且不会有变量命名冲突的问题
//2:食物的基本属性:食物也是一个对象,有宽,有高,有横纵坐标,有颜色,--要想创建对象,最好的办法是用构造函数
//3:食物的方法 :怎样生成食物,食物的样式,食物出现的位置(逃不出map的范围,这里就说明方法里面需要传map形参)---通过原型的方式来实现
// 4:每次生成的食物都会占用内存,虽然后期食物会被蛇吃掉,但是那只是一种假象。所有的食物还是存在的,这就需要在食物初始化的时候先把食物删除
// 自调用函数 -------食物对象
(function () {
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";
}
//var d = new Food();
// console.log(d.color);
// 食物的方法---怎么生成,具体样式的设置出现的位置,但是逃不出map的范围
Food.prototype.init = function (map) {
remove();
// 创建div
console.log(map.offsetWidth);
var div = document.createElement("div");
// 调加到map中
map.appendChild(div);
// 设置div的属性
div.style.width = this.width + "px";
div.style.height = this.height + "px";
div.style.backgroundColor = this.color;
// 先脱离文档流
div.style.position = "absolute";
// 随机横纵坐标
this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width;
this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height;
div.style.left = this.x + "px"
div.style.top = this.y + "px"
// 把div加到数组elements里面去
elements.push(div);
}
//私有的函数,删除食物的
function remove() {
// elements数组中有食物
for (var i = 0; i < elements.length; i++) {
var ele = elements[i];
ele.parentNode.removeChild(ele); //自杀
//再次把elements中的这个子元素也删掉
elements.splice(i, 1);
}
}
// window.Food = new Food();
window.Food = Food;
}());
//自调用函数---小蛇的
// food.init(my$("map")); //注意,在写方法的时候,传入的是形参,所有直接id名就可以,但是实参部分传实参,
//小蛇部分
// 1:小蛇也是一个对象,有自己的属性,长宽,方向--要想创建对象---最好的方式是构造函数
// 1.1:由于小蛇的身体最基本是三个小部分,所以身体用数组的形式存放数据(包括大小,颜色)
// 2:小蛇出现的方法
// 小蛇的数据存在body数组里面,所以要通过循环的方式为body一一的添加数据
// 自调用函数-------小蛇对象
(function () {
var elements = [];
function Snake(width, height, direction) {
this.width = width || 20;
this.height = height || 20;
this.body = [
{x: 3, y: 3, color: "red"},
{x: 2, y: 3, color: "orange"},
{x: 1, y: 3, color: "orange"}
]
this.direction = direction || "bottom";
}
// 小蛇的方法--初始化方法
Snake.prototype.init = function (map) {
removeSnake();
for (var i = 0; i < this.body.length; i++) {
var obj = this.body[i];
// 创建div
var div = document.createElement("div");
// 将div添加到地图里面
map.appendChild(div);
// 设置蛇的样式
div.style.width = this.width + "px";
div.style.height = this.height + "px";
div.style.backgroundColor = obj.color;
div.style.position = "absolute";
// 横纵坐标
div.style.left = obj.x * this.width + "px";
div.style.top = obj.y * this.height + "px";
// 把蛇放到elements里面
elements.push(div);
}
}
// 小蛇的方法--动起来
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 "right":
this.body[0].x += 1;
break;
case "left":
this.body[0].x -= 1;
break;
case "top" :
this.body[0].y -= 1;
break;
case "bottom":
this.body[0].y += 1;
break;
}
//判断有没有吃到食物
//小蛇头的坐标和食物的坐标一致
var headX = this.body[0].x * this.width;
var headY = this.body[0].y * this.height;
//食物
var foodX = food.x;
var foodY = food.y;
// console.log(foodX + "==========" + headX);
// console.log(foodY + "==========" + headY);
if (headX == foodX && headY == foodY) {
//获取小蛇最后的尾巴
var last = this.body[this.body.length - 1];
//把最后一个的蛇尾复制,加到小蛇的body里面
this.body.push({
x: last.x,
y: last.y,
color: last.color
});
//把食物删除,初始化食物
food.init(map);
}
}
// 私有函数,删除蛇的
function removeSnake() {
// elements中有蛇
var i = elements.length - 1;
for (; i >= 0; i--) {
var ele = elements[i];
ele.parentNode.removeChild(ele);
elements.splice(i, 1);
}
}
window.Snake = Snake;
// window.Snake = new Snake();
}());
// 自调用函数,游戏对象
(function () {
var that = null;
// 游戏的构造函数
function Game(map) {
this.snake = new Snake();
this.map = map;
this.food = new Food();
that = this;
}
Game.prototype.init = function () {
// 初始化游戏
// 食物初始化
this.food.init(this.map);
//小蛇初始化
this.snake.init(this.map);
// 调用自动移动
this.runSnake(this.food, this.map);
//调用按键的方法
this.bindKey();
// this.snake.move(this.food, this.map);
// this.snake.init(this.map);
//setInterval(function(){
// that.snake.move(that.food,that.map);
// that.snake.init(that.map);
//},150)
}
//添加原型方法,设置小蛇可以自动跑起来
Game.prototype.runSnake = function (food, map) {
//自动去动
// this是实例对象
var timeId = setInterval(function () {
//移动小蛇,这的this是window对象
this.snake.move(food, map);
// 舒适化小蛇
this.snake.init(map);
//横坐标最最大值
var maxX = map.offsetWidth / this.snake.width;
console.log(maxX); //30
//纵坐标最大值
var maxY = 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(timeId);
alert("游戏结束");
}
if (headY < 0 || headY >= maxY) {
clearInterval(timeId);
alert("游戏结束");
}
// e.init(map);
}.bind(that), 150) //bind改变了this的指向
}
//添加原型方法------设置用户按键,改变小蛇移动方向
Game.prototype.bindKey = function () {
//获取用户的键值,改变小蛇的方向
document.addEventListener("keydown", function (e) {
switch (e.keyCode) {
case 37:
this.snake.direction = "left";
break;
case 38:
this.snake.direction = "top";
break;
case 39:
this.snake.direction = "right";
break;
case 40:
this.snake.direction = "bottom";
break;
}
}.bind(that), false)
}
window.Game = Game;
// window.Game =new Game();
}());
var gm = new Game(my$("map"))
gm.init();
// 外部测试
// console.log(Food.color);
// 食物
// Food.init(my$("map"));
//蛇
// Snake.init(my$("map")); //先在地图上看到蛇
// setInterval(function(){
// Snake.move(Food,my$("map"));
// Snake.init(my$("map"));
// },150)
// Snake.move(Food, my$("map")) //走一步
// Snake.init(my$("map"));//走完一步重新画一条蛇,画的时候,先删除之前的蛇
// Snake.move(Food, my$("map"))
// Snake.init(my$("map"));
// Snake.move(Food, my$("map"))
// Snake.init(my$("map"));
// console.log(Food.x + "==========" + Food.y);
</script>
</body>
</html>
运行效果