<!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>
<title>贪食蛇</title>
<style type='text/css'>
div{ margin:0; padding:0;}
.snake{ width:300px; height:400px; border:1px solid #000; margin:0 auto;}
.snake div{width:10px; height:10px; float:left;}
.snake div.point{background:#000;}
.snake div.food{ background:blue;}
.tool{ width:300px; margin:0 auto; text-align:center; margin-top:10px;}
.msg{ width:300px; margin:0 auto; border:1px solid #000; padding:5px 0; font-size:12px ; text-align:center; border-top:none}
</style>
</head>
<body>
<div class='snake' id='snake'>
</div>
<div class='msg'>
分数:<span id='score'>0</span>
级别:<span id='level'>1</span>
</div>
<div class='tool'>
<input type='button' value='点击开始' οnclick='toggle(this);'/>
<input type='button' value='新游戏' οnclick='window.location.href = window.location.href'/>
</div>
<script type='text/javascript'>
var TRANSVERSE = 30;
var VERTICAL = 40;
var SPEED = 1;
var LEFT = 1;
var RIGHT = 2;
var TOP = 3;
var BOTTOM = 4;
var GAME_START = 1;
var GAME_STOP = 2;
var GAME_OVER = 3
//组成蛇的节点
var Component = function(point)
{
var prevDirection , currDirection,
next ,
location = point;
this.getNext = function()
{
return next;
}
this.setNext = function(el)
{
next = el;
}
this.setDirection = function(value)
{
currDirection = value;
}
this.getDirection = function()
{
return currDirection;
}
this.computeLocation = function()
{
location = Component.getNextPoint(location, currDirection)
if(next) next.computeLocation();
if(prevDirection != currDirection)
{
prevDirection = currDirection;
if(next) next.setDirection(currDirection);
}
}
this.getLocation = function()
{
return location;
}
}
Component.getNextPoint = function(point , direction)
{
var newPoint = {};
switch(direction)
{
case LEFT:
newPoint.x = point.x - SPEED;
newPoint.y = point.y ;
break;
case RIGHT:
newPoint.x = point.x + SPEED;
newPoint.y = point.y;
break;
case TOP:
newPoint.x = point.x;
newPoint.y = point.y - SPEED;
break;
case BOTTOM:
newPoint.x = point.x;
newPoint.y = point.y + SPEED;
break;
}
return newPoint;
}
//蛇
var Snake = function(head)
{
var snake = head, isGameover = false;
var self = this;
this.addComponent = function()
{
var lastNode = getLastNode();
var point = lastNode.getLocation();
var reverse;
switch(lastNode.getDirection())
{
case LEFT:
reverse = RIGHT;
break;
case RIGHT:
reverse = LEFT;
break;
case TOP:
reverse = BOTTOM;
break;
case BOTTOM:
reverse = TOP;
break;
}
var newPoint = Component.getNextPoint(point, reverse);
var node = new Component(newPoint);
node.setDirection(lastNode.getDirection());
lastNode.setNext(node);
}
this.getComponentLocation = function()
{
var cl = new Array;
var node = snake;
do{
cl.push(node.getLocation());
node = node.getNext();
}while(node);
return cl;
}
this.getLength = function()
{
var count = 0;
var node = snake;
while(node)
{
count ++;
node = node.getNext();
}
return count;
}
this.isGameover = function()
{
return isGameover;
}
this.move = function()
{
if(!isGameover) snake.computeLocation();
checkGameover();
}
this.navigate = function(direction)
{
if(!isGameover) snake.setDirection(direction);
}
this.getStartLocation = function()
{
return snake.getLocation();
}
this.getStartDirection = function()
{
return snake.getDirection();
}
var checkGameover = function()
{
var l = snake.getLocation();
var cl = self.getComponentLocation();
if(l.x < 0 || l.x >= TRANSVERSE || l.y < 0 || l.y >= VERTICAL )
{
isGameover = true;
return;
}
for(var i = 0 ; i < cl.length ; i ++)
{
if(l != cl[i] && cl[i].x == l.x && cl[i].y == l.y)
{
isGameover = true;
return;
}
}
}
var getLastNode = function()
{
var node = snake.getNext();
while(node)
{
var nextNode = node.getNext();
if(!nextNode) return node;
node = nextNode;
}
return snake;
}
}
//贪食蛇游戏
var SnakeGame = function()
{
var snake ;
var moveTimer , randomTimer;
var currDirection;
var foods = [];
var self = this;
var status = GAME_STOP;
this.snakeMoved = function(){};
this.started = function(){};
this.stopped = function(){};
this.gameEnded = function(){};
this.onAddComponent = function(){};
var getRandom = function(notin)
{
var avaiable = [];
for(var y = 0 ; y < VERTICAL ; y ++)
{
for(var x = 0 ; x < TRANSVERSE; x++ )
{
var j = 0;
var avaiableFlag = true;
while(j < notin.length)
{
var el = notin[j];
if(el.x == x && el.y == y)
{
notin.splice(j,1);
avaiableFlag = false;
break;
}
j ++;
}
if(avaiableFlag) avaiable.push({x : x , y : y});
}
}
var rand = Math.floor(Math.random() * avaiable.length);
return avaiable[rand];
}
this.navigate = function(direction)
{
var sd = snake.getStartDirection();
var d ;
if((sd == LEFT || sd == RIGHT) && (direction == TOP || direction == BOTTOM)) d = direction;
if((sd == TOP || sd == BOTTOM) && (direction == LEFT || direction == RIGHT)) d = direction;
if(d) currDirection = d;
}
var move = function()
{
moveTimer = window.setTimeout(move , computeMoveInterval());
if(currDirection) snake.navigate(currDirection);
snake.move();
var lc = snake.getStartLocation();
for(var i = 0 ; i < foods.length ; i ++)
{
if(lc.x == foods[i].x && lc.y == foods[i].y)
{
snake.addComponent();
self.onAddComponent();
foods.splice(i,1);
break;
}
}
if(snake.isGameover())
{
gameover();
return;
}
self.snakeMoved();
}
var createFood = function()
{
var notin = snake.getComponentLocation().concat(foods)
var rand = getRandom(notin);
foods.push(rand);
}
var arrayToHash = function(array)
{
var hash = {};
for(var i = 0 , point ; point = array[i++];) hash[[point.x , point.y]] = null;
return hash;
}
this.getMap = function()
{
var board = new Array;
var cl = snake.getComponentLocation();
var food = arrayToHash(foods);
for(var y = 0 ; y < VERTICAL; y ++)
{
for(var x = 0 ; x < TRANSVERSE ; x ++)
{
board.push({x: x , y : y});
}
}
cl = arrayToHash(cl);
board = arrayToHash(board);
for(var key in cl) board[key] = 'snake';
for(var key in food) board[key] = 'food';
return board;
}
this.getScore = function()
{
return snake.getLength() - 1;
}
this.getLevel = function()
{
var score = self.getScore();
var level = 0;
if(score <= 5) level = 1;
else if(score <= 12) level = 2;
else if(score <= 22) level = 3;
else if(score <= 35) level = 4;
else if(score <= 50) level = 5;
else if(score <= 75) level = 6;
else if(score <= 90) level = 7;
else if(score <= 100) level = 8;
else level = 9;
return level;
}
var computeMoveInterval = function()
{
var speed = {
'1':200,
'2':160,
'3':120,
'4':100,
'5':80,
'6':60,
'7':40,
'8':20,
'9':10
}
var level = self.getLevel();
return speed[level];
}
this.start = function()
{
status = GAME_START;
moveTimer = window.setTimeout(move , computeMoveInterval());
foodTimer = window.setInterval(createFood, 5000);
this.started();
}
this.stop = function()
{
status = GAME_STOP;
window.clearTimeout(moveTimer);
window.clearInterval(foodTimer);
this.stopped();
}
var gameover = function()
{
status = GAME_OVER;
window.clearTimeout(moveTimer);
window.clearInterval(foodTimer);
self.gameEnded();
alert('游戏结束');
}
this.gameState = function()
{
return status;
}
var initialize = function()
{
//var rnd = getRandom([]);
var head = new Component({x:Math.ceil(TRANSVERSE / 2), y: Math.ceil(VERTICAL / 2)});
head.setDirection([LEFT, RIGHT , TOP , BOTTOM][Math.floor(Math.random() * 4)])
snake = new Snake(head);
}
initialize();
}
//用户界面
var SnakeGameUI = function(holder, snakeGame)
{
var getHTML = function()
{
var html = '';
var map = snakeGame.getMap();
for(var key in map)
{
var className = '';
var pointType = map[key];
if(pointType == 'snake') className = 'point';
else if(pointType == 'food') className = 'food';
html += '<div class="'+ className +'"></div>';
}
return html ;
}
this.draw = function()
{
document.getElementById(holder).innerHTML = getHTML();
}
this.bindEvent = function()
{
document.body.οnkeydοwn= function(e)
{
e = e || window.event;
var keyCode = e.keyCode;
switch(keyCode)
{
case 37:
snakeGame.navigate(LEFT);
break;
case 38:
snakeGame.navigate(TOP);
break;
case 39:
snakeGame.navigate(RIGHT);
break;
case 40:
snakeGame.navigate(BOTTOM);
break;
}
}
}
this.unBindEvent = function()
{
document.body.onkeydown = null;
}
}
var game = new SnakeGame();
var gameUI = new SnakeGameUI('snake' , game);
game.snakeMoved = function(){gameUI.draw();}
game.started = function(){gameUI.bindEvent();}
game.stopped = function(){gameUI.unBindEvent();}
game.gameEnded = function(){gameUI.unBindEvent();}
game.onAddComponent = function()
{
document.getElementById('score').innerHTML = game.getScore();
document.getElementById('level').innerHTML = game.getLevel();
}
function toggle(btn)
{
var state = game.gameState();
if(state == GAME_STOP)
{
game.start();
btn.value = '暂停游戏';
}
else if(state == GAME_START)
{
game.stop();
btn.value = '点击开始';
}else
{
alert('游戏已结束');
}
}
</script>
</body>
</html>
Javascript贪食蛇
最新推荐文章于 2024-04-17 21:49:28 发布