HTML5遊戲 看你有多「色」 開發

全部文章搬運自個人我的主頁:sheilasun.mecss

在極客學院看到了這個遊戲,在網上找到這個遊戲玩了很久真的比較上癮,因而本身也試着作了一下,能夠戳這裏試玩→看你有多色html

遊戲規則:

找出顏色不一樣的方塊jquery

梳理界面:

界面應該至少有三個部分:git

1. 開始界面github

提示玩法,以及遊戲入口canvas

2. 遊戲界面api

須要提供:數組

  • 進行操做的地方(遊戲區)
  • 當前得分
  • 當前剩餘時間閉包

    遊戲設計者特地設置了一分鐘的時間限制,由於這款遊戲真的很很很很很耗眼睛,我費盡力氣也就玩了個「超級色魔lv44」級別,眼珠子都快瞪飛了。每一分鐘讓眼睛能休息下很科學。app

  • 暫停按鈕

3. dialog界面
好比點了暫停會跳轉到這裏,這時應提供「繼續遊戲」按鈕。
好比遊戲結束了也會跳轉到這裏,這時應提供遊戲結果,例如"經鑑定您是【瞎子lv2】",以及"再來一次"按鈕。

以上的「界面」在html中能夠用div實現,三個一樣大小的div,position均爲absolute,重疊在一塊兒放置,經過隱藏或顯示來完成「跳轉」效果。

梳理細節:

上面這些是大體的框架,下面梳理細節部分。
首先是遊戲區的實現,是一個正方形區塊,有n*n個方塊,n的值由當前關卡肯定,越到後面的關卡,n值越大,要在2*2的格局中找出不一樣顏色的那個,垂手可得,在9*9的格局就不那麼容易了。
並且,這個「不一樣顏色」的設置也有講究,咱們把每一關中出現的兩種顏色稱爲「普通顏色」和「不一樣顏色」,如圖,只有一個方塊是「不一樣顏色」,其餘方塊塗的都是「普通顏色」,找出這特殊的一個就過關了。
每關的「普通顏色」隨機獲取(是黑色或白色就剔除重選),「不一樣顏色」就是在「普通顏色」上加點亮度,如亮度提高10%,這個提高的比例每關也有差異,越到後面值越小,越難分辨。


此處輸入圖片的描述

代碼實現:

html以及css部分這裏就不說細節了,關鍵的點就是:
三個界面的position要設爲absolute,位置徹底重合,疊疊樂,這樣只要簡單的隱藏或顯示就好了。
剛加載時,顯示「開始界面」div,遊戲開始,顯示「遊戲界面」,暫停或遊戲結束,顯示「dialog」界面,繼續遊戲或再玩一次,又回到「遊戲界面」。

主要是說一說js部分:

  • 第一個問題,小方塊們是如何畫上去的?

其實一開始,我是想用a或span標籤的,可是越到後面關卡,小方塊越多,好比說9*9就能產生81個標籤,這樣的話,dom節點彷佛有點多啊。因而我就想用canvas,我又想代碼寫起來能夠簡便些,因而我就找上了createjs家的easeljs,說幹就幹,趕忙奔到createjs官網上大體看了一下用法,趕忙開工,API不會用反正能夠隨時回來查。下面是easeljs繪製圓的示例用法:

var stage = new createjs.Stage("demoCanvas");//參數傳入canvas對象或者其id
var circle = new createjs.Shape();
circle.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, 50);
circle.x = 100;
circle.y = 100;
stage.addChild(circle);
stage.update();

說個插曲,一開始我也在想是否是有必要引入createjs,後來我忽然想起來我在網上玩這個遊戲的時候,彷佛看到別人的方塊都是圓角的,比不加圓角好看好多,我,也想這麼作。可是依稀記得canvas彷佛並無現成的畫圓角矩形的方法,難道我要用arc加line去拼合?還有,我還得爲那個特殊的小方塊添加點擊事件呢,若是就用原生的api,我須要這樣作:

  • 用一個變量a保存那個特殊的小方塊覆蓋的座標範圍
  • 給canvas對象添加click事件
  • 在click事件中判斷click的位置與a中範圍是否交叉,是的話,那麼恭喜本身,點中啦

這太麻煩了,而用createjs的話,我能夠直接使用drawRoundRectangle方法,我還能夠在畫小方塊的時候就給它(僅給它)綁上click事件,特別方便。

  • 第二個問題,如何隨着關卡增長,同時增長遊戲難度?

前面說過,難度的增長是經過增長"小方塊的個數"和減小"不一樣顏色相對普通顏色增長的亮度比例",那麼如何反映到代碼上呢?

能夠用一個數組保存每關的每行小方塊個數(列方向上也是這個數),如:

var levs= [2, 3,  4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9]

這樣每關的小方塊總數就分別是:2*2,3*3,4*4,4*4......

每次要畫小方塊的時候,就從這個數組裏取值,如第三關就是每行levs[2]個,每列也是levs[2]個,即共4*4個。

