宝哥软件园

JavaScript蛇小部件实例代码

编辑:宝哥软件园 来源:互联网 时间:2021-09-03

1写在前面

看来想当小演示练手的《JavsScript高级编程》选择了蛇的游戏。因为之前都是用c#写的,所以把Snake写成一个类,然后一个一个拆分,只提供需要提供的方法。这样,Snake可以作为一个模块使用,可以在任何地方重用。但是用js编写时,由于不能很好地利用js语言的特性进行模块化编程,第一版的实现采用了面向过程的方式,将函数中需要的所有变量都声明为全局变量。虽然这样也可以实现函数,但是不能重用,定义了很多顶层变量,污染了全局变量。写完之后,我总想把自己写的东西重新打包一次,以便只提供必须提供的变量或者函数接口。在检查了大量数据后,可以通过闭包来实现js的封装。局部变量和闭包函数在函数内部声明为该类型的私有变量和函数,然后要开发的接口通过它提供给对象。

2食蛇成分的使用

2.1主要示例

示例代码1如下:

!doctype html lang=' en ' head meta charset=' utf-8 ' title吃蛇组件/title/head body canvas width=' 600 ' height=' 600 ' id=' games cense '/canvas/body script src=' http 3360s nakegame . js '/script script var snake game=new snake game(' games cense ',{ });蛇游戏. startgame();/script/html首先引入了蛇游戏. js组件,然后实例化蛇游戏对象,并向蛇游戏构造函数传递两个参数。第一个参数是canvas的id,第二个参数是游戏配置的对象。如果为空,将采用默认配置。最后调用对象的startGame()方法,实现吃蛇逻辑。默认方向控制键为上、下、左、右键,暂停为空格。效果如下:

我们可以通过改变实例化过程中传入的配置对象来实现对游戏的更多控制。

示例代码2:

