我的前端故事----歡樂大富翁( ̄︶ ̄)↗ (搖骰子+棋盤)

來源:互聯網
上載者:User

標籤:

      十一馬上就要到了~~做為前端的小夥伴~活動頁面必然是少不了了~那怎麼吸引眼球呢?當然是玩遊戲啦~這次就帶來一個我為十一做的小遊戲,作為活動頁中的襯托~~

      那我們要做個什麼樣的遊戲呢?先~

       由於實際的因為是公司的活動,我就不貼出來了~這裡用這個棋盤來大致說明一下效果咯~下面是遊戲規則:

       1,當使用者看到棋盤的時候,棋子出現在上一次停留下來的位置;

       2,當使用者點擊開始後,中間的骰子開始搖動,最後停止在伺服器返回的數字前;

       3,當骰子結束動畫後,棋子還是移動,一步一步的向前移動,遇到四個頂點的時候自動轉彎,並最終停留在骰子步數前進的位置前;

       4,當棋子結束移動後,頁面上顯示使用者最後剩下的遊戲次數,並且如果移動到有禮物的位置時彈出遮罩告訴使用者獲獎;

       5,在整個遊戲期間,不允許使用者繼續點擊開始按鈕,並且當使用者剩餘次數用完之後開始按鈕變色;

       遊戲規則都說明了,那麼需求分析就到這裡了,下面介紹頁面配置:

HTML結構:
<div class="game">    <div class="gameimg">             <div id="pieces" class="p0-0">    <!-- 棋子 -->                 <img src="images/pieces.png" />             </div>        <div class="play">             <div class="dice">     <!-- 骰子 -->                 <img id="dice" class="dicelo2" src="images/dice.png" />             </div>             <div class="playnum">                 您今天還有<span id="pn">0</span>次遊戲機會               </div>             <div id="playbtn">                  <img src="images/btn_start_gray.png" />             </div>         </div>    </div></div>

整體的結構就是一個大的div標籤,它的背景是整個棋盤,然後棋子通過相對布局定位在背景圖的18個位置上,然後骰子和開始按鈕以及說明都置中顯示在背景圖的中心。

CSS樣式:

       對於css樣式來說,主要用到的是相對定位,設定了18個位置的css樣式,而且命名規則是按照 ’p0-0‘這樣的方式來命名?為什麼我要這樣呢?這樣可以用類名儲存矩陣座標的位置。棋盤上的位置1對應座標的1-0、2對應2-0…..依此類推。最後就可以方便的設定棋子的位置了。同時,對於骰子的動畫,是通過一整張png圖片來進行定位。從骰子的1到6然後是動起來的3副圖片,一共9張圖片儲存在一整張png中,然後依舊採用相對定位的方式來給使用者展示。首先是骰子開始運動,我就迴圈顯示最後3張動起來的圖片,然後當動畫結束後將位置停留在所要顯示對應的數字前。

這樣把部分圖片貼出來就很明顯的說明了我的意圖~

javascrpt邏輯篇:

         首先是進入頁面的載入,流程就是首先通過jsonp請求伺服器,擷取該使用者上次的棋子位置,和剩餘次數等基礎資訊,然後渲染在頁面中,我就不在這裡展開了,這裡注意想說的是負責棋子移動和骰子搖動的邏輯部分。

         那麼按照遊戲規則,首先是骰子的搖動,當點擊開始按鈕後請求伺服器結束後調用骰子執行函數,接著將伺服器返回的骰子數字和到達的位置傳遞給複製骰子動畫的函數。