...
drawRects:function() {
    gameView.removeAllChildren();//移除上次繪製
    var num = this.levs[this.curLev];//當前關卡每行列應有的方塊數
    //計算每一個小方塊的寬度,全部小方塊寬度加上兩兩之間的間隔構成整個stage(繪製舞臺)的寬度
    var width = (stage.canvas.width - gap * (num - 1)) / num;
    var height = (stage.canvas.height - gap * (num - 1)) / num;
    var color = randomColor();//獲取隨機色
    var pickedX = _randomPick(0, num - 1);//隨機指定特殊方塊的位置
    var pickedY = _randomPick(0, num - 1);
    for (var i = 0; i < num; i++) {
        for (var j = 0; j < num; j++) {
            var rec;
            if (i === pickedX && j === pickedY) {
                rec = new Rectangle(width, height, color, .5, Rectangle.TYPE_PICKED);//建立特殊方塊
                (function (me) {
                        rec.addEventListener('click', function () {
                        me.nextLevel();//進入下一關
                 })
            })(this);//注意閉包
            } else {
                        rec = new Rectangle(width, height, color, .5, Rectangle.TYPE_NORMAL);//建立普通方塊
            }
            gameView.addChild(rec);
            rec.x = (width + gap) * i;//偏移&&鋪開
            rec.y = (height + gap) * j;
        }
    }
}
...

須要注意添加監聽事件的地方,一開始寫的時候沒注意直接用的this.nextLevel(),直接去window對象上找了,結果nextLevel方法天然是undefined。解決的辦法是建立一個當即執行函數,傳入this。

那麼如何設置亮度提高比例呢?
固然也能夠用相似上面的方法,用另外一個數組保存這些比例。可是我不想寫那麼死,仍是用一個函數實現吧:
在20%與60%間取值。

...
getLightenRatio: function () {  //由當前關卡數獲取亮度增長比例
    var minValue = 0.2, maxValue = 0.6;
    return maxValue - (maxValue - minValue) / (this.levs.length - 1) * this.curLev;
    }
...
  • 第三個問題,如何計算得分?如何結束遊戲?如何得到鑑定級別(或者說頭銜)?

關於得分這裏我都是作的簡單處理,過一關則加一分。
關於結束方式,由於這個遊戲裏沒有殭屍沒有炸彈,惟一的結束方式就只能是時間用完啦。
關於鑑定級別,如咱們玩的時候看到的「色狼lv23」是如何獲得的呢?
仍是定義一個數組,保存了這些級別的名稱。

var title=["瞎子", "色盲", "色郎", "色狼", "色鬼", "色魔", "超級色魔", "變態色魔", "孤獨求色"];

顯示遊戲結果的時候,就是從這個數組裏取出某值,具體取哪一個值,就看本身定義的規則了。
好比說,我認爲得分15分或如下的基本就算瞎子了,以後每加五分晉級一次,好比15分對應「瞎子」,16-20分對應「色盲」,21-25對應「色狼」,以此類推下去。
惟一須要注意的就是邊界控制,不要超出數組最大索引。

  • 第四個問題,暫停以及繼續遊戲應該作些什麼?

用一個變量保存剩餘時間leftTime,缺省值是60,即一分鐘後遊戲結束.
若是沒有暫停功能,那麼處理起來很簡單,遊戲剛進入時,初始化計時器,一秒tick一次,只要在計時器的tick事件裏遞減這個leftTime便可,當leftTime小於0,結束。
但加入暫停功能也不麻煩,只要手動設置一個標記isPaused,在tick事件的最開始判斷這個標記的值,false則執行事件的遞減。暫停按鈕的點擊便是改變這個變量的值爲true,繼續遊戲按鈕的點擊便是改變其爲false。

...
pause: function () { //暫停遊戲
    this.isPaused = true;
},
resume: function () { //繼續遊戲
    this.isPaused = false;
},
...

tick事件內部:

if (!me.isPaused) {
    --me.leftTime;
    if (me.leftTime === 0) {
        me.gameover();
    }
}
  • 第五個問題,「再來一次」該作些什麼?

應該回到遊戲界面並將環境重置,因此以前的代碼中應該提供一個reset方法,這裏調用這個方法便可。

好了,這樣下來,整個遊戲差很少就完成了,仍是戳這裏能夠玩~→看你有多色

戳這裏有代碼~→github-sheila1227,代碼遵循AMD規範,入口文件以下:

<script src="http://libs.tan14.net/require.js/2.1.14/require.min.js" data-main="js/app.js"></script>

入口文件中作一下配置:

requirejs.config({
    "baseUrl": "./js",
    "paths": {
        "app": "app",
        "jquery": "//libs.baidu.com/jquery/2.0.0/jquery.min" ,//結尾不要加.js擴展名
        "createjs": "easeljs.min"
    }
});

// Load the welcome module to start the app
requirejs(["welcome"], function(welcome) {
welcome.init('.page-welcome.page');
});

這裏有個問題是,由於jQuery支持AMD,因此我能夠直接require,可是createjs不支持AMD,因此我直接用script標籤直接引入,但我感受是否是應該用define包一下,讓它也能夠支持requirejs的方式。這個問題,留着後面查查資料再解決吧~

有任何不妥之處或錯誤歡迎各位指出,不勝感激~

相關文章
相關標籤/搜索