HTML5 游戏开发实战 | 贪吃蛇

简介: 在该游戏中,玩家操纵一条贪吃的蛇在长方形场地里行走,贪吃蛇按玩家所按的方向键折行,蛇头吃到食物(豆)后,分数加10分,蛇身会变长,如果贪吃蛇碰上墙壁或者自身的话,游戏就结束了(当然也可能是减去一条生命)。

image.png


贪吃蛇游戏的运行界面如上图所示。

01、贪吃蛇游戏设计的思路

把游戏画面看成40×30的方格。食物(豆)和组成蛇的块均在屏幕上占据一个方格。游戏设计中主要用到的4个类如下。

Farm类:主要用来显示场地,随机生成食物,初始化一条蛇。

Food类:抽象了食物(豆)的属性和动作。

Snake类:抽象了贪吃蛇的属性和动作,调用Block类来组成蛇,并处理键盘输入事件和蛇的移动。

Block类:表示组成蛇的块(实心圆)。一条蛇可以看成由许多“块”(或称节)拼凑而成,块是蛇身上最小的单位。

02、贪吃蛇游戏设计的步骤

游戏页面index.html

<!DOCTYPE html>
<html lang = "en">
< head >
<meta charset ="UTF - 8"
< title>小游戏之贪吃蛇</title>
< style>
# canvas{
   
   border: 3px solid red;</style>
</head>
< body>
<canvas id='canvas'width=800'height =00'></canvas><div id="textmsg">分数</div>
</body >

设计脚本

1. 食物(豆)类(Food)设计

在此游戏中,首先会在场地的特定位置出现一个豆,豆要不断被蛇吃掉,当豆被吃掉后,原豆消失,又在新的位置出现新的豆。这些豆都是由豆(Food)类创建的对象。

foodInit()函数用于在屏幕上显示一个豆(实心圆),设计方法是直接在场地(canvas)上画一个实心圆。

equal()函数用于判断是否与蛇身“块”node重合,也就是蛇吃到食物。

//食物类
function Food(x,y,w) {
   
   
var t= this;
t.x=x;
t.y=y;
t.w=w;//食物
//X坐标
//Y坐标
//大小
t.foodInit = function() [
//画一个实心圆
ctx.beginPath();
ctx.arc(x+w/2,y+w/2,w/20360false);ctx.fillStyle="red";
//填充颜色,默认是黑色
//画实心圆
ctx.fill();
ctx.closePath();
//判断是否重合
t.equal = function(node) 
if(this.x == node.x && this.y== node.y) return true;else(
return false;

2. 块类(Block)

在贪吃蛇游戏中,块用来构成蛇,在蛇出现时,要把构成蛇的块一个个地输出(显示),在蛇消失时,要把块消除掉,显示和消除哪一个块都要由位置决定,并且由于蛇是由多个块构成的,每个块要填到snakes数组中。

//蛇块类
function Block(x,Y,w)(
var t = this;
t.x= x;
t.y=y;
t.w= w;
//画一个蛇块
t.drawBlock = function()
ctx.beginPath();
ctx.arc(x+w/2,y+w/2,w/20360false);
//填充颜色,默认是黑色
ctx.fillStyle="blue";
ctx.fill();
//画实心圆
//清除蛇块
t.clear = function()!
ctx.fillStvle=white';
ctx.strokeStyle = white';
ctx.fillRect(x,Y,w,w);
ctx.strokeRect(x,Y, w,w);
//判断是否重合
t.equal = function(node)
if(this.x== node.x && this.y== node.y){
   
   return true;
else
return false;

3. 蛇类(Snake)设计

现在到了最难的步骤,就是处理蛇,一条完整的贪吃蛇是由一块一块组成的。snakes数组用于存放组成蛇的所有块;其中保存的第一个元素是蛇的头部,最后一个元素是蛇的尾巴。当蛇运动的时候,它头部增加一块而尾部减少一块。如果它吃到了豆,头部增加一块而尾部不减少。也就是说,蛇是从头部开始长的。蛇运行过程中要不断地改变方向;如果蛇头碰到了它自身,蛇就要死亡,即程序结束。

首先,画一条蛇并移动它。

//蛇类
function Snake(x,y  len,speed) {
   
   
var t = this;
t.x=x;
t.y=y;
t.dir='R';
t.len = len;
//dir 方向,R'向右
var nx = x;ny =y;
//初始蛇最初 len(5)块,并启动定时
t.init = function()
for(var i=0;i< len; i++){
   
   
var tempBlock = new Block(nx,ny,gridWidth);tempBlock.drawBlock();nx-= gridWidth;
snakes.push(tempBlock);
snake interval = setInterval(t.move,speed);
//定时移动蛇

然后,识别键盘事件,修改移动方向dir,初始移动dir方向为'R'(向右)。

//取得键盘方向
document.onkevdown = function(e)
var code = e.keyCode;
t.odir = t.dir;
switch(code)
case 37:
t.dir='L';
break;case 38:
t.dir='u';break;
case 39:
t.dir='R';break;case 40 :
t.dir='D';
//向左键
//向上键
//向右键
//向下键
break;

以下主要是让蛇动的move()函数。主要是根据原来蛇头snakes[0]的位置和移动方向确定新的蛇头位置,绘制新的蛇头,并清除原来的蛇尾即达到移动效果。

在蛇移动时,判断蛇头是否和食物相撞,是否碰撞到了场地的壁以及是否与自己相撞。

//移动蛇
t.move = function()
var newHead;
//是否碰撞到了场地的壁
if(snakes0].x+ snakes0].w >= canvas.width snakes0].x- snakes0].w<0snakes[0].y- snakes[0].w < 0 snakes[0].y + snakes[0].w > canvas.height)(gameover();
else{
   
   //根据原来蛇头 snakes[0]的位置和移动方向确定新的蛇头位置
if(t.dir=='R'){
   
   newHead= new Block(snakes[0].x + gridWidth,snakes[0].y,gridWidth);) else if (t.dir =='L')(
newHead = new Block(snakes[0].x- gridWidth,snakes[0].y,gridWidth);else if (t.dir==D') !
newHead = new Block(snakes[0].x,snakes[0].y + gridWidth,gridWidth);else if (t.dir==u') !
newHead= new Block(snakes[0].x,snakes[0].y- gridwidth,gridWidth)
//禁止反向跑
if(newHead.x == snakes[1].x && newHead.y == snakes[1].y)t.dir = t.odir;return;
//画新的蛇头newHead.drawBlock();//追加到数组中(长度会自动加)snakes.unshift(newHead);//清除原来尾部snakes[snakes.length - 17.clear();//并从数组中移除(长度会自动减)snakes.pop()
//清除(蛇尾)块
/判断食物是否和蛇头相撞
for(var i=0;i< foods.length; i++)if(foods[ i].equal( snakes[0]))
//给蛇增加长度
t.growth();
score= score +10:
textmsq.innerHTML = score +“分”
t.len = t.len + 1;
//蛇生长方法
//增加 10 分
//显示分数
clearInterval(snake interval);
//速度加快snake interval = setInterval(t.move,speed);
speed = speed < 20 ? speed : speed -10;
//判断是否与自己相撞
for(var i=1;i< snakes.length; i++)if(snakesil.equal(snakes[0T)) gameover();
)//move()函数结束

用于实现蛇生长growth()函数的具体功能是当蛇吃到一个豆后,蛇就要在它的尾巴上增加一块即蛇增长。设计思路是找到蛇尾snakes[snakes.length-1],根据蛇尾与蛇的倒数第2块snakes[snakes.length-2]的位置关系,计算出蛇尾新增一块的位置。

//给蛇增加长度(在尾巴加)
t.growth = function() var tail1 = snakes[ snakes.length - 1]var tai12 = snakes[snakes.ength - 2];var addBlock;if(tai11.x== tai12.x) [if(tail1.y>= tail2.y)
addBlock =new Block(tail1.x,tail1.y + gridWidth,gridWidth);
else
addBlock =new Block(tail1.x,tail1.y-gridWidth,gridWidth);
else
if(tai11.x>= tail2.x)
addBlock =new Block(tail1.x + gridWidth,tail1.y,gridWidth);
else
addBlock =new Block(tail1.x-gridWidth,tail1.y,gridWidth);
//数组加入尾部
snakes.push(addBlock);addBlock.drawBlock();
console.log(snakes.length);
)//growth()函数
* snake 类结束 */

4. 场地类(Farm)设计

为游戏的主场地,豆要在此范围内出现,蛇要在此范围内运行,显示场地内的所有对象、场地边框、豆和蛇。

//场地类,生成一个画布和豆、蛇
function Farm()
var t = this;
ctx.fillStyle ='white';
ctx.fillRect(00,canvas.width,canvas.height);foods =l;//随机生成一个食物t.addfood = function()var x= parseInt(canvas.width / gridWidth * Math.random()) * gridWidth;var y=parseInt(canvas.height / gridWidth * Math.random()) * gridWidth;var food = new Eood(x,y,gridWidth);food.foodInit();
//重新初始化豆数组,不要把前一次游戏的数组元素遗留
foods.push(food);
//重新初始化蛇身(块)数组,不要把前一次游戏的数组元素遗留snakes =;//更新速度 500 毫秒(即移动速度)
t.snake= new Snake(1001005500); //初始 5 节长度,位置(100,100)处//画蛇t.snake.init();

5. 主程序

在游戏开始后,要首先初始化场地Farm类,显示场地内的所有对象,场地边框、豆和蛇。同时要2秒随机产生一个新豆并显示。

var canvas = document.getElementById("canvas”)
var ctx = canvas.getContext( 2d');
var gridWidth = 20;
var score = 0;
var foods = new Array(),snakes = new Array();//开始游戏
function gameStart(
var farm = new Farm();
//放豆和蛇的数组
//2 秒产生一个豆
food interval = setInterval(farm.addfood,2000);
gameStart();
//结束
function gameover()var judge = confirm("游戏结束,是否重新开始”);score =0;
textmsg.innerHTML = score +“分clearInterval(snake interval);
//清除产生蛇移动定时
//清除产生新豆定时
clearInterval(food interval);
if(!judge){
   
   
//选择不重新开始
return false;
gameStart();

至此,贪吃蛇游戏编写完成。

目录
相关文章
|
2月前
|
移动开发 HTML5
html5掷骰子跳棋游戏源码
html5掷骰子跳棋游戏源码
42 1
html5掷骰子跳棋游戏源码
|
22小时前
|
前端开发 UED
【专栏:HTML与CSS实战项目篇】创建一个具有复杂布局的电商详情页
【4月更文挑战第30天】构建复杂布局的电商详情页涉及页面结构规划、样式设计和交互效果实现。首先规划顶部导航栏、商品图片展示区、商品信息区、用户评价区和相关商品推荐区。在样式设计上,注重色彩搭配、字体选择、布局与间距及图片处理。交互效果包括图片放大、添加到购物车按钮、滚动监听和评论互动,以提升用户体验。实际开发中需考虑跨设备兼容性和用户体验优化。
|
22小时前
|
移动开发 前端开发 JavaScript
【专栏:HTML与CSS实战项目篇】使用HTML5与CSS3制作一个动态表单验证页面
【4月更文挑战第30天】本文介绍了使用HTML5和CSS3创建动态表单验证页面的方法。首先,简述HTML5用于构建网页内容,CSS3用于描述样式。接着,分四步展示实现过程:1) 设计包含输入框和提示信息的表单结构;2) 使用CSS3创建样式,增强视觉效果;3) 使用JavaScript监听输入事件,动态验证表单并显示错误信息;4) 测试和调试确保跨平台兼容性。通过学习,开发者能掌握创建带验证功能的表单,提升用户体验。
|
22小时前
|
编解码 前端开发 JavaScript
【专栏:HTML与CSS实战项目篇】打造一个动态新闻网站
【4月更文挑战第30天】构建动态新闻网站,运用HTML和CSS提升编程技能和网页设计理解。项目包括首页、新闻列表页和详情页,设计简洁易用,包含顶部导航、轮播图和新闻列表。页面布局注重吸引力和易用性,色彩搭配选用冷色调为主,辅以亮色点缀。字体选择清晰易读,布局保持整洁。交互效果如轮播图、导航栏高亮和响应式设计增强用户体验。本文提供基础新闻网站构建指南,为进一步功能扩展和优化打下基础。
|
22小时前
|
前端开发 测试技术 定位技术
【专栏:HTML 与 CSS 实战项目篇】构建一个企业级网站:HTML 与 CSS 实战
【4月更文挑战第30天】本文介绍了使用HTML和CSS构建企业级网站的实战步骤,包括项目概述、页面结构设计、HTML结构搭建、CSS样式设计、具体页面实现、优化与提升。通过合理布局、美观样式和响应式设计,创建现代、简洁的网站,包含主页、关于我们、产品展示、新闻动态和联系我们等页面。优化图片和代码,确保性能,助力企业在数字时代树立良好形象并提升沟通效率。
|
23小时前
|
编解码 前端开发 UED
【专栏:HTML与CSS实践篇】响应式网站开发实战
【4月更文挑战第30天】本文探讨了响应式网站开发,它能根据用户设备自动调整布局,提供最佳浏览体验。通过HTML和CSS,利用媒体查询、Flexbox和百分比宽度等技术实现响应式设计。媒体查询按屏幕尺寸定义CSS规则,Flexbox处理元素排列。文章通过新闻网站首页设计实例,展示了如何应用这些理论,包括使用Flexbox设计导航栏,使用媒体查询调整轮播图和内容区域,以及创建自适应页脚。遵循移动优先原则,关注性能优化和用户体验,响应式设计是前端开发的关键,为多设备用户提供优质浏览体验。
|
3月前
|
安全 Windows
在线网页版扫雷游戏HTML源码
在线网页版扫雷游戏HTML源码
54 1
在线网页版扫雷游戏HTML源码
|
4月前
|
前端开发
前端实战_手撕HTML、CSS
前端实战_手撕HTML、CSS
|
4月前
|
JavaScript
基于js和html的骰子游戏
基于js和html的骰子游戏
23 0
|
4月前
|
前端开发 JavaScript
html+css+js开发一个猜数字游戏
【1月更文挑战第5天】html+css+js开发一个猜数字游戏
38 1