/** * 操作骰子的執行函數 * * @method play_dice * * @param  {ing}  dice_num  [骰子數字] * @param  {int}  next_step [到達位置] */function play_dice (dice_num, next_step) {    var _stop = dice_num,        _pande = next_step;    diceroll($(‘#dice‘), _stop, _pande);}
/** * 搖動骰子的動畫函數 * * @method diceroll * * @param  {object} dice      [骰子物件] * @param  {int}    num       [搖動的結果] * @param  {int}    _pande    [棋子停下的位置] */function diceroll(dice, num, _pande){    var i = 0,        b = 0,        a = function(i) {          b = setTimeout(function() {              dice.removeClass().addClass(‘dicelo‘ + (i % 3 + 7));   // 清除上次動畫後的點數              i++;              if (i > 5) {                  // 這裡的dicelo9是骰子最後一幅動畫的類名,刪除後依次添加dicelo7,dicelo8                   dice.removeClass(‘dicelo9‘).addClass(‘dicelo‘+num);                  var j = $(‘#pieces‘).attr(‘class‘).substr(1) || 1,                      n = j + _pande;                  var oldstep = _pande-num-1;                  person.step = num;                  run(person, true);//  1右,2下,3左,4上                     clearTimeout(b);                  i = 0;              } else {                  a(i);              }          }, 200);        };    a(i);}

       這裡通過一個定時器,不斷的迴圈骰子搖動的這個動畫,然後在執行5次之後就讓骰子停下來,同時清除定時器,然後在骰子停止搖動之後觸發棋子移動的函數,在run函數中需要兩個參數,如果第二個參數為true,就讓棋子還是移動,否則的話則只是計算棋子的矩陣座標。而person這個對象中儲存著座標位置start: [0, 0],所要前進的步數step,和當前前進的方向de,de的值我設定為1右,2下,3左,4上 。下面是棋子移動的函數。

/** * 控制棋子的移動和棋盤座標的轉換 * * @method run * * @param  {object}  person [棋子移動的座標] * @param  {Boolean} isAn   [棋子是否需要移動] * * @return {object}         [棋子移動的座標] */function run (person, isAn) {    var _start = person.start,        _step = person.step,        _de = person.de;    // 棋子移動過程的座標集合    gameList = new Array();    for (var i = 1; i <= _step; i++) {        if (_de == 1) {  // 棋子向右移動            _start[0] += 1;            if (_start[0] == 5) {                _de = 2;            }        }else if (_de == 2) {  // 棋子向下移動            _start[1] += 1;            if (_start[1] == 4) {                _de = 3;            }        }else if (_de == 3) {  // 棋子向左移動            _start[0] += -1;            if (_start[0] == 0) {                _de = 4;            }        }else if (_de == 4) {  // 棋子向上移動            _start[1] += -1;            if (_start[1] == 0) {                _de = 1;            }        }        gameList.push([_start[0], _start[1]]);  // 將移動後的結果儲存在集合中    }    // 當需要棋子移動時執行    if (isAn) {        var j = 0,            d = 0,            c = function(j) {              d = setTimeout(function() {                  $(‘#pieces‘).attr(‘class‘, null).addClass(‘p‘+gameList[0][0] + ‘-‘ +gameList[0][1]);                  gameList.shift(0);                  j++;                  if (gameList.length == 0) { // 如果棋子移動結束後則彈出相應的結果                          returndice(_start);                      clearTimeout(d);                  } else {                      c(j);                  }              }, 500);            };        c(j);    }    person.start = _start;    person.step = 0;    person.de = _de;    return person;}

      這裡依舊是使用定時器來重複顯示棋子的移動過程,由於定時器是非同步執行的,所以我將函數產生的一個運動結果儲存在數組中,然後在非同步定時器中一個個的遍曆數組中的結果,每次取出數組中的第一個結果,執行移動之後便移除第一個結果,後面的結果頂上來,下次取出的第一個結果就是下一次需要移動的結果,最終在結束移動的時候及隊列清空的情況下清除定時器,然後我在代碼中執行了returndice函數來顯示移動後的結果,如果中獎了則調出遮罩提示使用者的獲獎情況。

總結:

       到這裡,全部的邏輯基本都說明白了,其實整體來說就是3個函數的迴圈調用,為了保證在移動端上的效能,在每次定時器結束之後都需要及時的清除掉定時器,否則會出現定時器覆蓋的情況,在我測試的時候如果沒有及時清除定時器的話,在執行20000+的時候會出現移動的步數比實際的情況少一步的情況,最開始的時候我在最後寫了校正函數來保證最終棋子停下來的位置與伺服器返回的一致,本來以為是誤差,結果後來再測試的時候發現校正的時候會出現棋子閃現的情況,這是很不好的使用者體驗,而且按照我棋子移動的邏輯來看,是不可能出現錯位的,所以理論上是不需要校正函數的,所以再經過仔細查看代碼後發現了第二次棋子移動的定時器在使用後並沒有及時清除,在使用者遊戲次數較少的時候是很難出現bug的,但是自動化的測試的時候接近於無限的次數很容易出現錯誤的情況,所以還是很重要的bug,還好及時發現。。。o(︶︿︶)o 最後為了保證在一次遊戲的過程中使用者不能繼續點擊開始按鈕,所以在開始搖骰子的時候將全域鎖設定為false,並在最後棋子結束移動之後再開啟全域鎖。到此為止,所有的遊戲規則都滿足了~~

      今天就到這裡吧。。。下次帶來一個頁面跑馬燈的效果~~

我的前端故事----歡樂大富翁( ̄︶ ̄) (搖骰子+棋盤)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.