html贪吃蛇游戏编程,html5贪吃蛇小游戏设计与实现

  html贪吃蛇游戏编程,html5贪吃蛇小游戏设计与实现

  本文为您带来了一个如何使用JavaScript实现贪吃蛇游戏的例子。希望对你有帮助。

  

JavaScript实现贪吃蛇小游戏

  

功能概述

  该程序实现以下功能:

  吃蛇的基本功能

  统计分数

  开始和暂停

  选择难度等级

  设置快捷键

  5.1通过ijkl,wsad也可以实现方向切换。

  5.2“P”表示暂停,“C”表示开始或继续,“R”表示重新开始。

  

实现过程

  最初的实现原理其实是引用csdn的一位大神。他用20行JavaScript实现了吃蛇者的基本功能。可贵的是现在还没有bug。链接在这里。

  实现贪吃蛇大概有以下几个步骤:

  画一条蛇的移动区域。

  画一条蛇

  画食物

  让蛇动起来。

  制定游戏规则

  设定难度等级

  设置和暂停

  设置游戏结束后的后续动作。

  实现人机交互页面

  

画蛇的活动区域

  首先我们画蛇的活动区域,我们用JavaScript canvas来画。

  我们用一个400400 400 \乘以400400400的面积作为蛇的活动区域。

  canvas ID= canvas width= 400 height= 400 /canvas还通过CSS设置一条边界线

  #画布{

  边框:1px solid # 000000/*设置边框线*/}

画蛇和食物

  效果如下:

  在画蛇之前,我们需要思考一下蛇的数据结构。这里,我们以最简单的队列来代表蛇。

  队列头表示蛇头的位置,队列尾表示蛇尾的位置。

  我们之前画的。

  名流

  名流

  400 \乘以400

  400400区域分为400个区域。

  20

  20

  20 \乘以20

  2020个方块,而这些方块是用来组成蛇的,所以蛇所在的方块的位置的取值范围是0~399。

  例如:

  var snake=[42,41,40];上面的代码表示蛇的位置是42,41和40格,其中蛇头是42,蛇尾是40。

  对于食物,我们可以用一个变量food来存储食物的位置。食物的取值范围是0~399,不包括蛇的部分。由于游戏中需要随机生成食物,随机函数实现如下:

  //生成一个min~max的随机整数,用于随机生成食物函数random(min,max) {

  const num=math . floor(math . random()*(max-min))min;

  退货数量;}当食物被蛇吃掉后,需要再次刷新。由于食物不能出现在蛇的位置,我们使用while循环,当食物的位置不在蛇的数组中时,我们跳出循环。

  而(snake.indexOf((food=random(0,400)))=0);//再次刷新食物,注意食物不要在蛇里面。接下来,我们将通过画布来绘制它。

  首先,在js中获取canvas组件

  const canvas=document . getelementbyid( canvas );const CTX=canvas . get context( 2d );然后写画图函数画方块。画正方形的时候注意我们预留了1px作为边框,也就是我们画的正方形的边长是18,我们实际上填充的是18 18 \乘以1818 18的正方形。方块(方块左上角)的x,y坐标的计算也要注意加1px。

  //用于绘制蛇或食物代表的正方形,seat是正方形位置,取值为0~399,color是颜色函数draw(seat,color) {

  ctx.fillStyle=color//填充颜色

  fillrect的四个参数分别代表要绘制的正方形的X坐标、Y坐标、长和宽。这里1px是为了美观而预留给边框的。

  ctx.fillRect(

  (座位% 20) * 20 1,

  Math.floor(座位/20) * 20 1,

  18,

  18

  );}

