中秋節馬上就要來臨,公司開發了一個h5小游戲叉月餅,其實就是游戲“見縫插針”的翻版。這個游戲的開發任務落到了我的頭上。。。
一 游戲介紹
游戲場景基本如下所示:
二 所用工具
這次的開發還是用的公司原有的一些框架,其中包括處理圖片預加載、處理音效的等,其中包含了creatJS的一些內容,暫時還沒有研究。有時間要研究一下。
所用框架如下:
<script type="text/javascript" src="../Public/js/setviewport.js"></script> <script type="text/javascript" src="../Public/js/jweixin-1.0.0.js"></script> <script type="text/javascript" src="../Public/js/WeixinApi.js"></script> <script type="text/javascript" src="../Public/js/jquery-2.1.1.min.js"></script> <script type="text/javascript" src="../Public/js/hammer.min.js"></script> <script type="text/javascript" src="../Public/js/TweenMax.min.js"></script> <script type="text/javascript" src="../Public/js/preloadjs-0.6.0.min.js"></script> <script src="http://cdn.gbtags.com/EaselJS/0.7.1/easeljs.min.js"></script> <script src="http://cdn.gbtags.com/PreloadJS/0.4.1/preloadjs.min.js"></script> <script src="http://cdn.gbtags.com/SoundJS/0.5.2/soundjs.min.js"></script> <script type="text/javascript" src="../Public/js/main.js"></script> <script type="text/javascript" src="../Public/js/wScratchPad.min.js"></script>
其實主要用的是JQuery、TweenMAx、preload等。
三 頁面布局
游戲的主要畫面包括游戲初始頁、規則、游戲、過關提示、抽獎、抽獎結果並提交信息、通關提交信息等。因為PSD圖中游戲結束提示燈一些頁面都是在初始頁的基礎上加了個半透明的遮罩,所以這些提示都寫在了初始頁里面,游戲畫面是一個單獨的快,抽獎是一個單純的塊,抽獎結果是一個單獨的塊,抽獎結束是一個單獨的塊,過關提示是一個單獨的塊。
四 游戲邏輯
首先第一個頁面點擊按鈕查看游戲規則,游戲規則也點擊開始游戲開始游戲,簡單的點擊事件暫且不提。
我們需要初始化一些全局變量用於游戲控制。
var tar = $(".point"); //旋轉月餅1 var tar2 = $(".point2"); //旋轉月餅2 var arrowIndex = 1; //針數 var rotateNum = 0; //旋轉度數 var arrPos = [360]; //已有度數列表 var safeDistance = 8; //安全距離 var score = 0; //得分 var level=1; //關數 var levelmap=[0,2,4,6,8,9,10,11,12,13,14] //難度地圖,設置初始針數
如圖所示,月餅是旋轉的,而在這里我們有兩個旋轉的月餅。原因是point這個月餅是一個空的div,而月餅圖片是他的背景,而當我們把針射上去的時候,采用的方式是在point這個空div里面添加子元素,子元素就是針,而針子元素是相對於point定位的,結果就是針在月餅的上面,這樣當然不好看,所以我在point后面加上了一個月餅point2,用它把第一個月餅蓋住,兩個月餅一起轉動,這樣針就乖乖的插在了月餅里面。
arrowIndex是表示插得針數,rotateNum是月餅旋轉的角度,arrPos是月餅上已經有的針的角度,用於判斷插針結果,safeDistance是安全距離,當兩根針之間的角度差小於它是,游戲失敗,score是得分,level是關數,levelmap是難度地圖,用於初始化每關游戲開始時自帶針數。
1、倒計時
點擊開始游戲按鈕時,游戲場景出現,開始倒計時3秒。倒計時的實現是采用setInterval每隔1000ms換一張圖片。
function numCount(){ var flag=3; var timer2=setInterval(function(){ if(flag>1){ flag--; $('.count img').attr('src','../Public/images/a'+flag+'.png') }else{ clearInterval(timer2); can=true; gameStart(); } },1000) }
其中can為點擊事件的開關,初始為flase;當can為true時,方可點擊。
2、難度設置
游戲剛開始時設置難度,同時每過一關都要重新設置難度,所以需要在這個函數中將arrowIndex重置為1,將arrPos重置為[360],之所以初始為360不為空,是因為0度肯定是存在的,而360等於0度,在計算是否插針成功的時候,沒有360將會產生一些錯誤。
首先獲得當前難度,然后根據當前難度在levelmap里面取數,取出的數字即為下一關初始針數,然后用360/針數取整,針旋轉相應度數,將這些針循環寫入point,同時將這些度數push進數組arrPos,表示已經存在上述度數的針。初始化頁面下方球數,在調用這個函數的時候,需要傳入一個參數,即每關有多少根針,然后將通過循環將底部小球寫入相應div,並附上數字。
3、游戲開始
月餅旋轉使用的是setInterval來控制,每隔相應時間月餅轉動一度,同時全局變量rotateNum加1,當大於等於360的時候歸0,這樣月餅的角度一直在0到360之間變化。當發生點擊事件的時候,可以通過rotateNum的值獲取到當前月餅旋轉的角度,然后在point中添加一個元素(針),並使它旋轉到一定的角度。由於針是相對於月餅定位的,其top和left都為50%,通過調節margin使他出現在月餅正下方,所以如果月餅不轉的話,新添加的針出現在月餅的正下方,此時月餅和針的旋轉角度均為0,而當月餅旋轉X度之后,針如果不旋轉,也將出現在X度的方向,所以針需要旋轉Y=360-X度,即讓針從0度位置,先跟着月餅旋轉到X,在旋轉到Y,所以針相對於手機旋轉360度等於不旋轉,針將出現在月餅的最下方。然后將針旋轉的度數Y push進數組arrPos。定義一個新數組,然后使用grep方式用Y減去數組arrPos的每一項,當結果小於安全距離safeDistance的時候,將arrPos的這一項寫入新數組,如果新數組的長度大於等於2,說明存在兩根針之間的距離小於安全距離,游戲結束。當這次插針成功時,將度數寫入數組arrPos,將下方球第一個元素remove,同時分數加1,當分數大於等於10時,過關提示頁出現,關數加1,同時初始化難度。當關數大於等於10時,通全關,游戲界面隱藏,清空計時器,出現獎勵界面。若游戲失敗且過關數大於等於3,游戲界面隱藏,清空計時器,出現抽獎頁面。
4、抽獎
點擊抽獎按鈕,調ajax獲取抽獎,若用戶沒有抽獎資格,轉盤轉動幾圈,然后停在謝謝參與地方,彈窗提示用戶,然后刷新頁面。
若用戶有抽獎資格且中獎,轉盤轉動,最后根據獎品ID停在相應位置,然后跳出獲獎信息,並讓用戶填寫信息。用戶信息填寫成功並提交后,跳到最后宣傳頁面。
若用戶沒有中獎,,轉盤轉動,最后停在謝謝參與位置,跳出沒中獎,用戶點擊再次挑戰重新開始游戲。
5、再次挑戰,重新開始游戲
初始化各種全局變量,將頁面該隱藏的隱藏,改顯示的顯示,然后重新調用倒計時函數。
五 遇到的各種BUG
1、iOS端點擊延遲、閃屏:
愚蠢的我點擊事件隨便寫了個click,當然是不可以啦,畢竟300ms延遲傷不起呀,怪我怪我~~~
我們是用這種方法封裝的點擊事件
var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent); var touchstart = mobile ? "touchstart" : "mousedown"; var touchend = mobile ? "touchend" : "mouseup"; var touchmove = mobile ? "touchmove" : "mousemove";
2、IOS端連續點擊屏幕上移
這個問題很嚴重,快速雙擊是經常存在的,解決辦法如下代碼:
function initPreventPageDobuleTap(isPreventPageDobuleTap){ if(isPreventPageDobuleTap){ $('.main').on(touchstart,function(e){ e.preventDefault() }) }else{ $('.main').off(touchstart); $('.main').off(touchend); } }
意思就是當傳入false的時候,把touch事件給解綁,傳入true的時候,取消事件的默認動作。但是當有表單頁的時候,要關閉阻止事件,否則不能輸入文字了,請傳入false值,再次運行即可。
即要阻止雙擊,就傳true,取消事件的默認動作,但這樣會阻止表單,因為觸摸不會觸發input,所以要關閉它。