實(shí)例分享之JavaScript實(shí)現(xiàn)貪吃蛇小游戲_第1頁(yè)
實(shí)例分享之JavaScript實(shí)現(xiàn)貪吃蛇小游戲_第2頁(yè)
實(shí)例分享之JavaScript實(shí)現(xiàn)貪吃蛇小游戲_第3頁(yè)
實(shí)例分享之JavaScript實(shí)現(xiàn)貪吃蛇小游戲_第4頁(yè)
實(shí)例分享之JavaScript實(shí)現(xiàn)貪吃蛇小游戲_第5頁(yè)
已閱讀5頁(yè),還剩11頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第實(shí)例分享之JavaScript實(shí)現(xiàn)貪吃蛇小游戲效果如下:

至于寫界面的代碼,可以看文末的完整代碼,這里就稍微講解下綁定按鍵點(diǎn)擊事件與綁定快捷鍵

我們首先看下綁定按鍵點(diǎn)擊事件,點(diǎn)擊開始/繼續(xù)只需要調(diào)用requestAnimationFrame(game_control);,點(diǎn)擊暫停只需要調(diào)用cancelAnimationFrame(run_id);

//綁定開始按鈕點(diǎn)擊事件start_btn.onclick=function(){

run_id=requestAnimationFrame(game_control);};//綁定暫停按鈕點(diǎn)擊事件pause_btn.onclick=function(){

cancelAnimationFrame(run_id);};

點(diǎn)擊重新開始的話,則需要先暫停動(dòng)畫,然后刪除畫面上的蛇和食物,初始化所有設(shè)置,然后再調(diào)用requestAnimationFrame(game_control);開始游戲

注:初始化時(shí)需要初始化得分與難度等級(jí),這里解釋下為什么要將第一個(gè)食物設(shè)置為蛇頭下一個(gè)位置,因?yàn)檫@樣的話蛇會(huì)自動(dòng)先吃一個(gè)食物,繼而可以通過(guò)開始/繼續(xù)一個(gè)按鈕實(shí)現(xiàn)開始和繼續(xù)操作,同時(shí)run_game()函數(shù)中的食物繪制是在蛇吃到食物之后,保證第一個(gè)食物順利繪制,這樣的話score就需要初始化為-1

//用于初始化游戲各項(xiàng)參數(shù)functioninit_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;//重置難度等級(jí)為簡(jiǎn)單}//綁定重新開始按鈕點(diǎn)擊事件restart_btn.onclick=function(){

cancelAnimationFrame(run_id);

//將原有的食物和蛇的方塊都繪制成白色