让蛇动起来

  如果我们想让蛇动起来,首先需要规定蛇运动的方向。我们用一个可变的方向来表示蛇的运动方向。其取值范围为{1,-1,20,-20}。1表示向右,-1表示向左,20表示向下,-20表示向上。移动的时候,我们只需要把蛇头的

  那么如何让蛇动起来呢?对于蛇的每一个动作,我们都需要完成以下基本操作:

  将蛇移动的下一个位置换成新的蛇头,将下一个位置加入蛇队列,用浅蓝色画下一个方块,将老蛇头换成蛇身,用浅灰色画老蛇头,删除老蛇尾,弹出蛇队列,用白色画老蛇尾。当蛇吃食物时(蛇的下一个位置就是食物所在的位置),需要更新食物位置,用黄色画出新的食物。此时不需要删除旧的蛇尾,可以实现蛇吃完食物后增加长度的功能。

  我们需要编写一个函数来实现上述操作,并不断调用这个函数,从而刷新页面,这就是我们所说的动态效果。

  n=snake[0]方向;//找到新的蛇头坐标snake . un shift(n);//添加新的snake draw(n, # 1 A8 DCC );//将新的蛇头绘制为浅蓝色draw (snake [1], # ceccc );//将原来的蛇头(浅蓝色)改成蛇身(浅灰色)if (n==food) {

  而(snake.indexOf((food=random(0,400)))=0);//再次刷新食物,注意食物不要在蛇里面

  画(食,‘黄’);//画食物}否则{

  draw(snake.pop(), White );//把原来的蛇尾巴画成白色}接下来我们需要通过键盘控制蛇的移动。

  我们需要获取键盘的键值,然后通过一个监听函数监听键盘的按下操作。这里我们用上、下、左、右键(我们还扩展了WSAD键和IJKL键来控制上、下、左、右方向),设置一个变量N来表示下一个方向。

  //用来绑定键盘上、下、左、右事件,上、下、左、右箭头键,分别代表上、下、左、右四个方向。document . onkeydown=function(event){

  const key code=event . key code;

  if (keycode=40) {

  //向上38向下40向左37向右39

  n=[-1,-20,1,20][keycode - 37] 方向;//如果键码是另一个值,说明按了没用的键,方向不变。

  } else if (keycode=76 keycode=73) {

  //i 73 j 74 k 75 l 76

  n=[-20,-1,20,1][keycode - 73] 方向;

  }否则{

  开关(键码){

  案例87: //w

  n=-20;

  打破;

  案例83: //s

  n=20

  打破;

  案例65: //a

  n=-1;

  打破;

  案例68: //d

  n=1;

  打破;

  默认值:

  n=方向;

  }

  }

  方向=蛇[1] -蛇[0]==n?方向:n;//如果方向与原方向相反,则方向不变};

设定游戏规则

  贪吃蛇最基本的游戏规则如下:

  如果蛇撞到墙或蛇的身体或尾巴,游戏就结束了。如果蛇吃了食物,蛇的长度会增加(前一步已经达到),分数也会增加。先实现第一个,如下:

  //如果(

  snake.indexOf(n,1) 0

  n 0

  n 399

  (方向==1 n % 20==0)

  (方向==-1 n % 20==19)) {

  game_over()。}接下来,我们实现分数统计。对于分数的计算,我们只需要设置一个变量,score,来统计分数。然后我们每吃一个食物,变量就加一,然后分数信息就更新到网页上相应的位置。

  得分=分数1;Score_cal.innerText=当前分数:分数;//更新分数

设置难度等级

  我们在网页上设置一个单选框来设置难度等级。

  表单操作= id=mode_form

  难度等级:

  输入类型= radio name= mode id= simplely value= simplely checked/

  =simply 简单的标签/标签

  输入类型= radio name= mode id= middle value= middle /

  的标签=中间中间/标签

  输入类型= radio name= mode id= hard value= hard /

  Label= hard 难/label/form效果如下:

  那么我们如何在后台设置难度等级的功能呢?

  我们取调用蛇动函数的时间间隔,而不是难度。时间间隔越小,难度越大。我们可以把它分为三个层次:简单、中级和困难。

  我们创建一个时间间隔变量time_internal,然后用一个函数获取单选框的值,将对应模式的时间间隔赋给time_internal。

  //用刷新间隔来表示蛇的速度。刷新间隔越长,蛇的速度越慢。const simply _ mode=200const middle _ mode=100const hard _ mode=50var time _ internal=simply _ mode//刷新时间间隔,用来调整snake的速度。默认为简单模式。//同步难度等级函数syncMode() {

  var mode _ value=“”;

  for(var I=0;i mode _ item.lengthi ) {

  if (mode_item[i].已检查){

  模式值=模式项[i]。价值;

  }

  }

  开关(模式值){

  case simply :

  time _ internal=simply _ mode

  打破;

  案例“中间”:

  time _ internal=middle _ mode

  打破;

  案例“困难”:

  时间_内部=硬模式;

  打破;

  }}}最后,你只需要在蛇每次移动之前调用一次上面的函数syncMode()就可以实现难度切换了。至于蛇的速度具体怎么调整,看下面怎么解释。

  

