大学生的小乐趣:html画布制作贪吃蛇小游戏

最终效果:

大学生的小乐趣:html画布制作贪吃蛇小游戏_第1张图片

做贪吃蛇游戏需要Html5,部分Css美化,重要的是JavaScript的应用,因为我们主要是运用Html5的Canvas标签来打造游戏的,所以还是在JavaScript上的笔墨较多

首先搭建好框架:

 

 



	snake

	


	

然后在javascript代码区创建画布Dom对象:

 

	var canvas = document.getElementById('mycanvas');
	var ctx = canvas.getContext('2d');var canvas = document.getElementById('mycanvas');
	var ctx = canvas.getContext('2d');


创建蛇对象:

 

 

	var snake = {
		head : { x : 15 * 3, y : 0 },
		body : [{ x : 15 * 2, y : 0 },{ x : 15 * 1, y : 0 },{ x : 0, y : 0 }],
		speed : 100,
		direction: "right",
	};


注意点:蛇对象中的body是一个数组,数组内的元素是代表蛇每个节在画布上的X坐标和Y坐标,snake.body[0]为最靠近head的节,依此类推。。

 

 

描绘蛇:

 

	function drawSnake(){
		ctx.clearRect( 0, 0, 450, 450 );
		var headImg = new Image();
		var headSrc = "./snake_head_min_" + snake.direction +".png";/*存贮蛇图片的位置,用于动态改变head的图片位置*/
		headImg.src= headSrc;
		ctx.drawImage(headImg, snake.head.x, snake.head.y );
		for( var i = 0; i <= snake.body.length - 1; i++){
			var cell = new Image();
			cell.src = "./snake_body_min.png";
			ctx.drawImage(cell, snake.body[i].x, snake.body[i].y );
		}
	}

 

注意点:

 

1.每次描绘蛇之前都需要将原有的图画清空------ ctx.clearRect( 0, 0, 450, 450);  clearRect()用法详见:HTML5 canvas clearRect() 方法;

2.这里我采用的不是填充矩形的方法来实现画蛇,而是采用描绘图像的方法: 用法详见:HTML 5 标签

1)创建图像:var Img = new Image();

2)图像位置:Img.src="./img.png";

3)开始描绘:ctx.drawImage( Img, 0, 0);后两个参数表示的是描绘图片的x坐标的y坐标;

在这里我采用了自己制作的图片,注意要调整图片的大小(为展示,此处显示大图):

大学生的小乐趣:html画布制作贪吃蛇小游戏_第2张图片             大学生的小乐趣:html画布制作贪吃蛇小游戏_第3张图片

body head

因为蛇头有方向:所以对于head我们有四张图片:

大学生的小乐趣:html画布制作贪吃蛇小游戏_第4张图片

 

创建食物对象:

 

	var food = {
		x : 300,
		y : 150,
	};

 

 

x , y 代表食物在画布的x坐标和y位置。

 

描绘食物:

 

	function drawFood(){
		if(IsEat()){
			food.x = parseInt(Math.random() * 28) * 15;
			food.y = parseInt(Math.random() * 28) * 15;
		}
		var foodImg = new Image();
		foodImg.src="./apple_min.png";
		ctx.drawImage(foodImg, food.x, food.y );
	}function drawFood(){
		if(IsEat()){
			food.x = parseInt(Math.random() * 28) * 15;
			food.y = parseInt(Math.random() * 28) * 15;
		}
		var foodImg = new Image();
		foodImg.src="./apple_min.png";
		ctx.drawImage(foodImg, food.x, food.y );
	}


注意点:

 

1.关于获取随机数:Math.random();该函数返回一个区间为(0, 1 )的随机数;

2.此处我们将随机数乘以28以放大随机数的区间为(0, 28 ),总共的格子数为30 * 30 个 即450 / 15 = 30;

3.我们将其随机数的区间转化为整数:即1,2,3,4,。。。,27,

4.当food 被蛇吃的时候(snake.head的坐标与食物的坐标相同的时候),我们要随机在生成新的食物坐标,此处不考虑食物生成的坐标与蛇的身体有相同(食物生成在了蛇的body上)

 

判断食物是否被吃:

 

	function IsEat(){
		if( snake.head.x == food.x && snake.head.y == food.y){
			snake.body[snake.body.length] = { x : 0, y : 0};
			return 1;
		}
		return 0;
	}


注意点:

 

1.此处用了if判断语句,且判断的表达式需满足 蛇的头的坐标与食物的坐标相同(x坐标和y坐标);

2.为了在描绘食物的方法(drawFood();)里更好的判断,我们设置返回值 1 代表被吃,0代表未被吃;