for(vari=0;isnake.length;i++){

draw(snake[i],White

draw(food,White

//初始化游戲各項(xiàng)參數(shù)

init_game();

run_id=requestAnimationFrame(game_control);};

接下來(lái),我們綁定gameover中的兩個(gè)按鍵再來(lái)一把和取消

再來(lái)一把只需要完成重新開始里面的事件即可,取消只需要完成重新開始點(diǎn)擊操作中除了開始游戲的部分,即除了run_id=requestAnimationFrame(game_control);

這兩個(gè)按鈕都需要設(shè)置彈窗的display屬性為none

具體實(shí)現(xiàn)如下:

//綁定游戲結(jié)束時(shí)的取消按鈕點(diǎn)擊事件cancel_btn.onclick=function(){

for(vari=0;isnake.length;i++){

draw(snake[i],White

draw(food,White

init_game();

game_over_p.style.display=none}//綁定游戲結(jié)束時(shí)的再來(lái)一把按鈕點(diǎn)擊事件once_again_btn.onclick=function(){

for(vari=0;isnake.length;i++){

draw(snake[i],White

draw(food,White

init_game();

game_over_p.style.display=none

run_id=requestAnimationFrame(game_control);}

最后,我們來(lái)講解下如何設(shè)置快捷鍵,快捷鍵只需要用JavaScript模擬點(diǎn)擊對(duì)應(yīng)的按鈕即可,實(shí)現(xiàn)如下:

//同時(shí)綁定R重啟,P暫停,C繼續(xù)document.onkeydown=function(event){

constkeycode=event.keyCode;

if(keycode==82){

//R重啟

restart_btn.onclick();

}elseif(keycode==80){

//P暫停

pause_btn.onclick();

}elseif(keycode==67){

//C繼續(xù)

start_btn.onclick();

}};

問(wèn)題、調(diào)試與解決

注:此部分為本人在實(shí)現(xiàn)過(guò)程中出現(xiàn)的bug、調(diào)試過(guò)程以及解決方法,感興趣的可以看看,不感興趣的也可以跳過(guò)此部分,直接看文末的完整代碼

問(wèn)題1:點(diǎn)擊暫停和開始,游戲正常開始,按P也可以實(shí)現(xiàn)暫停,按C則畫面出現(xiàn)蛇所在的方格亂跳,無(wú)法正常開始,但是按C的操作中只模擬了開始/繼續(xù)按鈕的點(diǎn)擊?

效果如下:

調(diào)試過(guò)程:因?yàn)樯哳^的位置是由direction控制的,故想到設(shè)置斷點(diǎn),同時(shí)監(jiān)測(cè)這個(gè)變量的值的變化,發(fā)現(xiàn)這個(gè)值在按完P(guān)和C時(shí)被更新成很大的數(shù),進(jìn)而去找direction在哪里被更新,發(fā)現(xiàn)點(diǎn)擊P或C后還需要執(zhí)行下面這一行代碼,而實(shí)際上是不需要的

direction=snake[1]-snake[0]==ndirection:n;//若方向與原方向相反,則方向不變

解決方法:只需要執(zhí)行完對(duì)應(yīng)的模擬鼠標(biāo)點(diǎn)擊相應(yīng)按鈕事件之后就直接return就可以了

原代碼與修改后的代碼如下:

document.onkeydown=function(event){

constkeycode=event.keyCode;

if(keycode==82){

//R重啟

restart_btn.onclick();

return;//后來(lái)加上的

}elseif(keycode==80){

//P暫停

pause_btn.onclick();

return;//后來(lái)加上的

}elseif(keycode==67){

//C繼續(xù)

start_btn.onclick();

return;//后來(lái)加上的

}elseif(keycode=40){

//上38下40左37右39

n=[-1,-20,1,20][keycode-37]||direction;//若keycode為其他值,則方向不變

}elseif(keycode=76keycode=73){

//i73j74k75l76

n=[-20,-1,20,1][keycode-73]||direction;

}else{

switch(keycode){

case87://w

n=-20;

break;

case83://s

n=20;

break;

case65://a

n=-1;

break;

case68://d

n=1;

break;

default:

n=direction;

direction=snake[1]-snake[0]==ndirection:n;//若方向與原方向相反,則方向不變};

問(wèn)題2:調(diào)整難度等級(jí)后,蛇的速度并沒(méi)有發(fā)生改變,但是通過(guò)console.log()發(fā)現(xiàn)確實(shí)調(diào)用了同步難度模式的函數(shù)?

調(diào)試過(guò)程:在同步難度等級(jí)的函數(shù)中設(shè)置console.log()方法,輸出time_internal變量,同時(shí)設(shè)斷點(diǎn)調(diào)試,發(fā)現(xiàn)time_internal變量不發(fā)生變化,mode_value變量始終為undefined,最后發(fā)現(xiàn)應(yīng)該是值傳遞時(shí)的錯(cuò)誤mode_value=mode_item.value;

解決方法:修改值傳遞的方法,加上索引,改為mode_value=mode_item[i].value;

原代碼和修改后的代碼如下:

//同步難度等級(jí)functionsyncMode(){

varmode_value=

for(vari=0;imode_item.length;i++){

if(mode_item[i].checked){

mode_value=mode_item[i].value;//原來(lái)是mode_item.value

switch(mode_value){

casesimply:

time_internal=simply_mode;

break;

casemiddle:

time_internal=middle_mode;

break;

casehard:

time_internal=hard_mode;

break;

}}

!DOCTYPEhtmlhtmllang=en

head

metacharset=UTF-8/

metahttp-equiv=X-UA-Compatiblecontent=IE=edge/

metaname=viewportcontent=width=device-width,initial-scale=1.0/

title貪吃蛇小游戲/title

style

button{

width:100px;

height:40px;

font-weight:bold;

#game_title{

margin-left:95px;

#canvas{

border:1pxsolid#000000;/*設(shè)置邊框線*/

#score{

font-weight:bold;

#mode_form{

font-weight:bold;

#game_over{

display:none;/*設(shè)置gameover窗口不可見(jiàn)*/

position:fixed;

top:190px;

left:65px;

width:280px;

height:160px;

background-color:aliceblue;

border-radius:5px;

border:1pxsolid#000;/*設(shè)置邊框線*/

#once_again{

position:relative;

left:20px;

#cancel{

position:relative;

left:50px;

/style

/head

body

h1id=game_title貪吃蛇小游戲/h1

canvasid=canvaswidth=400height=400/canvas

pid=game_over

h3id=game_over_textalign=center游戲結(jié)束!/h3

h3id=game_over_scorealign=center您的最終得分為:0分/h3

buttonid=once_again再來(lái)一把/button

buttonid=cancel取消/button

pid=game_info

pb游戲說(shuō)明:/b/p

b1/b.用鍵盤上下左右鍵(或者IJKL鍵,或者WSAD鍵)控制蛇的方向,尋找吃的東西brb2/b.每吃一口就能得到一定的積分,同時(shí)蛇的身子會(huì)越吃越長(zhǎng)brb3/b.不能碰墻,不能咬到自己的身體,更不能咬自己的尾巴brb4/b.在下方單選框中選擇難度等級(jí),點(diǎn)擊b開始/繼續(xù)/b即開始游戲,點(diǎn)擊b暫停/b則暫停游戲,brnbsp;nbsp;nbsp;nbsp;再點(diǎn)擊b開始/繼續(xù)/b繼續(xù)游戲,點(diǎn)擊重新開始則重新開始游戲brb5/b.b快捷鍵/b:bC/b表示開始或繼續(xù),bP/b表示暫停,bR/b表示重新開始/p

pid=score目前得分:0分/p

formaction=id=mode_form

難度等級(jí):

inputtype=radioname=modeid=simplyvalue=simplychecked/

labelfor=simply簡(jiǎn)單/label

inputtype=radioname=modeid=middlevalue=middle/

labelfor=middle中級(jí)/label

inputtype=radioname=modeid=hardvalue=hard/

labelfor=hard困難/label

/form

br/

buttonid=startButton開始/繼續(xù)/button

buttonid=pauseButton暫停/button

buttonid=restartButton重新開始/button

script

constcanvas=document.getElementById(canvas

constctx=canvas.getContext(2d

conststart_btn=document.getElementById(startButton

constpause_btn=document.getElementById(pauseButton

constrestart_btn=document.getElementById(restartButton

constonce_again_btn=document.getElementById(once_again

constcancel_btn=document.getElementById(cancel

constgame_over_p=document.getElementById(game_over

constgame_over_score=document.getElementById(game_over_score

constscore_cal=document.getElementById(score

constmode_item=document.getElementsByName(mode

//用刷新間隔代表蛇的速度,刷新間隔越長(zhǎng),則蛇的速度越慢

constsimply_mode=200;

constmiddle_mode=100;

consthard_mode=50;

//注意要改為varconst是不會(huì)修改的

varsnake=[41,40];//蛇身體隊(duì)列

vardirection=1;//方向:1為向右,-1為向左,20為向下,-20為向上

varfood=42;//食物位置,取值為0~399

varn;//蛇的下一步的方向(由鍵盤和蛇的原方向決定)

varscore=-1;//得分

vartime_internal=simply_mode;//刷新時(shí)間間隔,用于調(diào)整蛇的速度,默認(rèn)為簡(jiǎn)單模式

letenabled=true;//用于控制是否刷新,實(shí)現(xiàn)通過(guò)一定頻率刷新

letrun_id;//請(qǐng)求ID,用于暫停功能

//產(chǎn)生min~max的隨機(jī)整數(shù),用于隨機(jī)產(chǎn)生食物的位置

functionrandom(min,max){

constnum=Math.floor(Math.random()*(max-min))+min;

returnnum;

//用于繪制蛇或者是食物代表的方塊,seat為方塊位置,取值為0~399,color為顏色

functiondraw(seat,color){

ctx.fillStyle=color;//填充顏色

//fillRect的四個(gè)參數(shù)分別表示要繪制方塊的x坐標(biāo),y坐標(biāo),長(zhǎng),寬,這里為了美觀留了1px用于邊框

ctx.fillRect(

(seat%20)*20+1,

Math.floor(seat/20)*20+1,

//同步難度等級(jí)

functionsyncMode(){

varmode_value=

for(vari=0;imode_item.length;i++){

if(mode_item[i].checked){

mode_value=mode_item[i].value;//原來(lái)是mode_item.value

switch(mode_value){

casesimply:

time_internal=simply_mode;

break;

casemiddle:

time_internal=middle_mode;

break;

casehard:

time_internal=hard_mode;

break;

//用于綁定鍵盤上下左右事件,我設(shè)置了wsad,或者ijkl,或者上下左右方向鍵,代表上下左右方向

//同時(shí)綁定R重啟,P暫停,C繼續(xù),注意:若是這幾個(gè)鍵則不需要更新direction的值,操作結(jié)束后直接返回即可

document.onkeydown=function(event){

constkeycode=event.keyCode;

if(keycode==82){

//R重啟

restart_btn.onclick();

return;

}elseif(keycode==80){

//P暫停

pause_btn.onclick();

return;

}elseif(keycode==67){

//C繼續(xù)

start_btn.onclick();

return;

}elseif(keycode=40){

//上38下40左37右39

n=[-1,-20,1,20][keycode-37]||direction;//若keycode為其他值,則方向不變

}elseif(keycode=76keycode=73){

//i73j74k75l76

n=[-20,-1,20,1][keycode-73]||direction;

}else{

switch(keycode){

case87://w

n=-20;

break;

case83://s

n=20;

break;

case65://a

n=-1;

break;

case68://d

n=1;

break;

default:

n=direction;

direction=snake[1]-snake[0]==ndirection:n;//若方向與原方向相反,則方向不變

//用于初始化游戲各項(xiàng)參數(shù)

functioninit_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;//重置難度等級(jí)為簡(jiǎn)單

functiongame_over(){

cancelAnimationFrame(run_id);

game_over_score.innerText=您的最終得分為:+score+分

game_over_p.style.display=block

//啟動(dòng)或繼續(xù)游戲

functionrun_game(){

syncMode();//同步難度等級(jí)

n=snake[0]+direction;//找到新蛇頭坐標(biāo)

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

//判斷蛇頭是否撞到自己或者是否超出邊界

if(

snake.indexOf(n,1)0||

n0||

n399||

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

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

game_over();

draw(n,#1a8dcc//繪制新蛇頭為淺藍(lán)色

draw(snake[1],#cececc//將原來(lái)的蛇頭(淺藍(lán)色)變成蛇身(淺灰色)

if(n==food){

score=score+1;

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

while(snake.indexOf((food=random(0,400)))=0);//重新刷新食物,注意食物應(yīng)不在蛇內(nèi)部

draw(food,Yellow//繪制食物

}else{

draw(snake.pop(),White//將原來(lái)的蛇尾繪制成白色

//setTimeout(arguments.callee,time_internal);//之前的方案,無(wú)法實(shí)現(xiàn)暫停和游戲的繼續(xù)

//控制游戲的刷新頻率,每隔time_internal時(shí)間間隔刷新一次

functiongame_control(){

i

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論