设置开始与暂停

  如何实现蛇动的动态效果,如何暂停,如何继续,如何调节速度。这就涉及到JavaScript动画的部分。建议看《JavaScript高级程序设计(第4版)》第十八章的部分,很详细。

  在最初的“20行JavaScript实现snake”中,并没有实现开始和暂停,而是通过设置一个立即执行函数来实现动态效果!function(){ }();然后在这个函数中使用SetTimeout (arguments.callee,150);这个函数每隔0.15秒调用一次,从而实现网页的持续刷新,称为动态效果。

  后来从一个web课程老师(弹球游戏)的案例中得知requestAnimationFrame方法可以达到动画效果,于是查询了百度。最后,我受到了《JavaScript高级程序设计(第4版)》这本书第18章的动画和画布图形的启发——如何开始和取消,如何自定义时间间隔(难度调整,蛇速)。

  书中给出的启动和取消动画的方法如下:

  var requestID//用于标记请求ID和取消动画

  函数updateProgress() {

  //做点什么.

  request id=requestAnimationFrame(update progress);//调用后在函数中反复调用函数

  }

  id=requestAnimationFrame(update progress);//第一次调用(即启动动画)

  cancelAnimationFrame(request id);//取消动画书讲述:

  书中还给出如何控制时间间隔的方法:

  该书讲述了:

  具体方法如下:

  让enabled=true函数expensiveOperation() {

  console.log(调用于,date . now());} window . addevent listener( scroll ,()={

  如果(启用){

  enabled=false

  requestAnimationFrame(expensive operation);

  setTimeout(()=enabled=true,50);

  } });受上面方法的启发,这里我们可以设置一个控制函数,用来控制每隔一段时间调用蛇运动的函数。实现如下:

  //控制游戏的刷新频率,每隔time_internal {

  如果(启用){

  enabled=false

  requestAnimationFrame(run _ game);

  setTimeout(()=enabled=true,time _ internal);

  }

  run _ id=requestAnimationFrame(game _ control);}//启动或继续游戏函数run_game() {

  sync mode();//同步难度级别

  n=snake[0]方向;//找到新蛇头的坐标

  snake . un shift(n);//添加新的蛇头

  //确定蛇头是撞到自己还是越界。

  如果(

  snake.indexOf(n,1) 0

  n 0

  n 399

  (方向==1 n % 20==0)

  (方向==-1 n % 20==19)

  ) {

  game_over()。

  }

  draw(n, # 1a 8 DCC );//将新的蛇头绘制为浅蓝色

  draw(snake[1], # cece cc );//将原来的蛇头(浅蓝色)改为蛇身(浅灰色)

  if (n==food) {

  得分=分数1;

  Score_cal.innerText=当前分数:分数;//更新分数

  而(snake.indexOf((food=random(0,400)))=0);//再次刷新食物,注意食物不要在蛇里面

  画(食,‘黄’);//画食物

  }否则{

  draw(snake.pop(), White );//将原来的蛇尾画成白色

  }

  //setTimeout(arguments.callee,time _ internal);//之前的方案无法实现游戏的暂停和继续}至于暂停,只需要在特定位置调用cancelAnimationFrame(run _ id);就是这样。

  

设置游戏结束后续操作

  我在想的是,比赛结束后会出现一个“弹窗”,显示最后的比分,以及是否再玩一次。

  效果如下:

  首先,我们实现网页的弹出窗口。通过调查,我们发现JavaScript弹出窗口可以通过alert()来实现。但是网页上的直接弹窗感觉不美观,影响体验。于是我想了想,可以用一个P标签来实现伪弹出,需要显示的时候设置它的显示属性为block,不需要显示的时候设置它的显示属性为none。它类似于Photoshop中图层的概念,所以我们可以在平时将其显示属性设置为none,在触发game over时将其显示属性设置为block。实现如下:

  p id=游戏结束

  H3= Game _ over _ text align= center 游戏结束了!/h3

  H3= game _ over _ score align= center 您的最终得分是:0 /h3

  Button id=once_again 再来一次/button

  button id= Cancel Cancel/button/p其CSS部分如下:

  #游戏结束{

  显示:无;/*将游戏窗口设置为不可见*/

  位置:固定;

  top:190 px;

  左:65px

  宽度:280px

  高度:160px

  背景色:aliceblue

  边框半径:5px

  边框:1px纯色# 000;/*设置边框线*/}#once_again {

  位置:相对;

  左:20px} #取消{

  位置:相对;

  左:50px}接下来我们需要实现game over的后续操作:暂停动画,显示比分,显示“弹出窗口”

  函数game_over(){

  cancelAnimationFrame(run _ id);

  Game_over_score.innerText=您的最终分数是: score points

  game _ over _ p . style . display= block ;}

