<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
/*如果是.map下面就要用class=map*/
#container{
width:800px;
margin:auto;
margin_top:60px;
}
#map{
width:800px;
height:400px;
background-color:#ccc;
overflow:hidden;
position:absolute;
}
</style>
<script language="javascript" type="text/javascript">
//设置食物,
function Food(){
this.w=20;
this.h=20;
this.color='red';
//显示食物
this.display=function(){//display是一个函数名,后面是函数体
//我们显示一个食物,首先要知道,大小,位置,属性
var new_div=document.createElement('div');//创建div节点
new_div.style.width=this.w+'px';//设置div的宽
new_div.style.height=this.h+'px';
//位置我们采用0,1,2....
//还要求出有多少个空格
//当前的坐标x:0-1乘以39个它小于40个,x就是有几个格格。y:就是小于20个,让食物在这个范围内活动
this.x=Math.round(Math.random()*39);//Math.random()产生0-1之间的数,Math.round四舍五入
this.y=Math.round(Math.random()*19);
//食物div距左边的距离:食物的宽*x几个格格,因为格格是按照食物分的
new_div.style.left=(this.w*this.x)+'px';
new_div.style.top=(this.h*this.y)+'px';
new_div.style.backgroundColor = this.color;//食物的颜色
new_div.style.position = 'absolute';//食物的定位是绝对定位,绝对定位就是在大屏幕上随便定位,它可以随意动,相对定位,它就相对于参照物而定位
document.getElementById('map').appendChild(new_div);//把这个食物div添加到mapdiv中
//记住这个旧的食物,给旧食物做个标记。就跟给蛇做个标记一样。生成食物的时候就要给这个食物做个标记,以便一会儿我要删除它
//this.div = new_div;
this.taiji=new_div;
}
this.reDisplay = function() {
//删除旧的食物
document.getElementById('map').removeChild(this.taiji);//removeChild删除子节点
this.display();//重新显示新的食物
}
}
//设置蛇
function Snake(){
this.w = 20;
this.h = 20;
this.direct = 'right';//蛇的默认方向
//通过数组来保存蛇身,一个元素代表一个蛇节,
this.body = [//默认把蛇定位到这
{x:5,
y:3,
color:"blue"
},
{x:4,
y:3,
color:"red"
},
{x:3,
y:3,
color:'red'
}
]
//显示蛇
this.display = function(){
for(var i = 0;i<this.body.length;i++){
var snake_div = document.createElement('div');//创建div节点
snake_div.style.width =this.w+'px';//div的宽,蛇的宽
snake_div.style.height =this.h+'px';
//蛇和食物都是20px,整个图层就是被分成多少个格格,格格的宽和高是20px,x就是横着几个格格,y是竖着几个格格
//蛇具左边的距离:蛇的宽*x格格数,
snake_div.style.left = (this.w*this.body[i].x)+'px';//this.body[i].x就是为了获得x的值
snake_div.style.top = (this.h*this.body[i].y)+'px';
snake_div.style.position = 'absolute';
snake_div.style.backgroundColor = this.body[i].color;//蛇的颜色,蛇身和蛇头不一样色
document.getElementById('map').appendChild(snake_div);//把蛇这个div添加到map这个div中
//将显示的div记录下来,旧的蛇,记录下来,给他做个标记
this.body[i].div = snake_div;
}
}
//蛇移动
this.move=function(){
//先移动蛇身,后面的覆盖前面的i=this.body.length-1,因为蛇一共有三节,this.body.length=3,而数组的下标是0,1,2,蛇身就是2,1,i>0是因为蛇头是0,this.body[0],不能把蛇头给覆盖
for(var i=this.body.length-1;i>0;i--){
this.body[i].x=this.body[i-1].x;//x向前移动一个,行走时,不论x,y后面的永远覆盖前面的
this.body[i].y=this.body[i-1].y;
}
//移动蛇头
switch(this.direct){//因为是蛇头,它时这个json对象中的第一个元素,所以是body[0]。判断当前的蛇的方向
case 'up'://如果蛇的方向是向上的话,就y-1
this.body[0].y-=1;//this.body[0].y=this.body[0].y-1假如y=3,向上走一个,y=2
break;//break跳出整个循环
case 'down':
this.body[0].y+=1;
break;
case 'left':
this.body[0].x-=1;
break;
case 'right':
this.body[0].x+=1;//x,y改变了,json对象中的x,y也会改变,this.body中的x,y也会改变
break;
}
//把旧的蛇节删除
this.removeSnake();
//按照新的位置属性重新显示一下
this.display();
//判断是否撞墙
if(this.body[0].x < 0 || this.body[0].x > 39 || this.body[0].y < 0 || this.body[0].y >19) {
//撞了
alert('GAME OVER!');
//清空定时器
clearInterval(snake_id);
}
//判断是否撞到自己
for(var i = this.body.length-1; i >= 4; i--){
if(this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) {
//
alert('GAME OVER!');
//清空定时器
clearInterval(snake_id);
break;
}
}
//判断是否吃上
if(this.body[0].x == food.x && this.body[0].y == food.y) {
// 头和食物撞上了
//蛇要增加一个,需要在body中增加一个元素即可
this.body[this.body.length] = {
x:23,
y:2,
color:'red',
div:null
};
//重新分配食物的地址,重新显示:
food.reDisplay();
}
//判断方向,这个是键盘的判断
//keycode对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关。
this.setDirect=function(keycode){//传进来键的unicode字符码
switch(keycode){
case 37://因为向上的键unicode的值是37,确定是哪个键表示向上
if(this.direct!='right'){
this.direct='left';
}
break;
case 38:
if(this.direct!='down'){
this.direct='up';
}
break;
case 39:
if(this.direct!='left'){
this.direct='right';
}
break;
case 40:
if(this.direct!='up'){
this.direct='down';
}
break;
}
}
}
this.removeSnake=function(){
var map=document.getElementById('map');//得到map图层中的所有内容
for(var i=0;i<this.body.length;i++){
if(this.body[i].div!=null){
map.removeChild(this.body[i].div);// 删除子节点。你同过appendChild把蛇的div添加到map的div中,你在删除map的div中的子节点,也就是蛇,通过for循环,一节一节删除,this.body[i].div就是给蛇做的标记
}
}
}
}
function init(){
food = new Food();//实例化一个对象
food.display();//通过它的对象调用它的方法
snake = new Snake();//实例化一个对象
snake.display();//snake相当于全局变量
}
function start(){
//snake.move();//当调用move时,就会移动,刷新一次,就移动一下
snake_id=setInterval("snake.move()",300);
}
function changeDirect(evt){
snake.setDirect(evt.keyCode);//这个是调用snake中的setDirect函数,因为snake是全局变量
}
</script>
</head>
<!--onkeydown某个键盘按键被按下。就会触发这个事件-->
<body οnlοad="init()" οnkeydοwn="changeDirect(event)">
<div id="container">
<input type="button" οnclick="start()" value="开始">
<div id="map"></div>
</div>
</body>
</html>
当撞墙或者是自己碰到自己都会提示游戏结束