2DRoguelike拾荒者(unity)

同樣的溜哮,實(shí)現(xiàn)過程只記大致思路與新知識點(diǎn)谊路,不記細(xì)節(jié)赊锚。
github: https://github.com/robotluo/2DRoguelike
大致實(shí)現(xiàn)功能:
 1.創(chuàng)建主角和敵人成箫,創(chuàng)建地圖
 2.隨機(jī)生成敵人和食物
 3.獲取食物格郁、碰撞檢測
 4.與敵人碰撞時(shí)狀態(tài)機(jī)的變換
 5.血量控制腹殿、關(guān)卡轉(zhuǎn)換
 6.添加音效

2DRoguelike 是官方的案例之一独悴,與之前所用的有所區(qū)別在于使用了狀態(tài)機(jī)來控制人物動(dòng)畫。
  狀態(tài)機(jī)保存了許多不同的狀態(tài)锣尉,事件觸發(fā)可以改變狀態(tài)機(jī)的狀態(tài)刻炒,實(shí)現(xiàn)效果的轉(zhuǎn)換。

創(chuàng)建地圖:

將素材裝入一個(gè)數(shù)組自沧,隨機(jī)一個(gè)索引并創(chuàng)建實(shí)例落蝙。

// outWalls 為外墻數(shù)組
// Map 為一個(gè)空 GameOnject 的 Transform,用于裝載地圖暂幼,比較整潔 
int outWallIndex = Random.Range (0, outWalls.Length);
GameObject tmp = GameObject.Instantiate (outWalls [outWallIndex], new Vector3 (row, col, 0), Quaternion.identity) as GameObject;
tmp.transform.SetParent (Map);

當(dāng)我們有許多實(shí)例需要隨機(jī)生成時(shí)筏勒,例如,敵人旺嬉、食物管行、障礙物等都需要隨機(jī)生成在地圖中,因此可以寫一個(gè)專門的方法邪媳。
先將地圖上能存實(shí)例的坐標(biāo)存入 mapList:

private List<Vector2> mapList = new List<Vector2>();
//將地圖上能放置物品的坐標(biāo)存入 mapList
        mapList.Clear ();
        for (int row = 2; row <= rowMax - 2; row++) {
            for(int col =2 ;col <= colMax - 2; col++) {
                mapList.Add (new Vector2 (row, col));
            }
        }

專門用于創(chuàng)建的方法:

void creatElement(int count, GameObject[] array){
        for (int i = 0; i < count; i++) {
            int listIndex = Random.Range (0, mapList.Count ); //隨機(jī)取得放置點(diǎn)
            int arrIndex = Random.Range (0, array.Length);  //隨機(jī)取得對象

            Vector2 pos = mapList [listIndex]; //取出放置點(diǎn)
            mapList.Remove(pos);            // list 中去掉該位置
            GameObject tmp = GameObject.Instantiate (array[arrIndex],pos,Quaternion.identity) as GameObject;
            tmp.transform.SetParent (Map);
        }
    }

調(diào)用時(shí)只需要傳入數(shù)量和數(shù)組即可捐顷。

狀態(tài)機(jī)的創(chuàng)建:

將素材多選直接拖入Hierarchy 中,會(huì)自動(dòng)生成兩個(gè)文件雨效。一個(gè)是動(dòng)畫迅涮,這里命名為 Animation ,另一個(gè)是控制器徽龟,這里命名為AnimatorController叮姑。狀態(tài)機(jī)的邏輯非常簡單,將每個(gè)狀態(tài)的具體實(shí)現(xiàn)封裝起來据悔,當(dāng)滿足某個(gè)條件传透,將狀態(tài)從當(dāng)前狀態(tài)轉(zhuǎn)換到另一狀態(tài),狀態(tài)內(nèi)部與狀態(tài)轉(zhuǎn)換之間不互相影響极颓。
  如果一個(gè)主角有多個(gè)狀態(tài)朱盐,例如有靜止、移動(dòng)菠隆、攻擊兵琳、受傷等等,只需要將其全部拖到同一個(gè)物體上骇径,如果直接拖到 Hierarchy 會(huì)產(chǎn)生多個(gè)狀態(tài)機(jī)躯肌。