实现人机交互页面

  接下来的部分是改善用户体验的部分,具体实现以下功能/操作。

  解释游戏的人机交互按钮:开始/继续、暂停、重启快捷键。由于时间太慢,无法在游戏过程中通过移动鼠标到暂停按钮来暂停,游戏可能会被终止。所以你要设置开始/继续(C)、暂停(P)、重启(R)的快捷键。有的电脑键盘上上下左右键都很小,操作不方便。您可以添加WSAD或IJKL扩展来控制上,下,左,右方向。

  至于写接口的代码,可以在文末看到完整的代码。这里,我们将稍微解释一下绑定按钮click事件和绑定快捷键。

  首先,我们来看绑定按钮点击事件。点击“开始/继续”,只需调用request animation Frame(game _ control);点击“暂停”,就调用cancelAnimationFrame(run _ id);

  //绑定开始按钮,点击事件start_btn.onclick=function () {

  run _ id=requestAnimationFrame(game _ control);};//点击事件pause_btn.onclick=function () {

  cancelAnimationFrame(run _ id);};如果点击“重新开始”,需要先暂停动画,然后删除屏幕上的蛇和食物,初始化所有设置,再调用request animation Frame(game _ control);开始游戏

  //函数init_game() {

  snake=[41,40];

  方向=1;

  食物=42;

  得分=-1;

  time _ internal=simply _ mode

  enabled=true

  Score_cal.innerText=当前分数:0 ;//更新分数

  模式项目[0]。选中=真;//将难度重置为simple }//绑定重启按钮,点击事件restart _ BTN . onclick=function(){

  cancelAnimationFrame(run _ id);

  //用白色画出原来的食物和蛇方块。

  for(var I=0;我蛇.长度;i ){

  draw(蛇[i],白);

  }

  画(食,‘白’);

  //初始化游戏的各种参数

  init _ game();

  run _ id=requestAnimationFrame(game _ control);};接下来,我们将游戏中的两个键绑定在“再来一次”和“取消”上

  “只需再次重启中完成事件”,取消,“只需完成重启”,点击除游戏开始外的部分操作,即除run _ id=request animation Frame(game _ control);

  这两个按钮都需要将弹出窗口的显示属性设置为none。

  具体实现如下:

  //在事件cancel_btn.onclick=function () {

  for(var I=0;我蛇.长度;i ){

  draw(蛇[i],白);

  }

  画(食,‘白’);

  init _ game();

  game _ over _ p . style . display= none ;}//再一次绑定游戏结束时的按钮点击事件once _ again _ BTN . onclick=function(){

  for(var I=0;我蛇.长度;i ){

  draw(蛇[i],白);

  }

  画(食,‘白’);

  init _ game();

  game _ over _ p . style . display= none ;

  run _ id=requestAnimationFrame(game _ control);}最后,我们来说明一下快捷键的设置方法。快捷键只需要通过JavaScript模拟点击相应的按钮,实现如下:

  //同时绑定R重启,P暂停,C继续document . onkeydown=function(event){

  const key code=event . key code;

  if(keycode==82){

  //R重新启动

  restart _ BTN . onclick();

  } else if(keycode==80){

  //P暂停

  pause _ BTN . onclick();

  } else if(keycode==67){

  //C继续

  start _ BTN . onclick();

  } };

