最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

我們來用Unity復(fù)刻一下《黃金礦工》

2019-04-27 20:00 作者:皮皮關(guān)做游戲  | 我要投稿

作者:繁華如夢


前言

空洞騎士的項(xiàng)目算是告一段落了,開新坑開新坑。

這里只有一個(gè)問題:

不想再肝了。滿腦子裝的都是摸魚。

要是有在摸魚的同時(shí)又能填坑的操作就好了。

對(duì)了。

以前玩過一個(gè)摸魚必備游戲《黃金礦工》,開這個(gè)坑就可以邊摸魚邊填坑了。

經(jīng)過上述不超過5分鐘的、大起大落的心理過程后,便有了這期的文章。

雖然黃金礦工比較簡單,但其中細(xì)枝末節(jié)較多。文章只會(huì)講解較為重要的技術(shù)點(diǎn),其余部分歡迎參考后續(xù)工程代碼食用。

模擬繩子

黃金礦工游戲中,玩家通過按鍵操作并發(fā)射鉤子來挖取金礦,鉤子與絞盤之間有一條繩子進(jìn)行連接,這條繩子我們使用Unity提供的LineRenderer組件來進(jìn)行實(shí)現(xiàn)。

由于素材的限制,我們使用鉤子的這張圖片做為玩家的本體,并在上面添加LineRenderer組件,然后在Materials選項(xiàng)中選擇默認(rèn)的精靈圖材質(zhì)(Sprites-Default),然后將Order in Layer選項(xiàng)修改為1,防止被背景2D物體遮擋。其中,Positions選項(xiàng)是用來設(shè)置線段的2點(diǎn),LineRenderer組件會(huì)在游戲運(yùn)行時(shí)自動(dòng)在2點(diǎn)之間進(jìn)行連線。而我們也是在代碼中動(dòng)態(tài)修改這2點(diǎn)的值,來實(shí)現(xiàn)繩子的效果。大致設(shè)定如圖:

LineRenderer設(shè)置

接下來,在絞盤的位置新建一個(gè)空物體,用于確定線段的起點(diǎn)。然后在代碼中更新Positions選項(xiàng)中點(diǎn)的位置即可。代碼如下:

public class Player : MonoBehaviour {

??? public Transform startTrans;??? //起始點(diǎn)

??? LineRenderer lineRenderer;

??? void Start() {

??????? lineRenderer = GetComponent<LineRenderer>();

??????? lineRenderer.startWidth = 0.1f;//修改線條寬度

??? }

??? void Update() {

??????? UpdataLine();

??? }

??? public void UpdataLine()

??? {

??????? lineRenderer.SetPosition(0, startTrans.position);

??????? lineRenderer.SetPosition(1, transform.position);//設(shè)置線條2點(diǎn)的位置

??? }

}

?

完成后效果如下:

旋轉(zhuǎn)

游戲中,鉤子總是繞著絞盤來進(jìn)行旋轉(zhuǎn)。使用RotateAround這個(gè)函數(shù)就可輕松解決,難點(diǎn)是如何限制鉤子只在下方進(jìn)行旋轉(zhuǎn)操作,而不會(huì)旋轉(zhuǎn)到上方。此處,我們使用向量之間的夾角來進(jìn)行判斷,鉤子是否旋轉(zhuǎn)出邊界。由于素材的問題,鉤子對(duì)應(yīng)的方向是Up軸的正下方。如下圖:

人物朝向

我們就需要通過Up軸的反方向,與絞盤的Right軸之間的夾角,來進(jìn)行旋轉(zhuǎn)的處理。代碼如下:


public enum RotaDir

{

??? left,

??? right,

}//定義旋轉(zhuǎn)方向枚舉

?? ?public RotaDir nowDir;??? //玩家當(dāng)前的旋轉(zhuǎn)方向

??? public float angleSpeed;? //旋轉(zhuǎn)速度

??? public void PlayRotate()

??? {

?

??????? float rightAngle = Vector3.Angle(transform.up * -1, Vector3.right);//計(jì)算玩家前進(jìn)方向與Right的夾角

?

?

??????? if (nowDir == RotaDir.left)

??????? {

??????????? if (rightAngle < 170)

??????????? {?? //在可旋轉(zhuǎn)范圍內(nèi)按當(dāng)前方向繼續(xù)旋轉(zhuǎn)

??????????????? transform.RotateAround(startTrans.position, Vector3.forward, angleSpeed * Time.deltaTime);

??????????? }

??????????? else

??????????? {

??????????????? nowDir = RotaDir.right;//超出范圍,改變方向進(jìn)行旋轉(zhuǎn)

??????????? }

?

??????? }

??????? else

??????? {

??????????? if (rightAngle > 10)

??????????? {

??????????????? transform.RotateAround(startTrans.position, Vector3.forward, -angleSpeed * Time.deltaTime);

??????????? }

??????????? else

?? ?????????{

??????????????? nowDir = RotaDir.left;

??????????? }

?

??????? }

??? }

?

完成后效果如下:

移動(dòng)

通過上面的步驟,我們可以很輕松的知道,鉤子的朝向總是自己的Up軸的反方向。那么移動(dòng)的方向也是如此。只要一直朝這個(gè)方向移動(dòng)就行了,返回也是同樣的道理。代碼如下:

??? public float angleSpeed;

??? public void PlayMoveForward()//前向移動(dòng)

??? {

??????? transform.position += transform.up * -1 * moveSpeed * Time.deltaTime;

??? }

??? public void PlayBackMove()//返回移動(dòng)

??? {

??????? transform.position += transform.up * moveSpeed * Time.deltaTime;

??? }

?

完成后效果如下:

道具交互

不同的道具有不同的交互效果,本作中主要的效果就是得分增加,道具增加,以及玩家移動(dòng)減速了。

道具效果

新建一個(gè)PropScript腳本,專門用來記錄當(dāng)前道具的接觸效果或者獲得分?jǐn)?shù)。其中通過道具的類型來進(jìn)行處理。代碼如下:

public enum PropType

{

??? None,

??? Fraction,??? // 分?jǐn)?shù)類型道具

??? Boom,??? // 炸彈

??? Potion,??? // 雙倍藥劑

} //定義道具類型枚舉

public class PropScript : MonoBehaviour {

?

??? public int fraction;// 當(dāng)前道具分?jǐn)?shù)

??? public PropType nowType;// 當(dāng)前道具類型

??? public int scaleLevel=1;? //當(dāng)前道具的縮放道具? 默認(rèn)為1? 用于計(jì)算玩家鉤住時(shí)的速度

??? public void UseProp()//使用道具的方法

??? {

??????? switch (nowType)

??????? {

??????????? case PropType.Fraction:

??????????????? GameMode.Instance.AddFraction(fraction);//分?jǐn)?shù)增加

??????????????? break;

??????????? case PropType.Potion:

??????????????? GameMode.Instance.isDouble = true;//開啟雙倍開關(guān)

??????????????? break;

??????????? case PropType.Boom:

??????????? ????GameMode.Instance.AddBoomProp();//添加炸彈道具

??????????????? break;

??????? }

??? }

}

人物減速

我們使用觸發(fā)器來檢測鉤子是否抓中了物體,如果抓中了。就在此時(shí)更改玩家的速度。由于之前在PropScript中設(shè)置了縮放的等級(jí),我們可以通過這個(gè)來計(jì)算新的速度(PS:人物速度 = 原人物速度-原人物速度*減速系數(shù)*縮放等級(jí))。代碼如下:

public class Player : MonoBehaviour {

...

??? private void OnTriggerEnter2D(Collider2D collision)

??? {

??????? PropScript propScript = collision.gameObject.GetComponent<PropScript>();

??????? if (propScript != null)

??????? {

??????????? float tempDistance = Vector3.Distance(transform.position, propScript.transform.position);

??????????? propScript.transform.position = transform.position + transform.up * -1 * tempDistance;//位置修正

??????????? propScript.transform.SetParent(transform);//設(shè)置父物體用于拖拽移動(dòng)

??????????? ComputeSpeed(propScript.scaleLevel);

??????? }

??? }

??? public void ComputeSpeed(int scaleLevel)//計(jì)算新的玩家速度

??? {

??????? moveSpeed = moveSpeed - moveSpeed * 0.15f * scaleLevel;

??? }

}

?

道具生成

黃金礦工游戲中,有多種道具來豐富游戲的內(nèi)容。在進(jìn)行道具生成之間,先準(zhǔn)備好對(duì)應(yīng)的游戲數(shù)據(jù),能夠使開發(fā)事半功倍。

數(shù)據(jù)準(zhǔn)備

