canvas原生js写的贪吃蛇

<!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">
	*{
		padding: 0;
		margin: 0;
	}

	.wrap{
		 500px;
		height: 500px;
		border: 1px solid #ccc;
		margin: 0 auto;
		position: relative;
	}
	canvas{
		position: absolute;
		top: 0;
		left: 0;
	}
	#gridC{
		z-index: 2;
	}
	#canvas{
		z-index: 1;
	}
</style>
</head>
 
<body>
	<div class="wrap">
		<canvas id="gridC" width="500" height="500"></canvas>
		<canvas id="canvas" width="500" height="500"></canvas>
	</div>
	
</body>
<script type="text/javascript">
    var theCanvas = document.getElementById('canvas');
    var ctx = theCanvas.getContext("2d");	
	var run = false;
	var maxBound = {};
	var config = {
		gridX:20,
		gridY:20		
	}
	
	var body = [
		{
			x:8,
			y:8
		},
		{
			x:8,
			y:9
		},
		{
			x:8,
			y:10
		}
	];
	
	var food = {
				x:0,
				y:0
			}
		
	
	
	
	
	var keyCodeMethod = {
		'38':function(){
			//上  : x不变,y减一
			move('y',-1);
		},
		'40':function(){
			//下: x不变,y加一
			move('y',1);
		},
		'37':function(){
			//左:y不变,x减一
			move('x',-1);
		},
		'39':function(){
			//右: y 不变,x加一
			move('x',1);
		}
		
	}

	drawnAll();
	
	window.onkeydown = function(e){
		var method = keyCodeMethod[e.keyCode];
		if(method){
			method();
		}
	}
	
	//移动
	function move(axis,speed){
		for(var i = body.length-1; i > 0; i--){
			body[i].x = body[i-1].x;
			body[i].y = body[i-1].y;
		}
		body[0][axis] = body[0][axis] + speed;
		//判断死亡
		if(!isValid(body[0])){
			gameOver();
		}
		
		//吃东西
		eat(body[0]);
		
		
		//数据修改完成,全部重新渲染
		drawnAll();
	}
	
	//判断死亡
	function isValid(option){
		option = option || {};
		var valid = true;
		if(option.x < 0){
			option.x = 0;
			valid = false;
		}
		if(option.x > maxBound.x){
			option.x = maxBound.x;
			valid = false;
		}
		if(option.y < 0){
			option.y = 0;
			valid = false;
		}
		if(option.y > maxBound.y){
			option.y = maxBound.y;
			valid = false;
		}
		return valid;
	}
	
	//吃东西
	function eat(option){
		option = option || {};
		if(food && option.x == food.x && option.y == food.y){
			//吃到食物
			body.push({
				x:option.x,
				y:option.y
			});
			//吃到食物就需要再创建一个食物
			food = null;
			createFood();
		}
	}
	
	//创建食物
	function createFood(){
		var pos = axisPoint();
		while(!validFood(pos)){
			pos = axisPoint();
		}
		food = pos;
	}
	
	//随机创建位置
	function axisPoint(){
		var x = Math.floor(Math.random()*maxBound.x);
		var y = Math.floor(Math.random()*maxBound.y);
		return {x:x,y:y};
	}
	//验证食物的位置是否可用,不能再身体上
	function validFood(option){
		option = option || {};
		var flag = true;
		for(var i = 0; i < body.length; i++){
			if(option.x == body[i].x && option.y == body[i].y){
				flag = false;
				break;
			}
		}
		return flag;
	}
	
	//将原始坐标转化为canvas坐标
	function pointTransform(option,color){
		option = option || {};
		var obj = {
			config.gridX,
			height:config.gridY,
			color:color||''
		};
		obj.x = option.x * config.gridX;
		obj.y = option.y * config.gridY;	

		return obj;
	}
	
	//收集可用的参数列表
	function createOptionArr(){
		var arr = [];
		//身体
		for(var i = 0; i < body.length; i++){
			arr.push(pointTransform(body[i],'green'));
		}
		//食物
		if(food){
			arr.push(pointTransform(food,'pink'));	
		}
		
		
		//设置头部的颜色
		arr[0].color = 'red';
		return arr;
	}
	
	
	//游戏结束
	function gameOver(){
		alert('游戏结束');
		console.log('游戏结束');
	}
	
	
	//画所有
	function drawnAll(){
		ctx.clearRect(0,0,500,500);
		var arr = createOptionArr();
		for(var i = arr.length-1; i >= 0; i-- ){
			drawReat(arr[i]);
		}
	}
	
	//画矩形
	function drawReat(option){
		option  = option || {};
		var x = option.x;
		var y = option.y;
		var width = option.width;
		var height = option.height;
		var radius = option.radius||0;
		var color = option.color || 'green';
		var type = option.type || 'fill';
	    ctx.beginPath();
	    ctx.moveTo(x, y+radius);
	    ctx.lineTo(x, y+height-radius);
	    ctx.quadraticCurveTo(x, y+height, x+radius, y+height);
	    ctx.lineTo(x+width-radius, y+height);
	    ctx.quadraticCurveTo(x+width, y+height, x+width, y+height-radius);
	    ctx.lineTo(x+width, y+radius);
	    ctx.quadraticCurveTo(x+width, y, x+width-radius, y);
	    ctx.lineTo(x+radius, y);
	    ctx.quadraticCurveTo(x, y, x, y+radius);
	    ctx[type + 'Style'] = color;
	    ctx.closePath();
	    ctx[type]();
	} 

	//网格
	maxBound = drawGrip();
	function drawGrip(){
		var gridC = document.getElementById('gridC');
   		var gridCtx = gridC.getContext("2d");
		var width = gridC.width;
		var height = gridC.height;
		var gridX = config.gridX;
		var gridY = config.gridY;
		var maxBound = {
			x:0,
			y:0
		}
		//画横线
		for(var i = gridY; i < height; i=i+gridY){
			drawLine(gridCtx,0,i,width,i);
			maxBound.y++;
		}
		//画竖线
		for(var i = gridX; i < width; i = i + gridX){
			drawLine(gridCtx,i,0,i,height);
			maxBound.x++;
		}
		return maxBound;
	}
	
	function drawLine(ctx,startX,startY,endX,endY){
		ctx.lineWidth=1;
		ctx.beginPath();
		ctx.moveTo(startX,startY);
		ctx.lineTo(endX,endY);
		ctx.closePath();
		ctx.strokeStyle="#ddd";
		ctx.stroke();		
	}
	
</script>
</html>

  

原文地址:https://www.cnblogs.com/muamaker/p/8079172.html