问题、调试与解决

  问题1:点击暂停开始,游戏正常开始。按P暂停。按C,蛇所在的方块跳起来。不能正常启动,但是按C只模拟“开始/继续”按钮的点击?

  效果如下:

  调试过程:因为蛇头的位置是由方向控制的,所以想到了设置一个断点,监测这个变量的值的变化。我发现这个值在按下P和C之后被更新到了一个非常大的数字,然后去找方向更新到了哪里。我发现点击P或者C后需要执行下面一行代码,其实没必要。

  方向=蛇[1] -蛇[0]==n?方向:n;//如果方向与原方向相反,则方向不变。解决方法:你只需要在相应的按钮事件上执行相应的模拟鼠标点击然后直接返回。

  原始代码和修改后的代码如下:

  document . onkeydown=function(event){

  const key code=event . key code;

  if(keycode==82){

  //R重新启动

  restart _ BTN . onclick();

  返回;//稍后添加

  } else if(keycode==80){

  //P暂停

  pause _ BTN . onclick();

  返回;//稍后添加

  } else if(keycode==67){

  //C继续

  start _ BTN . onclick();

  返回;//稍后添加

  } else if (keycode=40) {

  //向上38向下40向左37向右39

  n=[-1,-20,1,20][keycode - 37] 方向;//如果keycode是另一个值,方向不会改变。

  } else if (keycode=76 keycode=73) {

  //i 73 j 74 k 75 l 76

  n=[-20,-1,20,1][keycode - 73] 方向;

  }否则{

  开关(键码){

  案例87: //w

  n=-20;

  打破;

  案例83: //s

  n=20

  打破;

  案例65: //a

  n=-1;

  打破;

  案例68: //d

  n=1;

  打破;

  默认值:

  n=方向;

  }

  }

  方向=蛇[1] -蛇[0]==n?方向:n;//如果方向与原方向相反,则方向不变};问题2:调整难度等级后,蛇的速度没有变化,但是通过console.log()发现同步难度模式的功能确实被调用了?

  调试过程:在同步难易程度函数中设置console.log()方法,输出time_internal变量,设置断点进行调试。发现time_internal变量不变,mode_value变量始终未定义。最后发现传值时应该是错误mode _ value=mode _ item.value

  解决方法:修改值传递的方法,增加索引,改为mode_value=mode_item[i]。价值;

  原始代码和修改后的代码如下:

  //同步难度等级函数同步模式(){

  var mode _ value=

  for(var I=0;i mode _ item.lengthi ) {

  if (mode_item[i].已检查){

  模式值=模式项[我].价值;//原来是模式_项目。值

  }

  }

  开关(模式值){

  case simply :

  时间内部=简单模式

  打破;

  案例"中间":

  时间内部=中间模式

  打破;

  案例"困难":

  时间_内部=硬模式;

  打破;

  }}

