<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.map{
width: 800px;
height: 600px;
background-color: rgb(15, 206, 240);
position: relative;
margin: 30px auto;
}
button{
display: block;
width: 80px;
height: 25px;
margin: 10px auto;
}
</style>
</head>
<body>
<!-- 地图 -->
<div>
<button id="btn">开始游戏</button>
</div>
<div class="map"></div>
<script src="food.js"></script>
<script src="snake.js"></script>
<script src="game.js"></script>
<script>
var map = document.querySelector(".map")
var btn = document.querySelector("#btn")
var g = new Game(map)
g.render2()
btn.onclick = function (){
g.startGame()
}
</script>
</body>
</html>
Food.js
// 创建食物对象
// 食物 大小 坐标 背景颜色
// 自定义构造函数方法创建
// 用||设置默认值
// 优化版
function Food(options){ //options是一个对象
// 设置默认值。
options=options||{}
this.width = options.width||20
this.height = options.height||20
this.backgroundColor =options.backgroundColor||"red"
this.x = options.x||0
this.y = options.y||0
}
// 参数为对象 对象里内容为无序键值对
// 将食物添加到地图中
// 用render函数 render 函数放在原型里 不会造成内存浪费
// 创建一个div 把食物 放进这个div里
Food.prototype.render = function (target){
var div =document.createElement("div")
// 设置div的样式
div.innerText ="W"
div.style.position = "absolute"
div.style.width = this.width+"px" //px不能忘
div.style.height = this.height+"px" //px 不能忘
div.style.backgroundColor = this.backgroundColor
map.appendChild(div)
// 随机这个div的位置 //offsetWidth 获取的是数值 方便计算
this.x = parseInt(Math.random()*target.offsetWidth/this.width)
this.y = parseInt(Math.random()*target.offsetHeight/this.height)
// console.log(this.x)
// 设置left top 一定要先定位 这个最后 单位px 不能忘
div.style.left = this.width*this.x+"px"
div.style.top = this.height*this.y+"px"
}
snake.js
// 创建蛇对象
// headBgc 蛇头的颜色
// bodyBgc 蛇身的颜色
// body 蛇身
// []空数组里放蛇身 因为 蛇有多节
function Snake(options) {
options= options ||{}
this.width =options.width||20
this.height = options.height||20
// 给蛇设置移动方向
this.direction = options.direction||"right"
this.headBgc = options.headBgc||"pink"
this.bodyBgc = options.bodyBgc||"red"
this.body = options.body||
[ //蛇开始 默认三节 坐标固定好
{x:2,y:0},
{x:1,y:0},
{x:0,y:0}
]
}
// 把蛇添加到map中去
Snake.prototype.render1 = function (target) {
// 蛇身是多节 存在body1的数组中 所以要遍历这个数组
for(var i =0;i<this.body.length;i++ ){
var span = document.createElement("span")
span.style.width= this.width +"px"
span.style.height= this.height +"px"
if(i==0){
span.style.backgroundColor = this.headBgc
span.innerText = "Z"
}else{
span.style.backgroundColor = this.bodyBgc
}
// span加到map中去
target.appendChild(span)
// 给span定位 才能 设置 left top
span.style.position = "absolute"
// this.body[i].x/y 获取数组中 x y的值
span.style.left = this.body[i].x*this.width +"px"
span.style.top = this.body[i].y*this.height+"px"
}
}
// 蛇移动
// 移动方式 复制蛇头的坐标信息 移动复制的那一份删除蛇尾
Snake.prototype.move = function (target,food){
// 复制的蛇头,添加到数组当中
// 在数组当中,删除蛇尾
// 复杂数据类型
var newHead = {
x:this.body[0].x,
y:this.body[0].y
}
// 判断蛇的移动方向
switch(this.direction){
case "right":
// 往右走 x++
newHead.x++
break;
case "left":
// 左走
newHead.x--
break;
case "up":
// 上走
newHead.y--
break;
case "down":
// 下走
newHead.y++
break;
}
// 蛇吃食物
// 吃掉的食物消失 食物刷新 蛇长度变长
if(newHead.x==food.x&&newHead.y ==food.y){
var div = target.querySelector("div")
target.removeChild(div)
food.render(target)
}else{
// 没吃到食物 就不变长
this.body.pop()//删除蛇尾
}
this.body.unshift(newHead)//添加蛇头
var spans = target.querySelectorAll("span")
// spans是伪数组 需要遍历 一个一个删除
for(var i =0;i<spans.length;i++){
target.removeChild(spans[i])
}
this.render1(target)
}
game.js
function Game(target){
this.snake = new Snake();
this.food = new Food();
this.map = target
}
Game.prototype.render2 = function () {
this.snake.render1( this.map)
this.food.render(this.map)
}
Game.prototype.startGame = function () {
var that =this
var time=setInterval(function(){
that.snake.move(that.map,that.food)
var head = that.snake.body[0]
// 蛇撞墙
if(head.x>=that.map.offsetWidth/that.snake.width){
clearInterval(time)
alert("妹妹,游戏 gaí束!!!")
}else if(head.x<0){
clearInterval(time)
alert("妹妹,游戏 gaí束!!!")
}else if(head.y>=that.map.offsetHeight/that.snake.height){
clearInterval(time)
alert("妹妹,游戏 gaí束!!!")
}else if(head.y<0){
clearInterval(time)
alert("妹妹,游戏 gaí束!!!")
}
// 可以从4开始
for(var i =4;i<that.snake.body.length;i++){
if(head.x==that.snake.body[i].x&&head.y==that.snake.body[i].y){
clearInterval(time)
alert("妹妹,游戏 gaí束!!!")
}
}
},200);
//上下左右键控制蛇移动
document.onkeyup = function (e) {
var keycode = e.keyCode
if(keycode==37){
if(that.snake.direction=="right"){
return;
}
that.snake.direction = "left"
}else if(keycode==38){
if(that.snake.direction == "down"){
return;
}
that.snake.direction = "up"
}else if(keycode==39){
if(that.snake.direction == "left"){
return;
}
that.snake.direction = "right"
}else if(keycode==40){
if(that.snake.direction =="up"){
return;
}that.snake.direction = "down"
}
}
}