body {
text-align: center;
}
/* 地图 */
.map {
position: relative;
margin: 40px auto;
width: 800px;
height: 500px;
background: url(../img/bg1.png);
box-shadow: 0px 0px 50px 20px green;
}
/* 蛇头、蛇身体、食物基本样式 */
.snake-head,
.snake-body,
.food {
position: absolute;
width: 20px;
height: 20px;
/* border-radius: 17px; */
}
/* 蛇的身体 */
.snake-body {
background: url(../img/body.png);
box-shadow: 0 0 10px 1px gold;
}
/* 蛇头样式 */
.snake-head {
background: url(../img/head.png);
}
/* 食物 */
.food {
background:url(../img/food.png);
animation: food infinite alternate-reverse 0.5s;
}
@keyframes food{
0%{
box-shadow: 0 0 5px 2px greenyellow;
}
100% {
box-shadow: 0 0 100px 2px greenyellow;
}
}
.dead {
width: 100%;
height: 100%;
background: rgba(0, 0, 0,0.8);
/* background: blue; */
position: absolute;
top:0;
left:0;
color:red;
display: none;
}
.dead h1 {
text-align: center;
font:bold 100px '宋体';
color:#fff;
}
.dead span {
width: 100px;
height: 30px;
background: #00ff00;
font:bold 20px/30px '宋体';
padding:10px 20px;
cursor: pointer;
user-select: none;
}
.dead span:hover {
background: orange;
}
input {
width: 80px;
}
//食物food.js
//食物随机的显示在页面某个位置,通过建立一个snake类,里面的x,y的属性值来设置
//首先咋们要知道food构造函数里面要添加那些属性和方法
//是根据需求来写的,里面要有位置,然后就要涉及到top,和left值
//然后食物有一个随机定位的方法,所以还要给食物添加一个函数用来随机定位
//食物的属性
function Food (){
this.x = 0;
this.y = 0;
this.div = $('<div></div>').appendTo('.map').addClass('food');
}
//食物的方法
Food.prototype.randomLoacation = function(){
var xNum = $('.map').width()/20;
var yNum = $('.map').height()/20;
this.x = parseInt(Math.random() * xNum ) * 20;
this.y = parseInt(Math.random() * yNum ) * 20;
this.div.css({
left: this.x,
top: this.y
})
// console.log(this.x)
}
//snake.js
//研究蛇的属性和方法
/**
* 属性:
* ① 蛇具有位置,还有蛇头和蛇身之分,将来会是一个数组
* ② 蛇还有方向
*/
function Snake (){
this.direction = 'right';
this.datas = [
{x:3, y:0, className:'snake-head'},
{x:2, y:0, className:'snake-body'},
{x:1, y:0, className:'snake-body'}
];
}
/**
* 方法:
* ① 蛇要绘制出来
* ② 蛇可以移动
* ③ 蛇会死亡
*/
Snake.prototype.draw = function() {
var that = this;
var datas = that.datas;
for(var i = 0; i < datas.length; i++){
var snake = $('<div></div>').addClass(datas[i].className).appendTo('.map');
// console.log(datas[i].y)
snake.css({
left: datas[i].x * 20,
top: datas[i].y * 20
})
}
}
//移动: 从后面向前面修改,将倒数第二个给了倒数第一个
//为什么不直接从前面到后面?? 因为,若将第一个给了第二个,然后此时第二个的值就是以前第一个的值,第二个的值就不在了,被覆盖了
Snake.prototype.move = function() {
var that = this;
var datas = that.datas;
var direction = that.direction;
for(var i = datas.length - 1; i > 0 ; i--){
datas[i].x = datas[i-1].x;
datas[i].y = datas[i-1].y;
// console.log(datas[i].x); //已经实现了让蛇身移动
}
//根据方向,来决定蛇头的移动位置
if(direction == 'right'){
datas[0].x += 1;
} else if(direction == 'left'){
datas[0].x -= 1;
} else if(direction == 'top'){
datas[0].y -= 1;
} else if(direction == 'bottom'){
datas[0].y += 1;
}
//当蛇移动之后要把以前的位置清除掉
//这里就是让带有蛇的类名的div全部清除,后面还有一个绘制蛇的步骤,所以不用考虑蛇不在了
$('.snake-head , .snake-body').remove();
that.draw();
}
//蛇撞墙后死亡,就是当蛇头的x,y超过范围后,将会返回一个值,game通过这个值来判断是否结束游戏
Snake.prototype.died = function() {
var head = this.datas[0];
var width = $('.map').width();
var height = $('.map').height();
if(head.x < 0 || head.x > width/20 || head.y < 0 || head.y > height/20){
// console.log('死亡了')
return true;
}else {
return false;
}
}
//蛇吃食物: 当蛇吃到食物后长度会自动加1;
//具体实现: 判断食物和蛇头的位置的x,y是否相等,若相等表示吃到食物,然后向里面datas里面push一个对象,不用定义x,y只需要定义他的类名, 他的位置由绘制的时候自动添加;
Snake.prototype.eat = function() {
var that = this;
// console.log(that)
var head = that.datas[0];
var foodLeft = $('.food').offset().left - $('.map').offset().left;
var foodTop = $('.food').offset().top - $('.map').offset().top;
// console.log(foodLeft)
if(head.x * 20 == foodLeft && head.y*20 == foodTop){
// console.log('吃到食物了');
that.datas.push({className:'snake-body'});
// $('.food').remove();
return true;
}
return false;
}
// var snake = new Snake();
// snake.draw();
// setInterval(function(){
// snake.move();
// snake.eat();
// },2000)
//游戏 game.js
/**
* 游戏方法:
* ① 开始游戏
* ② 暂停游戏
*/
/**
* 游戏的属性 :
* ① 有一个snake属性,可以控制蛇
* ② food属性
* ③
*/
function Game() {
this.snake = new Snake();
this.food = new Food();
this.food.randomLoacation();
this.snake.draw();
this.scroe = 0;
}
/**
* 开始游戏
*/
var flag;
Game.prototype.start = function (){
var that = this;
flag = setInterval(function() {
// console.log(this.snake)
that.snake.move();
that.snake.eat();
var isEat = that.snake.eat();
console.log(that)
if (isEat) {
// 增加分数
console.log('迟到了')
that.scroe += 100
// 设置给输入框
$('input').val('分数:' + that.scroe);
// 随机食物位置
that.food.randomLoacation();
}
// 判断是否死亡
var isdied = that.snake.died();
if(isdied){
game.end();
$('.dead').slideDown(500);
// 按钮失去焦点
$('#btn1').blur();
}
},100)
}
Game.prototype.end = function (){
clearInterval(flag);
}
var game = new Game();
$('#btn1').click(function(){
game.start()
})
$('#btn2').click(function(){
game.end()
})
$('#btn3').click(function(){
location.reload();
})
//通过键盘事件控制
$(document).keydown(function(e) {
// console.log(e.keyCode)
if(e.keyCode == 37) {
game.snake.direction = 'left';
} else if(e.keyCode == 38) {
game.snake.direction = 'top';
} else if(e.keyCode == 39) {
game.snake.direction = 'right';
} else if(e.keyCode == 40) {
game.snake.direction = 'bottom';
}
})