完整代码

   !DOCTYPE htmlhtml lang=en

  头

  meta charset=UTF-8 /

  meta http-equiv= X-UA-Compatible content= IE=edge /

  meta name= viewport content= width=device-width,initial-scale=1.0 /

  标题贪吃蛇小游戏/标题

  风格

  按钮{

  宽度:100像素

  高度:40px

  字体粗细:粗体;

  }

  #游戏标题{

  左边距:95px

  }

  #画布{

  边框:1px固体# 000000/*设置边框线*/

  }

  #分数{

  字体粗细:粗体;

  }

  #mode_form {

  字体粗细:粗体;

  }

  #游戏结束{

  显示:无;/* 设置游戏结束窗口不可见*/

  位置:固定;

  顶:190 px

  左:65像素

  宽度:280像素

  高度:160像素

  背景色:aliceblue

  边框半径:5px

  边框:1px纯色# 000;/* 设置边框线*/

  }

  #再一次{

  位置:相对;

  左:20px

  }

  #取消{

  位置:相对;

  左:50px

  }

  /风格

  /头

  身体

  h1 id=game_title 贪吃蛇小游戏/h1

  画布id=canvas 宽度=400 高度= 400 /画布

  p id=游戏结束

  H3 id= game _ over _ text align= center 游戏结束!/h3

  H3 id=" game _ over _ score " align=" center "您的最终得分为: 0分/h3

  按钮id=once_again 再来一把/按钮

  按钮id="取消"取消/按钮

  /p

  英国铁路公司

  p id=游戏信息

  平装书游戏说明:/b/p

  p

  b1/b .用键盘上下左右键(或者字母学习键,或者前后左右键)控制蛇的方向,寻找吃的东西brb2/b .每吃一口就能得到一定的积分,同时蛇的身子会越吃越长brb3/b .不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴brb4/b .在下方单选框中选择难度等级,点击b开始/继续/b 即开始游戏,点击b暂停/b 则暂停游戏,brnbsp .图尔克再点击b开始/继续/b 继续游戏,点击重新开始则重新开始游戏brb5/b. b快捷键/b: bC/b 表示开始或继续, bP/b 表示暂停, bR/b 表示重新开始/p

  /p

  p id=分数目前得分: 0分/p

  表单操作= id=mode_form

  难度等级:

  输入类型= radio name= mode id= simplely value= simplely checked/

  =简单的标签简单/标签

  输入类型= radio name= mode id= middle value= middle /

  =中间的标签中级/标签

  输入类型= radio name= mode id= hard value= hard /

  =硬的标签困难/标签

  /表单

  br /

  按钮id=开始按钮开始/继续/按钮

  button id=pauseButton 暂停/按钮

  按钮id=restartButton 重新开始/按钮

  脚本

  const canvas=文档。getelementbyid(“canvas”);

  康斯特CTX=帆布。获取上下文(“2d”);

  const start _ BTN=文档。getelementbyid(“开始按钮”);

  常量暂停_ BTN=文档。getelementbyid(“暂停按钮”);

  const restart _ BTN=文档。getelementbyid(“重新启动按钮”);

  const once _ again _ BTN=文档getelementbyid( once _ again );

  常量取消_ BTN=文档。getelementbyid(“cancel”);

  const game _ over _ p=文档。getelementbyid( game _ over );

  const game _ over _ score=文档。getelementbyid( game _ over _ score );

  const score _ cal=文档。getelementbyid( score );

  const mode _ item=文档。getelementsbyname(“mode”);

  //用刷新间隔代表蛇的速度,刷新间隔越长,则蛇的速度越慢

  const simply _ mode=200

  const middle _ mode=100

  const hard _ mode=50

  //注意要改为var const是不会修改的

  var snake=[41,40];//蛇身体队列

  定义变量方向=1;//方向:1为向右,-1为向左,20为向下,-20为向上

  var food=42//食物位置,取值为0~399

  var n;//蛇的下一步的方向(由键盘和蛇的原方向决定)

  定义变量分值=-1;//得分

  var time _ internal=simply _ mode//刷新时间间隔,用于调整蛇的速度,默认为简单模式

  让enabled=true//用于控制是否刷新,实现通过一定频率刷新

  let run _ id//请求ID,用于暂停功能

  //产生最小~最大的随机整数,用于随机产生食物的位置

  函数随机(最小值,最大值){

  const num=数学。地板(数学。random()*(max-min))min;

  退货数量;

  }

  //用于绘制蛇或者是食物代表的方块,座位为方块位置,取值为0~399,颜色为颜色

  功能图(座椅、颜色){

  ctx.fillStyle=color//填充颜色

  //fillRect的四个参数分别表示要绘制方块的x坐标,y坐标,长,宽,这里为了美观留了1px用于边框

  ctx.fillRect(

  (座位% 20) * 20 1,

  数学.地板(座位/20) * 20 1,

  18,

  18

  );

  }

  //同步难度等级

  函数同步模式(){

  var mode _ value=

  for(var I=0;i mode _ item.lengthi ) {

  if (mode_item[i].已检查){

  模式值=模式项[我].价值;//原来是模式_项目。值

  }

  }

  开关(模式值){

  case simply :

  时间内部=简单模式

  打破;

  案例"中间":

  时间内部=中间模式

  打破;

  案例"困难":

  时间_内部=硬模式;

  打破;

  }

  }

  //用于绑定键盘上下左右事件,我设置了wsad,或者ijkl,或者上下左右方向键,代表上下左右方向

  //同时绑定稀有重启,P暂停,C继续,注意:若是这几个键则不需要更新方向的值,操作结束后直接返回即可

  文档。onkeydown=函数(事件){

  常量键码=事件。关键代码;

  if(keycode==82){

  //R重启

  重启BTN。onclick();

  返回;

  } else if(keycode==80){

  //P暂停

  暂停BTN。onclick();

  返回;

  } else if(keycode==67){

  //C继续

  从BTN出发。onclick();

  返回;

  } else if (keycode=40) {

  //上38 下40 左37 右39

  n=[-1,-20,1,20][keycode - 37] 方向;//若键码为其他值,则方向不变

  } else if (keycode=76 keycode=73) {

  //i 73 j 74 k 75 l 76

  n=[-20,-1,20,1][keycode - 73] 方向;

  }否则{

  开关(键码){

  案例87: //w

  n=-20;

  打破;

  案例83: //s

  n=20

  打破;

  案例65: //a

  n=-1;

  打破;

  案例68: //d

  n=1;

  打破;

  默认值:

  n=方向;

  }

  }

  方向=蛇[1] -蛇[

  0] == n ? direction : n; // 若方向与原方向相反,则方向不变

   };

   // 用于初始化游戏各项参数

   function init_game() {

   snake = [41, 40];

   direction = 1;

   food = 42;

   score = -1;

   time_internal = simply_mode;

   enabled = true;

   score_cal.innerText = "目前得分: 0分"; // 更新得分

   mode_item[0].checked = true; // 重置难度等级为简单

   }

   function game_over(){

   cancelAnimationFrame(run_id);

   game_over_score.innerText = "您的最终得分为: " + score + "分";

   game_over_p.style.display = "block";

   }

   // 启动或继续游戏

   function run_game() {

   syncMode(); // 同步难度等级

   n = snake[0] + direction; // 找到新蛇头坐标

   snake.unshift(n); // 添加新蛇头

   // 判断蛇头是否撞到自己或者是否超出边界

   if (

   snake.indexOf(n, 1) > 0

   n < 0

   n > 399

   (direction == 1 && n % 20 == 0)

   (direction == -1 && n % 20 == 19)

   ) {

   game_over();

   }

   draw(n, "#1a8dcc"); // 绘制新蛇头为浅蓝色

   draw(snake[1], "#cececc"); // 将原来的蛇头(浅蓝色)变成蛇身(浅灰色)

   if (n == food) {

   score = score + 1;

   score_cal.innerText = "目前得分: " + score; // 更新得分

   while (snake.indexOf((food = random(0, 400))) >= 0); // 重新刷新食物,注意食物应不在蛇内部

   draw(food, "Yellow"); // 绘制食物

   } else {

   draw(snake.pop(), "White"); // 将原来的蛇尾绘制成白色

   }

   // setTimeout(arguments.callee, time_internal); //之前的方案,无法实现暂停和游戏的继续

   }

   // 控制游戏的刷新频率,每隔time_internal时间间隔刷新一次

   function game_control(){

   if(enabled){

   enabled = false;

   requestAnimationFrame(run_game);

   setTimeout(() => enabled = true, time_internal);

   }

   run_id = requestAnimationFrame(game_control);

   }

   // 绑定开始按钮点击事件

   start_btn.onclick = function () {

   run_id = requestAnimationFrame(game_control);

   };

   // 绑定暂停按钮点击事件

   pause_btn.onclick = function () {

   cancelAnimationFrame(run_id);

   };

   // 绑定重新开始按钮点击事件

   restart_btn.onclick = function () {

   cancelAnimationFrame(run_id);

   // 将原有的食物和蛇的方块都绘制成白色

   for(var i = 0; i < snake.length; i++){

   draw(snake[i], "White");

   }

   draw(food, "White");

   // 初始化游戏各项参数

   init_game();

   run_id = requestAnimationFrame(game_control);

   };

   // 绑定游戏结束时的取消按钮点击事件

   cancel_btn.onclick = function () {

   for(var i = 0; i < snake.length; i++){

   draw(snake[i], "White");

   }

   draw(food, "White");

   init_game();

   game_over_p.style.display = "none";

   }

   // 绑定游戏结束时的再来一把按钮点击事件

   once_again_btn.onclick = function () {

   for(var i = 0; i < snake.length; i++){

   draw(snake[i], "White");

   }

   draw(food, "White");

   init_game();

   game_over_p.style.display = "none";

   run_id = requestAnimationFrame(game_control);

   }

   </script>

   </body></html>【相关推荐:javascript学习教程

  以上就是实例分享之JavaScript实现贪吃蛇小游戏的详细内容,更多请关注我们其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: