




版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 機(jī)械合同安全協(xié)議書
- 承包流轉(zhuǎn)合同協(xié)議書模板
- 保底合同協(xié)議書怎么寫
- 時(shí)租場(chǎng)地合同協(xié)議書
- 母嬰辦卡合同協(xié)議書
- 開拓市場(chǎng)與發(fā)展客戶策略(5范例)
- 中國(guó)冷芯盒樹脂項(xiàng)目經(jīng)營(yíng)分析報(bào)告
- 慧可-青少年藝術(shù)培訓(xùn)項(xiàng)目商業(yè)計(jì)劃書
- 擴(kuò)股股東協(xié)議書范本合同
- MDI企業(yè)供需現(xiàn)狀與發(fā)展戰(zhàn)略規(guī)劃
- 《公路橋涵施工技術(shù)規(guī)范》JTG-T3650-2020培訓(xùn)
- 2024年天津市單位職工勞動(dòng)合同(三篇)
- 2024秋期國(guó)家開放大學(xué)??啤兑簤号c氣壓傳動(dòng)》一平臺(tái)在線形考(形考任務(wù)+實(shí)驗(yàn)報(bào)告)試題及答案
- 膽石癥病人的護(hù)理
- 四川省成都市2024年小升初英語(yǔ)試卷(含答案)
- 建筑施工安全生產(chǎn)標(biāo)準(zhǔn)化指導(dǎo)圖冊(cè)
- 渠道襯砌施工方案(渠道預(yù)制混凝土塊)
- 2024年新課標(biāo)高考政治真題試卷含答案
- 02S515排水檢查井圖集
- DL∕T 5344-2018 電力光纖通信工程驗(yàn)收規(guī)范
- T-CCIIA 0004-2024 精細(xì)化工產(chǎn)品分類
評(píng)論
0/150
提交評(píng)論