首先制作所有的道具的2D預(yù)制體,并統(tǒng)一將他們的Order in Layer參數(shù)改為1(PS:由于背景的2D物體對(duì)應(yīng)參數(shù)設(shè)置的為0,為了能夠覆蓋在背景之上,就需要調(diào)高參數(shù)),然后將他們保存在Resources/Prefabs文件夾下(PS:子文件夾可以隨便設(shè)置,但是必須得是在Resources文件夾下),方面后續(xù)代碼的讀取。如下:

不同用途的預(yù)制體

接下來,新建一個(gè)Gamemode腳本,來控制并管理游戲中的道具生成以及勝利相關(guān)功能等。然后在里面初始化對(duì)應(yīng)的道具數(shù)據(jù)。代碼如下:

public class GameMode : MonoBehaviour {

??? public Dictionary<string, GameObject> tempLates;??????? //存儲(chǔ)所有的道具預(yù)制體模板

??? public string[] objNames;?????? //所有分?jǐn)?shù)道具的物體名稱

??? public int[] fractionData;????? //道具的分?jǐn)?shù)數(shù)據(jù)

??? public int[] targetFraction;??? //每一關(guān)的目標(biāo)分?jǐn)?shù)

??? public float[] scaleData;?????? //縮放數(shù)據(jù)

??? public string[] propName;?????? //特殊道具名稱

??? public float minX;?????? //生成的最小X值 面板賦值

??? public float maxX;?????? //生成的最大X值 面板賦值

??? public float minY;?????? //生成的最小y值 面板賦值

??? public float maxY;?????? //生成的最大y值 面板賦值

??? void Start() {

??????? targetFraction = new int[] { 3000, 4000, 5000, 7000, 9000, 12000 ,15000,20000,25000};

??????? objNames = new string[] { "Diamonds", "gold", "goldTwo", "stoneOne", "stoneTwo" };

??????? fractionData = new int[] { 1000, 300, 500, 100, 150 };

??????? propName = new string[] { "explosive", "Potion" };

??????? scaleData = new float[] { 1.0f, 1.2f, 1.5f, 1.8f, 2.0f };//手動(dòng)填入關(guān)卡的相應(yīng)數(shù)據(jù)

??????? InitData();//初始化 讀取數(shù)據(jù)并填充字典

??? }

}

?

其中設(shè)置的道具生成的范圍大致如下圖:

道具生成范圍

道具生成

隨機(jī)位置

已經(jīng)準(zhǔn)備好了對(duì)應(yīng)的數(shù)據(jù),接下來就是根據(jù)對(duì)應(yīng)數(shù)據(jù)生成道具。首先隨機(jī)道具生成的位置,通過之前GameMode設(shè)置的生成數(shù)值,我們可以輕松得到在范圍內(nèi)的隨機(jī)坐標(biāo)。代碼如下:

??? public Vector3 RandomPos()

??? {

??????? float xVaule = Random.Range(minX, maxX);

??????? float yVaule = Random.Range(minY, maxY);

??????? Vector3 tempPoint = new Vector3(xVaule, yVaule, 0);

??????? return tempPoint;

??? }

?

隨機(jī)旋轉(zhuǎn):

??? public Quaternion RandomRotate()

??? {

???? ???float angle = Random.Range(0, 360);

??????? Quaternion tempQuat = Quaternion.AngleAxis(angle, Vector3.forward);

??????? return tempQuat;

??? }

?

由于之前設(shè)置了縮放等級(jí),隨機(jī)縮放就只需要從數(shù)組中取出對(duì)應(yīng)的值即可。于是代碼如下:

??? public float RandomScale(out int scaleLevel)??? // 隨機(jī)道具縮放 返回縮放值,用于計(jì)算

??? {

??????? int index = Random.Range(0, scaleData.Length);

??????? scaleLevel = index+1;

??????? float scaleVaule = scaleData[index];

??????? return scaleVaule;

??? }

?

通過之前設(shè)置的關(guān)卡分?jǐn)?shù)信息,以及各種道具的分?jǐn)?shù)。我們來生成當(dāng)前關(guān)卡的道具。主要是先隨機(jī)出道具,然后計(jì)算當(dāng)前已經(jīng)生成道具分?jǐn)?shù)的總和,查看是否超出目標(biāo)關(guān)卡分?jǐn)?shù),超出就不在生成,不超出就重復(fù)上面的操作。直到分?jǐn)?shù)超出(PS:道具的分?jǐn)?shù)=道具配置的分?jǐn)?shù)*道具的縮放值)。代碼如下:


public class GameMode : MonoBehaviour {

...

??? public int level;//當(dāng)前游戲關(guān)卡數(shù)

??? public void SwitchLevel()

??? {

??????? int creatfraction = 0;????? //現(xiàn)在已經(jīng)生成的分?jǐn)?shù)

??????? int tempfraction = targetFraction[level];//當(dāng)前關(guān)卡的目標(biāo)分?jǐn)?shù)

??????? tempfraction += minFraction;//為了降低游戲難度,讓生成道具的分?jǐn)?shù)總和,能夠超過目標(biāo)分?jǐn)?shù)+minFraction

??????? while (creatfraction < tempfraction)//如果現(xiàn)在生成的分?jǐn)?shù)小于目標(biāo)分?jǐn)?shù)

??????? {

??? ????????int objIndex = Random.Range(0, objNames.Length);

??????????? string tempName = objNames[objIndex];//隨機(jī)道具名稱

??????????? GameObject tempObj = RandomProp(tempName);

??????????? float tempScale = 1;//道具的縮放值

??????????? int scaleLevel = 1;//道具的縮放等級(jí)

??? ????????if (objIndex != 0)//鉆石不進(jìn)行旋轉(zhuǎn)縮放操作

??????????? {

??????????????? Quaternion tempQuat = RandomRotate();

??????????????? tempObj.transform.rotation = tempQuat;

??????????????? tempScale = RandomScale(out scaleLevel);

??????????????? tempObj.transform.localScale *= tempScale;//設(shè)置道具的縮放

??????????? }

??????????? var tempScript = tempObj.AddComponent<PropScript>();//給生成道具添加腳本

??????????? tempScript.nowType = PropType.Fraction;//設(shè)置類型

??????????? int fraction = fractionData[objIndex];//活動(dòng)設(shè)定的道具分?jǐn)?shù)

??????????? fraction = (int)(fraction * tempScale);//計(jì)算出現(xiàn)在的道具分?jǐn)?shù)

??????????? creatfraction += fraction;

??????????? tempScript.fraction = fraction;

??????????? tempScript.scaleLevel = scaleLevel;//設(shè)置道具的縮放等級(jí)

??????????? levelObjs.Add(tempObj);

??????? }

??????? int propCount = Random.Range(0, 3);?????? //場上最多2個(gè)特殊道具

??????? while (propCount > 0)

??????? {

??????????? propCount--;

??????????? GameObject tempObj = RandomSpecialProp();//同上

??????????? levelObjs.Add(tempObj);

??????? }

??? }

??? public GameObject RandomProp(string name)//隨機(jī)道具

??? {

??????? GameObject templateObj = tempLates[name];

??????? Vector3 tempPoint = RandomPos();

??????? GameObject tempObj = Instantiate(templateObj, tempPoint, Quaternion.identity);

??????? return tempObj;

??? }

}

?

游戲演示

結(jié)語

這樣,一個(gè)簡答的黃金礦工就算完成了。但是還缺少UI顯示,關(guān)卡切換等功能,文章沒有給出實(shí)現(xiàn)的講解。歡迎童鞋參考后續(xù)的完整版工程食用,來補(bǔ)上缺失的部分。

相關(guān)鏈接
工程與試玩文件鏈接:https://pan.baidu.com/s/1kTVE9mE6sylGdgDKOzePOw#list/path=%2F



慣例時(shí)間

有想系統(tǒng)學(xué)習(xí)游戲開發(fā)的童鞋,歡迎訪問:http://levelpp.com/?

另有專業(yè)開發(fā)交(gao)流(ji)群等待大家強(qiáng)勢插入:869551769

我們來用Unity復(fù)刻一下《黃金礦工》的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
苏尼特左旗| 和平县| 大连市| 湖南省| 武功县| 海门市| 双鸭山市| 绵竹市| 惠州市| 冷水江市| 开远市| 清远市| 常德市| 郯城县| 休宁县| 建始县| 高青县| 眉山市| 乡宁县| 银川市| 金堂县| 阜阳市| 云和县| 莱阳市| 乳山市| 壶关县| 剑川县| 寻乌县| 涡阳县| 集贤县| 稷山县| 泽库县| 新安县| 西青区| 蕲春县| 河东区| 孟津县| 凤翔县| 准格尔旗| 罗定市| 西乌|