!doctype html lang=' en ' head meta charset=' utf-8 ' title吃蛇组件/title/head body canvas width=' 600 ' height=' 600 ' id=' games cense '/canvas/body script src=' http : snakeGame . js '/script script var snake game=new snake game(' games cense ',{ snakeColor:'red ',foodColor:'green ',scenseColor: ' blue ',directionKey:蛇游戏. startgame();/script/html你可以通过参数的名称知道,配置蛇的颜色,食物和游戏背景,控制游戏的方向键。配置方向顺序为[左、下、右、上]。效果如下:

当然还有更多配置。还可以定义分数变化的回调函数和游戏结束时的回调函数。下面描述了蛇游戏对象共享的配置参数和方法。

2.2公共方法

startGame():开始游戏。在这个方法中,各种设置被初始化。比如重置分数、蛇身、速度等。

changeGameStatus():改变游戏状态,即暂停和开始。在蛇游戏对象中有一个私有变量作为游戏状态变量。

2.3配置游戏参数的对象的gameConfigObj属性,

GameConfigObj对象应该总共有10个属性和3个回调函数

属性

大小:蛇块和食物大小,默认20行计数:行,默认30列计数3360列,默认30蛇颜色:蛇的身体颜色,默认绿色食物颜色:食物颜色,默认黄色四色颜色:游戏场景背景颜色,无声黑色方向键:方向键,默认[39,40,37,38]上,下,左,右pasueKey :暂停键,默认3360curSpeed:初始速度,默认为200毫秒。

回叫功能

onCountChange :事件,每一种食物,分数都会改变,这个方法用一个参数(计数)调用

onGamePause :事件,当游戏状态改变时,调用此方法,参数为1表示暂停,0表示游戏正在进行。

onGameOver :事件,游戏结束时,调用该方法。

2.4使用进阶

通过上面的属性我们可以设计一个交互性更加强的程序。代码如下。

示例3

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 '标题贪吃蛇组件/title style type=' text/CSS ' * { margin :0 px;padd :0 px } # game BD { width :850 pxmargin :50 px汽车;} # GamesCense {底色:绿色;float : left } # Gameset { margin-left :10 px;float:left}。游戏盒样式{页边距-底部:7 pxpadding:5px 10px }。游戏盒风格H3 {边缘-底部:7像素;} .gamebox style p {行高: 1.7 em} .gameBoxStyle输入{ margin-top :7 px;背景-颜色:白色;border:1px灰色固体;padding:3px 9px右边距:9 px} .gameBoxStyle输入[type=text]{ width :90 px;} .gamebox风格输入:悬停{背景色: # e2ff F2} .game box style # TxtVaLue { color : red;}/style/headdydiv id=' gamebd ' canvas id=' gamesence ' width=' 600 ' height=' 600 '/canvas div id=' gameSet ' div id=' game control ' class=' game box style ' H3游戏控制/h3 p方向键:上,下,左,右/p p开始/暂停:空格/p/div div id=' gameStatus ' class=' game box style ' H3游戏状态/h3 p用户名:输入类型=“文本”占位符='输入用户名:' id='txtUserName '值='游客123 '/p/p当前用户一得分:span id='txtValue'0/span/p输入类型='按钮'值='开始游戏id=' BtInstart '/输入类型='按钮'值='暂停id=' BTN暂停/div div id=' 游戏风格的H3游戏记录/H3 a href=' # ' rel=' external nofollow ' rel=' external nofollow '查看历史记录/a/div/div脚本src=' http : js/蛇形游戏。 js '/script/body script src=' http 3360 snake game。js '/脚本脚本var BTN start=document。getelementbyid(' BTN start ');var btnPasue=文档。getelementbyid(' BTN暂停');var gamenake=新的蛇游戏(' gamesence ',{ 0蛇形颜色: '红色,onCountChange:function(计数){ var txt score=document。getelementbyid(' txt值');txtscore。innertext=计数。tostring();txtScore=null},OnGamePause : FuncTion(状态){ if(状态){ BTNPAUSE。值='开始;}else { btnPasue.value='暂停} },onGameOver:function(状态){ alert('游戏结束');} });BTN开始。onclick=function(event){ if(check username()){ gamenake。start game();BTN开始。blur();} } btnpasue。onclick=function(event){ gamenake。changegamestatus();BTN开始。blur();}函数check username(){ var txtUserName=document。getelementbyid(' Txtusername ');if(TxTussername。价值。长度==0){ alert('用户名不能为空');返回false} else { return true} }/脚本/html上面的代码通过设置OnChangeCount、onGamePause、onGameOver、三个回调函数,实现界面与组件的交互。效果如下:

在《JavaScript高级编程》 这本书中说道一个模块模式,但是这种模式是单例模式,也就是闭包最后返回一个字面量的对象。但是我需要在一个页面中能够同时开启两个贪吃蛇的窗口,两个游戏通过设置配置不同的方向键和按钮操作,实现两个人同时一起玩。所以,在实现蛇游戏组件时,没有采用道格拉斯所说的模块模式。下面演示一下,如何在一个页面中,让两个人同时一起玩游戏。代码如下:

示例四

首先建立一个超文本标记语言文件

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 ' title jaume ' s贪吃蛇/title link rel='样式表href=' CSS/gamestyle。CSS ' rel='外部无跟随'/headdydiv id=' gamebd ' canvas id=' gamesence ' width=' 600 ' height=' 600 '/canvas canvas id=' gamese 1 ' width=' 600 ' height=' 600 ' style=' background-color : black '/canvas div id=' gameSet ' div id=' game control ' class=' gamebox style ' H3游戏控制/h3 p方向键:上,下,左,右/p p开始/暂停:空格/p/div div id=' gameStatus “游戏盒风格”的H3游戏状态/h3 p当前用户一得分:span id='txtValue'0/span/p p当前用户2得分:span id=' TxtValueee 1 ' 0/span/p输入类型='按钮'值='开始游戏id=' BTN开始'/div/div id='游戏' class='游戏盒风格' H3游戏记录/H3 a href=' # ' rel=' external nofollow ' rel=' external nofollow '查看历史记录/a/div/div脚本src=' http : js/蛇形游戏。 js '/script script src=' http : js/ui script。js '/脚本/正文/html样式文件如下:

* { margin :0 pxpadding :0 px } # game BD {/* width :850 px;*//*边距:50 px auto*/宽度:100%;} # GamesCense {底色:绿色;float : left } # Gameset { margin-left :10 px;float:left}。游戏盒样式{页边距-底部:7 pxpadding:5px 10px }。游戏盒风格H3 {边缘-底部:7像素;}.gamebox style p {行高: 1.7 em}.gameBoxStyle输入{ margin-top :7 px;背景-颜色:白色;border:1px灰色固体;padding:3px 9px右边距:9 px}.gameBoxStyle输入[type=text]{ width :90 px;}.gamebox风格输入:悬停{背景色: # e2ff F2}.game box style # TxtVaLue { color : red;}在超文本标记语言中拖入了两个文件,一个是贪吃蛇组件,另一个是UIScript.js,其中的代码如下:

/** *由the jewish museum 犹太人博物馆于2017年8月16日创建*/var BTN开始=文档。getelementbyid(' BTN start ');var gameSnake=new蛇形游戏(' gameScense ',{ 0蛇形颜色: '红色,directionKey:[68,83,65,87],pauseKey:81,oncountchange :函数(count){ var txtScore=document。getelementbyid(' txt值');txtscore。innertext=计数。tostring();txtScore=null },onGameOver:function(状态){ alert('游戏结束');}});var gameSnake1=新蛇游戏(“游戏许可证1”,{ 0蛇形颜色: '绿色,大小:20,onCountChange:function(计数){ var txtScore=document。getelementbyid(' TxtValue1 ');txtscore。innertext=计数。tostring();txtScore=null },onGameOver:function(状态){ alert('游戏结束');}});BTN开始。onclick=function(event){ gamenake。start game();gamenake 1。start game();BTN开始。blur();}实例化两个蛇游戏对象,一个对象使用默认的上下左右键和空格键作为方向键和暂停键,而另一个使用了,W,A,S,D以及Q作为方向键和暂停键。效果如下:

嗯哼,没错,完美实现了。使用蛇游戏这个组件,创建贪吃蛇游戏就是如此的简单。下面简单介绍一下,组件的实现方式。

3贪吃蛇组件实现方式

在上一节中就提到过,没有采用过道哥拉斯的设计模式,下面给出贪吃蛇设计结构。具体的源代码,可以在后面的链接中进行下载。代码如下:

/** *由the jewish museum 犹太人博物馆于2017年8月18日创建*/var蛇游戏=function () { /*蛇块和食物组件类*/函数蛇块(行,列){ this.row=rowthis.col=col}蛇块。prototype.draw=函数(图形、颜色、大小){ graphic . fill style=color graphic . fill rect(size * this . col,size*this.row,size-2,size-2);}蛇块。prototype.clearDraw=函数(图形、颜色、大小){ graphic . fill style=color graphic . fill rect(size * this . col,size*this.row,size,size);}蛇块。prototype.equal=函数(蛇块){ if(蛇块。row==this.row蛇块。col==这个。col){ return true;} else {返回false} } /*贪吃蛇组件类*/函数蛇游戏(gameScenseId,gameConfigObj) { //私有属性var gamesence=文档。getelementbyid(gamene id);var graphic=gameconse。get context(' 2d ');定义变量计数=0;var蛇形var curFoodvar runIdvar is moved=false//方向改变后,如果没有移动则方向键暂时失效var gameStatus=false var cordedirection=1;var size=GameconfigObj。尺寸| | 20;var行数=GameconfigObj。行数| | 30;var colCount=GameconfigObj。colCount | | 30定义变量蛇颜色=gameConfigObj。蛇颜色|| '绿色;var food color=gameconfigobj。食物颜色| | '黄色;var PileColor=GameconfigObj。PileColor | | '黑色';var directionKey=gameconfigobj。directionKey | |[39,40,37,38];var pauseKey=gameconfigobj。pauseKey | | 32var级别计数=GameconfigObj。级别计数| | 10;var curs speed=gameconfigobj。curs速度| | 200;//公开事件var OncountChange=GameconfigObj。OncountChange | | null//带有一个参数var ongame pause=GameconfigObj。ongame pause | | null//带有一个参数var ongame over=GameconfigObj。ongame over | | null//判断if(gamesence。宽度!=size *行数| | gamesence。身高!=size*colCount){ throw '场景大小不等于行列大小*蛇块大小;} //特权方法this.startGame=startGamethis。changeGameStatus=changeGameStatus;//注册数字正射影像图键盘事件var PRefunc=document . onkey down document。onkey down=function(e){ var key=(e | | event).键码;handleKeyInput(键);如果(类型为PRefunc==' function '){ PRefunc(e);} } //私有方法/*初始化蛇身*/函数initSnake(){ } /*绘制场景背景色*/函数InitLiTe(){ }/*产生食物*/函数genFood(){ } /*吃食物*/函数eatFood(黑鱼){ } /*判断游戏是否结束*/函数gameOver(){ } /*蛇移动*/函数蛇形移动(){ }函数changeSpeed(){ }函数handleKeyInput()键){ }函数initGame(){ }函数triggerEvent(回调,参数){ }函数runGame(){ }函数pauseGame(){ }函数changeGameStatus(){ }函数startGame(){ } }返回蛇形游戏;//最后返回一个组件构造函数}();上面有一个很重要的地方,就是键盘注册的代码,单独列出来分析一下。

var PRefunc=document . onkey down document。onkey down=function(e){ var key=(e | | event).键码;handleKeyInput(键);如果(类型为PRefunc==' function '){ PRefunc(e);} }该段代码的逻辑是,首先判断在文件上是否注册了onkeydown事件,如果注册了该事件,则保存所引用的事件处理程序,然后重置onkeydown事件程序,然后在新的事件处理程序中,调用先前的事件处理程序,这样就实现了事件触发后,调用所有监听该事件处理程序,而不是直接覆盖。

另外关于贪吃蛇的设计逻辑,可以参看我另外一篇文章,个人觉得讲的非常详细了,文章:基于控制台实现贪吃蛇游戏

3小结

通过吃蛇组件的设计,我对js的模块化设计有了一点了解。但是我不知道上面实现的吃蛇模块的缺陷。希望有大神能看完这篇文章,给点指导。当然,组件还可以进一步扩展,比如用图片替换游戏块。如果你感兴趣,可以从以下链接下载。换了之后别忘了分享。

源代码下载链接:https://github.com/StartAction/SnakeGame

以上是边肖介绍的JavaScript Snake Widget的示例代码,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你的!

更多资讯
游戏推荐
更多+