繼續繼續。
上一篇地址:【Cocos Creator 實戰】05 - 如何判斷拼圖完成(勝利)
概覽
主要內容
來看看今天要做的內容:
- 如何給拼圖遊戲加上計時器(timer)
- 如何控制節點顯示/隱藏
- Widget(對齊掛件)的使用
來看看將要實現的效果:
1、倒計時結束前仍未拼完
2、倒計時結束前已拼完
項目資源
推薦大家先把項目 clone 到本地,然後參考着代碼來看本篇文章。
我的每篇文章會對應一個分支,大家直接看對應的分支就可以,master 對應的是最新的內容,會整合各個分支。
演示地址也是對應每篇文章獨立部署的。
開搞
項目結構
我們先來看一下我們這次修改的內容:
其中,綠框選中的是新增的文件,黃框選中的是修改的文件。
字體
注意我們上面圖片中 ① 的部分,這裏面的內容表示字體文件。
Cocos Creator 目前支持三類字體資源:系統字體,動態字體和位圖字體。
- 系統字體:在創建label的時候,指定
Use System Font
即可。 - 動態字體(矢量字體):目前
只支持 TTF
格式的動態字體。 - 位圖字體(點陣字體):由 fnt 格式的字體文件和一張 png 圖片組成,fnt 文件提供了對每一個字符小圖的索引。
我們在定時器中使用的就是 位圖字體
。
注意在使用位圖字體的時候必將 fnt 文件和 png 文件同時拖拽到資源管理器中。
簡單說一下這 動態字體(矢量字體)
和 位圖字體(點陣字體)
的區別哈。
以下內容引自維基百科:
- 矢量字體
矢量字體是與點陣字體相對應的一種字體。矢量字體的每個字形都是通過數學方程來描述的,一個字形上分割出若干個關鍵點,相鄰關鍵點之間由一條光滑曲線連接,這條曲線可以由有限個參數來唯一確定。矢量字的好處是字體可以無級縮放而不會產生變形。向量字體在顯示或者打印出來之前需要進行光柵化。目前主流的矢量字體格式有3種:Type1,TrueType和OpenType,這三種格式都是平臺無關的。
- 點陣字體
點陣字體(Dot-matrix-fonts)也叫位圖字體(Bitmap-fonts),其中每個字形都以一組二維像素信息表示。這種文字顯示方式於較早前的電腦系統(例如未有圖形介面時的 DOS 操作系統)被普遍採用。由於位圖的緣故,點陣字體很難進行縮放,特定的點陣字體只能清晰地顯示在相應的字號下,否則文字只被強行放大而失真字形,產生成馬賽克式的鋸齒邊緣。但對於字型大小 8-14px 的尺寸較小的漢字字體(即現今操作系統大多採用的預設字型大小)現今亦仍然被使用於熒幕顯示上,能夠提供更高的顯示效果;不過現今該種點陣字體主要只作為「輔助」的部分,當使用者設定的字體尺寸並無擁有點陣圖像時,字體便會以向量圖方式顯示;而當列印時,印有字體無論大小亦會使用向量字型打印。
好吧,說人話。
點陣字體和矢量字體最大的區別在於縮放之後是否清晰上。點陣字體放大之後會不清晰,而矢量字體不存在這個問題。
點陣字體的優勢是速度快,省資源,很容易把字體效果做好。
是不是還是不清楚,感覺對我們敲代碼沒什麼幫助呀。
那就簡單記住下面的兩句話。
- 數字&字母的顯示,考慮用效果好的
位圖字體(點陣字體)
- 漢字的顯示,儘量用
動態字體(矢量字體)
,然後給字體加效果
上面兩句話不是絕對的,但是剛開始做的時候,按照這個方式來,不會有什麼大問題。
如何控制節點的顯示&隱藏
兩種方式哈,一種是在資源管理器(Cocos Creator 編輯器)中設置,一種是通過代碼設置。
-
資源管理器中設置
如上圖,先在編輯器中選中節點,然後將屬性欄中左上角的checkbox勾選掉,這樣,這個節點就不會顯示了,同樣的,這個節點的子節點也都不會顯示出來。 -
代碼設置
this.node.active = true; //打開(顯示)
this.node.active = false; //關閉(隱藏)
簡單吧,爲什麼要設置節點的隱藏呢?因爲我們不想讓遊戲一開始的時候就把結束的窗口彈出來,就這麼簡單。
那有的人說了,爲什麼不在結束的時候再生成新的窗口呢?
我只能說,可以,但沒必要,這種基礎的,沒什麼變化的節點,只是單純的控制顯示/隱藏即可,沒必要動態生成,敲代碼不累啊。
如何設置節點的相對位置 & 自動大小 & 對齊策略
比如,我想要在距離屏幕左上角 x=100
、y=100
的位置放置一個節點,可以怎麼做呢?
比如,我想要做一個距離屏幕各個邊的距離都是 50 的節點,我要怎麼設置呢?
再比如,我想做一個蒙層,把整個屏幕都蓋住,咋整?
大家想一想,根據我們目前掌握的知識,有沒有方法做到。
在這裏思考 30s。
在這裏思考 30s。
在這裏思考 30s。
在這裏思考 30s。
在這裏思考 30s。
有,對吧。
我們可以獲取屏幕的大小,然後再根據我們前面講的座標的理論,動態的計算各個節點的大小、動態的計算各個節點的位置,就可以了。
但是很麻煩。
今天我們來介紹一個更簡單的方法:對齊掛件(Widget)
Widget 是節點的一個組件,在 Cocos Creator 編輯器中直接添加就可以:
再看看這個東西的設置:
這裏的 Top
、Left
、Bottom
、Right
對應的 checkbox 就是是否啓用這個方向的對齊策略,其對應的輸入框就是具體的對齊的數值。
還有很重要的一個屬性,而且是很容易被忽略的屬性就是 Target
。
他表示我們採用對齊策略時參考的目標節點,畢竟沒有目標的話, 設置相對位置就是胡扯。這個屬性的默認值是當前節點的父節點。
還有個小知識點:Canvas
節點會始終保持和屏幕大小一致。
好了,根據上面知識點,我們能看出來,上圖中的設置,是設置一個 覆蓋整個屏幕
的節點。
如何防止節點的點擊穿透
什麼是點擊穿透呢?簡單來說,就是你點擊了上層的節點,但是這個節點下層的節點響應了點擊事件。
這是瀏覽器的默認策略。
如果我們不屏蔽默認的點擊穿透,就會出現下面這種情況:
我們已經彈出了結束窗了,也蓋上蒙層了,但是還能操作後面的拼圖。
我們要做的,就是防止這件事!
上代碼:
this.maskNode.on('touchstart', function (event) {
event.stopPropagation();
});
this.maskNode.on('touchend', function (event) {
event.stopPropagation();
});
其中 maskNode
就是我們那個覆蓋整個屏幕的蒙層節點。
搞定。
如何倒計時
上面說了半天,還沒點題呢,怎麼添加計時器。
schedule
:開始一個計時器scheduleOnce
:開始一個只執行一次的計時器unschedule
:取消一個計時器unscheduleAllCallbacks
:取消這個組件的所有計時器
簡單吧。
看看我們的核心代碼:
stopTimer() {
this.unschedule(this.__timerCallback);
},
__startTimer() {
this.count = 60;
this.schedule(this.__timerCallback, 1);
},
__timerCallback() {
if (this.count <= 0) {
this.unschedule(this.callback);
this.endManager.getComponent('end-manager').showLose();
return;
}
this.count--;
this.timerLabel.string = "00:" + this.__prefixZero(this.count, 2);
},
__startTimer
方法是開啓我們的計時器,倒計時 60s
,間隔 1s
,每次執行 __timerCallback
方法。
__timerCallback
方法中先判斷計時是否結束,如果沒結束,要更新 label 的值。
其實使用 js 的 setTimeout
和 setInterval
也可以實現大部分功能,大家可以靈活選用。一般情況下還是推薦大家使用 scheduler
來實現
OK了。
總結
知識點
1、矢量字體
和 點陣字體
的區別與如何選用
2、如何控制節點的顯示與隱藏(兩種方式)
3、對齊掛件(Widget)的使用
4、如何防止節點的點擊穿透
5、計時器的使用
下一步
前面斷斷續續也寫了幾篇教程了,收到了以爲熱心同學的反饋:
在拼圖遊戲中,如果幾塊拼圖都重合在一個錨點,感覺會降低遊戲體驗。可是如何做到移動圖片至已經存在圖片的錨點時,將後來的圖片彈到其他區域(也就是說有圖片的錨點不能吸附新的圖片)。這種功能該怎麼實現呢?
真是不好意思,一直沒有弄出來。
下一步,我們就來優化這個問題。
PS:其實這次的標題雖然是如何給遊戲添加計時器,但關於計時器的內容還真是挺少的。剛開始把例子和文章都寫好了,但是覺得知識點太少了,就完善了一下結束時的彈出窗,結果就引出了上面 1234 四個知識點,一發不可收拾。