html画布制作贪吃蛇小游戏
来源:互联网 发布:linux 目录别名 编辑:程序博客网 时间:2024/04/30 15:01
最终效果:
做贪吃蛇游戏需要Html5,部分Css美化,重要的是JavaScript的应用,因为我们主要是运用Html5的Canvas标签来打造游戏的,所以还是在JavaScript上的笔墨较多
首先搭建好框架:
<!DOCTYPE html><html><head><title>snake</title><style type="text/css">#canvas_frame{height:500px;width:500px;margin:auto;background:#444;border-radius:8px;box-shadow:0px 0px 15px #000;}canvas{background:#21F;margin:25px 25px;}#start_button{height:40px;width:150px;border:0px;background:#000;color:white;line-height:40px;font-size:15px;}</style></head><body><div id="canvas_frame"><canvas id="mycanvas" width="450" height="450"></canvas></div><section style="height:40px;width:100%;text-align:center;"><button id="start_button" onclick="moveSnake();">start</button></section><script type="text/javascript">/*javascript代码区*/</script></body></html>
然后在javascript代码区创建画布Dom对象:
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 <canvas> 标签
1)创建图像:var Img = new Image();
2)图像位置:Img.src="./img.png";
3)开始描绘:ctx.drawImage( Img, 0, 0);后两个参数表示的是描绘图片的x坐标的y坐标;
在这里我采用了自己制作的图片,注意要调整图片的大小(为展示,此处显示大图):
body head
因为蛇头有方向:所以对于head我们有四张图片:
创建食物对象:
var food = {x : 300,y : 150,};
描绘食物:
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;最靠近头的节将继承头的坐标。
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;
该游戏的制作就完成了,当然我们也可以把它可以做的更好。
最后上完整代码:
<!DOCTYPE html><html><head><title>snake</title><style type="text/css">#canvas_frame{height:500px;width:500px;margin:auto;background:#444;border-radius:8px;box-shadow:0px 0px 15px #000;}canvas{background:#21F;margin:25px 25px;}#start_button{height:40px;width:150px;border:0px;background:#000;color:white;line-height:40px;font-size:15px;}</style></head><body><div id="canvas_frame"><canvas id="mycanvas" width="450" height="450"></canvas></div><section style="height:40px;width:100%;text-align:center;"><button id="start_button" onclick = "moveSnake();">start</button></section><script type="text/javascript">var canvas = document.getElementById('mycanvas');var ctx = canvas.getContext('2d');/*//画格子 ctx.strokeStyle = 'white';for( var i = 1; i <= 30; i++ ){ctx.beginPath();ctx.moveTo( 15 * i, 0 );ctx.lineTo( 15 * i, 450 );ctx.closePath();ctx.stroke();}for( var i = 1; i <= 30; i++ ){ctx.beginPath();ctx.moveTo( 0, 15 * i );ctx.lineTo( 450, 15 * i );ctx.closePath();ctx.stroke();}*///创建游戏对象var game = {width : 450,height : 450,};//创建一条蛇var snake = {head : { x : 15 * 3, y : 0 },body : [{ x : 15 * 2, y : 0 },{ x : 15 * 1, y : 0 },{ x : 0, y : 0 }],length : 4,speed : 100,direction: "right",};//创建食物var food = {x : 300,y : 150,color : "green",};//描绘蛇function drawSnake(){ctx.clearRect( 0, 0, 450, 450 );var headImg = new Image();var headSrc = "./snake_head_min_" + snake.direction +".png";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 );}}//描绘食物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 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 );}//判断游戏结束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!");}}}//监听键盘输入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;}}//判断是否吃了食物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;}</script></body></html>
本文中的超链接指向W3school
- html画布制作贪吃蛇小游戏
- 【小游戏】C++手工制作贪吃蛇
- 利用unity 制作贪吃蛇小游戏
- Day02 骚年,玩蛇吗?(制作小游戏贪吃蛇)
- html 5 (javascript) 17行代码,贪吃蛇小游戏
- 小游戏 贪吃蛇
- 贪吃蛇小游戏
- 贪吃蛇小游戏
- 贪吃蛇小游戏
- Applet贪吃蛇小游戏
- 贪吃蛇小游戏记录:
- 贪吃蛇小游戏笔记
- [小游戏]贪吃蛇
- 经典贪吃蛇小游戏
- 贪吃蛇小游戏~
- 【java】贪吃蛇小游戏
- 【java】贪吃蛇小游戏
- javascript贪吃蛇小游戏
- 星月蓝图
- pomelo(十)英文文档首页
- luogu P2368 EXCEEDED WARNING B
- 12进制和20进制计数器用verilog语言实现
- POJ
- html画布制作贪吃蛇小游戏
- Echarts初探
- C#子线程执行完后通知主线程
- 【干货】人工智能工程师的三个层次(附技术学习路线图)
- 如何准确搜索?
- javascript函数的静态加载与动态执行
- JAVA 注解的几大作用及使用方法详解
- laravel框架validator验证使用
- 基于日志的同步数据一致性和实时抽取