共用狀態(tài)機(jī):
  狀態(tài)機(jī)分為兩部分,動(dòng)畫和控制既峡。在實(shí)際中我們可能需要多個(gè)角色共用同一狀態(tài)機(jī)羡榴。例如碧查,兩種不同的怪物运敢,他們的動(dòng)畫不同校仑,但是處理狀態(tài)的邏輯是完全一樣的,這時(shí)候如果分別使用兩個(gè)狀態(tài)機(jī)就有點(diǎn)多余传惠,所以需要共用迄沫。
  我們可以這么做,如果我們有了一個(gè) Controller_1 想要重用,首先在同一文件夾下右鍵 -> create -> Animator Override Controller卦方,命名為 Controller_2 羊瘩,點(diǎn)擊 Controller_2 會(huì)看到 Inspector 視圖下有一個(gè) Controller 需要賦值,將 Controller_1 賦值到此處盼砍,再將新的動(dòng)畫進(jìn)行對應(yīng)賦值尘吗。這樣,Controller_1 與 Controller_2 就共用一套邏輯浇坐。
狀態(tài)切換:
  雙擊一個(gè)控制器睬捶,選中一個(gè)狀態(tài),右鍵 Make Transition近刘,會(huì)出現(xiàn)一個(gè)箭頭擒贸,此時(shí)連接到需要轉(zhuǎn)換的狀態(tài)。
例如:

狀態(tài)機(jī).png

連線代表能夠轉(zhuǎn)換觉渴,現(xiàn)在需要自定義轉(zhuǎn)換的條件介劫。如下圖,添加兩個(gè) Trigger
Trigger.png

選中連線案淋,再在 Inspector 視圖下 Conditions 添加 所需Trigger座韵,改變Has Exit Time 勾選,Has Exit Time表示播放完變換踢京,當(dāng)我們攻擊時(shí)應(yīng)該是立刻做出反應(yīng)回右,所以不需要勾選。而從攻擊狀態(tài)變?yōu)槠胀顟B(tài)只需要播放完即可漱挚,不需要Trigger翔烁。

主角移動(dòng):

添加 Rigidbody ,用 MovePosition 方法移動(dòng)

myRigidbody = GetComponent<Rigidbody2D> ();
myRigidbody.MovePosition (Vector2.Lerp(transform.position, movePosition, moveSpeed * Time.deltaTime));
//(當(dāng)前位置旨涝,目標(biāo)位置蹬屹,移動(dòng)速度)

碰撞檢測:
  這里采用射線的方式進(jìn)行碰撞檢測,向目標(biāo)位置發(fā)射射線白华,判斷所碰撞物體種類再進(jìn)行相關(guān)處理慨默。

myCollider.enabled = false; //去掉當(dāng)前碰撞器,防止檢測到自身
RaycastHit2D hit = Physics2D.Linecast (movePosition,movePosition + new Vector2(hor,ver));
myCollider.enabled = true; //重新啟用碰撞器

對 hit 進(jìn)行判斷和相關(guān)處理即可弧腥。
例如:攻擊墻體厦取,需要向其發(fā)送一個(gè)信息,以及播放攻擊動(dòng)畫

private Animator myAnimator;
myAnimator = GetComponent<Animator> ();
myAnimator.SetTrigger ("Attack"); //改變狀態(tài)機(jī)

hit.collider.SendMessage ("Damager");//調(diào)用墻體的 Damager fangfa

怪物控制:
  怪物與主角的控制方式不同管搪,主角是按鍵控制虾攻,而怪物是自己移動(dòng)铡买。
在一個(gè)單例 GameManager 中用一個(gè) List 儲(chǔ)存所有敵人,當(dāng)主角移動(dòng)時(shí)霎箍,調(diào)用 GameManager 中的 相應(yīng)方法奇钞,遍歷 List 通知所有敵人移動(dòng)。

Text 顯示信息:
  我們需要幾個(gè) UI Text 來顯示信息漂坏,需要顯示當(dāng)前食物的剩余景埃、提示當(dāng)前關(guān)卡、游戲結(jié)束時(shí)顯示 Game Over顶别」柔悖 
例如顯示食物數(shù)量:

private Text foodText;  //
foodText = GameObject.Find ("FoodText").GetComponent<Text> ();//按名稱查找
foodText.text = "Food : " + Hp;

關(guān)卡變換:

關(guān)卡的變換首先要判斷是否到達(dá)這種,這里有一個(gè)細(xì)節(jié)驯绎。我們判斷是否到達(dá)終點(diǎn)需要知道主角的位置蒂胞,所以在 GameManager 中要先獲得主角的引用。但若是在 Awake 中獲取条篷,MapManager 可能并沒有把主角創(chuàng)建出來骗随,此時(shí)會(huì)報(bào)錯(cuò)。所以地圖的創(chuàng)建一定要在 MapMahager 中的 Awake赴叹,而主角的獲取需要在 GameManager 中的 Start鸿染。
  當(dāng)然,還有一種方式就是在 GameManage 中統(tǒng)一控制乞巧,先創(chuàng)建地圖再創(chuàng)建 UI涨椒。
  關(guān)卡變換涉及到一個(gè)場景的切換(新知識),關(guān)卡變換地圖需要重新生成绽媒,但血量蚕冬,關(guān)卡數(shù)需要保留。
  為了保留血量和關(guān)卡是辕,我們在進(jìn)入新的關(guān)卡時(shí)不能銷毀當(dāng)前 GameManager 囤热。

DontDestroyOnLoad (this.gameObject);//在 GameManager 中使用此方法,重新加載時(shí)不銷毀 GamaManager
void OnLevelWasLoaded(int scenesLevel) { 
//每次加載關(guān)卡時(shí)都會(huì)調(diào)用获三,可以在其中寫一些需要更新的信息旁蔼,具體可以查看API
  level++;
  initGame (); //初始化場景
}

此時(shí)會(huì)發(fā)現(xiàn)疙教,雖然當(dāng)前 GameManager 沒有被銷毀棺聊,但是出現(xiàn)了兩個(gè) GamaManager 。所以我們需要將 GameManager 做成 Prefabs 贞谓,不讓它存在場景中限佩,而是用創(chuàng)建的方式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裸弦,一起剝皮案震驚了整個(gè)濱河市祟同,隨后出現(xiàn)的幾起案子作喘,更是在濱河造成了極大的恐慌,老刑警劉巖耐亏,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徊都,死亡現(xiàn)場離奇詭異沪斟,居然都是意外死亡广辰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門主之,熙熙樓的掌柜王于貴愁眉苦臉地迎上來择吊,“玉大人,你說我怎么就攤上這事槽奕〖妇Γ” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵粤攒,是天一觀的道長所森。 經(jīng)常有香客問我,道長夯接,這世上最難降的妖魔是什么焕济? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮盔几,結(jié)果婚禮上晴弃,老公的妹妹穿的比我還像新娘。我一直安慰自己逊拍,他們只是感情好上鞠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著芯丧,像睡著了一般芍阎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缨恒,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天能曾,我揣著相機(jī)與錄音,去河邊找鬼肿轨。 笑死寿冕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的椒袍。 我是一名探鬼主播驼唱,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼驹暑!你這毒婦竟也來了玫恳?” 一聲冷哼從身側(cè)響起辨赐,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎京办,沒想到半個(gè)月后掀序,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惭婿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年不恭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片财饥。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡换吧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钥星,到底是詐尸還是另有隱情沾瓦,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布谦炒,位于F島的核電站贯莺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宁改。R本人自食惡果不足惜缕探,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望透且。 院中可真熱鬧撕蔼,春花似錦、人聲如沸秽誊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锅论。三九已至讼溺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間最易,已是汗流浹背怒坯。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留藻懒,地道東北人剔猿。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像嬉荆,于是被迫代替她去往敵國和親归敬。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)汪茧,斷路器椅亚,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件舱污、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評論 4 62
  • This article is a record of my journey to learn Game Deve...
    蔡子聰閱讀 3,783評論 0 9
  • 文/鴻運(yùn) 雨后天邊掛彩虹呀舔,云托雁字輕。 高山流水賦真情扩灯,竹林簫響應(yīng)媚赖。 爬山虎,醉翁亭驴剔,層層碧綠蔥省古。 欲把花草化春雨...
    HONGYUNDANGTOU閱讀 535評論 6 12
  • 我很多時(shí)候都在想粥庄,自己內(nèi)心真正想做的事情到底是什么丧失。雖然我的興趣愛好很廣泛,但是在所有興趣之中我最終還是得找一樣來...
    鈐魚擺擺閱讀 158評論 1 1