Javascript贪食蛇

           <!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>

        

演示地址:http://www.chhblog.com/Web/DemoView.aspx?DemoID=33

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值