注意:這個卡讀成“qi?!?。
如果至始至終都是一樣的速度,那也太無聊了。所以增加關(guān)卡就很有必要了。
01.制作關(guān)卡對象
直接復(fù)制一個場景中的“HighScore”,重命名為Level,調(diào)整坐標(biāo):(206, 97, 0)。
刪除最后一個數(shù)字,修改中間的數(shù)字:除了“Middle”,全部隱藏。
然后將03重命名為Line,04,05重命名為03,04:


然后移除該對象上的ScoreScreen腳本組件。
02.添加關(guān)卡類
添加一個關(guān)卡類腳本:Level。該類只需4個數(shù)字,前兩個數(shù)字為主關(guān)卡,后兩個為次關(guān)卡:
using UnityEngine;
public class Level : MonoBehaviour
{
public GameObject Number01;
public GameObject Number02;
public GameObject Number03;
public GameObject Number04;
public void SetLevel(int mainLevel, int MinorLevel)
{
// 設(shè)置主關(guān)卡
Number01.GetComponent<Number>().SetNumber(mainLevel % 100 / 10);
Number02.GetComponent<Number>().SetNumber(mainLevel % 10);
// 設(shè)置次關(guān)卡
Number03.GetComponent<Number>().SetNumber(MinorLevel % 100 / 10);
Number04.GetComponent<Number>().SetNumber(MinorLevel % 10);
}
}
03.添加關(guān)卡腳本
將腳本添加至關(guān)卡對象上,并綁定場景中的數(shù)字對象:

除此之外,還要將關(guān)卡對象拖放到導(dǎo)演對象的“Level Obj”上。
04.添加成員和初始化
準(zhǔn)備工作都做好了,接下來實現(xiàn)功能。
首先要添加成員,關(guān)卡腳本的引用和關(guān)卡值:
Level _levelScript;
int _level; // 關(guān)卡
本游戲沒有主次關(guān)卡之分,所以只需要一個關(guān)卡值就夠了。
然后就是初始化:
_level = 0;
// 初始化關(guān)卡
_levelScript = LevelObj.GetComponent<Level>();
if (_levelScript == null) return false;
_levelScript.SetLevel(0, _level);

05.如何實現(xiàn)變速
僅僅是實現(xiàn)變速的話,將定時器的時間間隔修改下即可:
InvokeRepeating("GameCore", 0, 1 - (_level - 1) * 0.1f);
按照這個公式,那么關(guān)卡1~10的速度分別為:
1 - 1s下落1格
2 - 0.9s下落1格
3 - 0.8s下落1格
4 - 0.7s下落1格
5 - 0.6s下落1格
6 - 0.5s下落1格
7 - 0.4s下落1格
8 - 0.3s下落1格
9 - 0.2s下落1格
10 - 0.1s下落1格,這個是最快的速度,一秒下落10格
計算速度并不難,關(guān)鍵是變速的時機(jī)。
首先,當(dāng)方塊處于加速下落時(按下下方向鍵但不松開),肯定不能變更速度,否則按鍵還沒松開,速度突然變慢了(加速的速度大于所有關(guān)卡的速度)算怎么回事?
然后消除方塊后如果正好使分?jǐn)?shù)達(dá)到了提升關(guān)卡的條件,那么就需要變速,也就是說,在消除方塊階段結(jié)束后,需要啟動一個更快的定時器來驅(qū)動GameCore()。但如果在這里啟動定時器,就會重現(xiàn)第32節(jié)中出現(xiàn)的Bug,不過有一個比較不錯的解決方案,就是在Invoke Repeating()之前先調(diào)用CancleInvoke():
CancelInvoke("GameCore");
InvokeRepeating("GameCore", 0, 1 - (_level - 1) * 0.1f);
雖然還是會有問題(多線程的問題),不過應(yīng)該能大大減少觸發(fā)Bug的概率。之前的Bug是因為我沒有調(diào)用CanlInvoke():

調(diào)用CancleInvoke()之后:

不過還是會有問題,因為有可能會出現(xiàn)這種順序:

只是概率非常低,因為停止和啟動兩行代碼是寫在一起的,要觸發(fā)Bug需要你松開按鍵的時機(jī)必須剛剛好卡在線程一的這兩行代碼之間。就算觸發(fā)了,按一下加速就恢復(fù)了。
然后因為不能在加速狀態(tài)中變速,所以需要加一個標(biāo)記來判斷是否處于加速狀態(tài)中:
bool _InQuickDown = false; // 記錄是否正在快速下落
在按下下方向鍵時設(shè)置為true,松開后設(shè)置為false,順便修改啟動核心邏輯的定時器代碼,根據(jù)關(guān)卡來計算時間間隔:
// 按鍵 - 下方向鍵
if (Input.GetKeyDown(KeyCode.DownArrow))
{
_InQuickDown = true;
CancelInvoke("GameCore");
InvokeRepeating("GameCore", 0, 0.03f);
}
if (Input.GetKeyUp(KeyCode.DownArrow))
{
_InQuickDown = false;
CancelInvoke("GameCore");
InvokeRepeating("GameCore", 0, 1 - (_level - 1) * 0.1f);
}
然后需要在消除階段結(jié)束后變更速度前添加一個判斷:
// 如果未處于加速中
if (!_InQuickDown)
{
CancelInvoke("GameCore");
InvokeRepeating("GameCore", 0, 1 - (_level - 1) * 0.1f);
}
好了,現(xiàn)在變速的幾個地方都添加好代碼了,最后一件事就是根據(jù)分?jǐn)?shù)計算關(guān)卡。
我的關(guān)卡提升規(guī)則是,每增加2500分提升一個Level:
// 更新關(guān)卡
int newLevel = _currentScore / 2500 + 1;
if (newLevel > 10) newLevel = 10;
if (newLevel > _level)
{
_level = newLevel;
_levelScript.SetLevel(0, _level);
}
為了方便測試提升關(guān)卡后是否會提升速度,你可以將2500改成一個很小的值,比如200分。
1秒下落10格真的反應(yīng)不過來:

代碼鏈接:https://pan.baidu.com/s/1eIYPXNIL6V8i-aJ6ncmcXQ
提取碼:at6a