3.食物被吃之后应该生成一个新的节(此处默认生成的节懂得x坐标和y坐标都为0(这个不要紧)在蛇移动的时候会自动改变该值)

snake.body[snake.body.length] = { x : 0, y : 0};

 

 

开始重头大戏----移动蛇:

首先移动蛇我们需要的是:不断地描绘图像,并且不断的更新蛇的头的身体各节的坐标:

代码上:

 

	function moveSnake(){
		for( var i = snake.body.length - 1; i > 0 ; i-- ){
				snake.body[i].x = snake.body[i - 1].x;
				snake.body[i].y = snake.body[i - 1].y;
			}
			snake.body[0].x = snake.head.x;
			snake.body[0].y = snake.head.y;
		switch( snake.direction ){
			case "right":{
				snake.head.x = snake.head.x + 15;
				break;
			} 
			case "left":{
				snake.head.x = snake.head.x - 15;
				break;
			}
			case "up":{
				snake.head.y = snake.head.y - 15;
				break;
			}
			case "down":{
				snake.head.y = snake.head.y + 15;
				break;
			}
		}
		drawSnake();
		drawFood();
		IsGameover();
		setTimeout( 'moveSnake()', snake.speed );
	}


注意点:

 

1.为了达到更新蛇的头和蛇的身体各节坐标的目标,我们的想法应该是:较后的节继承较前的节的坐标;所以就有for循环:

 

			for( var i = snake.body.length - 1; i > 0 ; i-- ){
				snake.body[i].x = snake.body[i - 1].x;
				snake.body[i].y = snake.body[i - 1].y;
			}
			snake.body[0].x = snake.head.x;
			snake.body[0].y = snake.head.y;for( var i = snake.body.length - 1; i > 0 ; i-- ){
				snake.body[i].x = snake.body[i - 1].x;
				snake.body[i].y = snake.body[i - 1].y;
			}
			snake.body[0].x = snake.head.x;
			snake.body[0].y = snake.head.y;

最靠近头的节将继承头的坐标。

 

2.针对头的坐标更新我们根据蛇的方向(snake.direction)来进行判断:

 

switch( snake.direction ){}

 

 

 

3.在移动蛇的时候,我们需要不断的画蛇,不断的画食物,不断的判断是否结束游戏,并且我们需要不断的调用自己这个函数;

更新时间我们用setTimeout();用法详见:HTML DOM setTimeout() 方法

 

判断GameOver:

判断游戏结束有两个标准:

1.碰壁,游戏结束

2.吃着自己,游戏结束

 

代码上:

 

	function IsGameover(){
		if(snake.head.x == game.width && snake.direction == 'right'){
			alert("GameOver!");
		}
		if(snake.head.x == -15 && snake.direction == 'left'){
			alert("GameOver!");
		}
		if(snake.head.y == game.height  && snake.direction == 'down'){
			alert("GameOver!");
		}
		if(snake.head.y == -15 && snake.direction == 'up'){
			alert("GameOver!");
		}
		for( var i = 0; i < snake.body.length; i++ ){
			if( snake.head.x == snake.body[i].x && snake.head.y == snake.body[i].y){
				alert("GameOver!");
			}
		}
	}


注意点:

 

1.四个if判断语句用于判断碰壁:!!满足条件为 坐标 和 蛇的移动方向(例如 蛇的head的x坐标为0,方向向上  =》 碰壁)

2.for循环语句:对每个body的节判断其坐标是否与head的坐标重合(重合即代表 蛇头吃到自己的身体了)

 

监听键盘输入:

 

	document.onkeydown = function(e){
		var code = e.keyCode;
		switch(code){
			case 38:{
				if( snake.direction != 'down'){
					snake.direction='up';
				}
				break;
			}
			case 39:{
				if( snake.direction != 'left'){
					snake.direction='right';
				}
				break;
		}
			case 40:{
				if( snake.direction != 'up'){
					snake.direction='down';
				}
				break;
			}
			case 37:{
				if( snake.direction != 'right'){
					snake.direction='left';
				}
				break;
			}
			default:break;
		}
	}


注意点:

 

1.html Dom document对象的onkeydown事件后的函数需要引入参数(e)

2.对该事件(event)的键盘值(keyCode)进行判断然后改变蛇的方向--snake.direction;

 

该游戏的制作就完成了,当然我们也可以把它可以做的更好。

 

最后上完整代码:

 




	snake

	


	

 

 

图片资源:

     
 

本文中的超链接指向W3school

 

 

 

 

你可能感兴趣的:(网页前端)