1. 程式人生 > >Unity3d筆記:爐石傳說中的功能實現解析

Unity3d筆記:爐石傳說中的功能實現解析

播放片頭動畫:在void OnGUI()中用GUI.DrawTexture()方法顯示視訊,用GUI.Label()顯示提示;Start()中使用MovieTexture().Play()方法播放視訊。此介面互動分兩種情況:點選一次彈出提示,再點選一次退出視訊;動畫自動播放完畢退出視訊和提示。對於第一種,使用標誌位isShowMessage,第一此點選前isShowMessage=false,點選後變成true,第二次點選前isShowMessage=true,通過判斷isShowMessage來確定這是第一次點選還是第二次點選。對於第二種,判斷如果MovieTexture.isPlaying為false則播放完畢,然後執行StopMov(),注意為了讓StopMov()僅執行一次,條件為isDrawMov!=MovieTexture.isPlaying(等同於MovieTexture.isPlaying&&isDrawMov==true)。

英雄選擇:只要能判斷滑鼠點選的圖示是哪個英雄人物,並把其spriteName和名字陣列的值傳遞過去即可。找spriteName:讓代表英雄的物體名字gameObject.name和圖集中代表英雄的spriteName名字一一對應,這樣滑鼠點選到某英雄圖示時就能找到這個英雄的spriteName。找對應儲存名字的名字:每個英雄命名最後一位加上數字,通過物體名字即transoform.gameObject.name找到這個字串,然後用字元陣列找出字串最後一位即:char nameIndex=heroName[heroName.length-1];通過這個nameIndex索引去找名字陣列中的名字,當然前提是陣列中名字必須和數字號一一對應。

英雄選擇面板控制:建一個空物體或者一個UI容器承載選擇面板的所有UI元素。在其上掛在指令碼控制整個介面的UI互動,比如給元素初始化(一開始隱藏等觸發事件後顯示),比如TweenScale、TweenPosition等動畫播放。

介面的跳轉:相關控制都寫在相機的指令碼StartMenu中。一般介面切換都有動畫,所以只要控制動畫的播放即可進入其他介面,如:TweenPosition.PlayForward()。注意介面的初始化在Awake()中寫上setActive(false)。注意按鈕點選事件偵聽,用UIButton()中的OnClick()。偵聽Tween動畫播放完畢,要用到“事件委託”logoTweenScale.AddOnFinished(this.LogoTweenFinished),LogoTweenFinished為方法。

水晶槽設計:UILable顯示數量,UISprite顯示圖案。把功能封裝到UpdateShow()方法中,在Update()中呼叫方法。定義一個UISprite型別陣列crystals裝水晶和兩個變數usableNum,totalNum分別代表可用水晶和總共水晶數,總共水晶控制物體顯示,可用水晶控制亮暗不同spriteName。通過遍歷陣列控制物體顯示或者更換spriteName,需要四組遍歷:1、控制totalNum後的水晶隱藏(做UI時,sprite擺滿槽),即crystals[i].gameObject.SetActive(false);2、控制0到totalNum間的水晶保持顯示。3、控制usableNum後面的水晶是暗色,即crystals[i].spriteName = "TextInlineImages_normal";。控制0到usableNum間的水晶是按順序正常顯示,即crystals[i].spriteName = "TextInlineImages_0" + (i + 1);注意i==9時,是"TextInlineImages" + (i + 1)。Lable的顯示方法:lable.text = usableNumber + "/" + totalNumber。

歷史卡牌槽設計:封裝AddCard()方法,在Update()中呼叫。先進行UI製作,作為新生成歷史卡牌的位置資訊。在槽內擺滿sprite,card1card2…,再擺一個inCard和一個outCard。用instantiate()生成歷史卡牌,使用prefab,生成位置為inCard.postion(NGUI在生成後,下一幀會初始化到0位置,所以需要用協程停頓一幀讓NGU先I初始化後再執行改變新歷史卡牌的位置)StartCoroutine(AddCard()),yield return 0,IEnumerate。下載外掛itween(project搜尋,選擇appstone,然後下載匯入),再使用itween.MoveTo()製作位移動畫(動畫執行的同時代碼也能繼續執行),移動到card1位置。使用List集合(類似陣列)儲存新生成的歷史卡牌List.Add(GameObject),遍歷陣列向下移動槽內卡牌即cardList[i].transform.position = cardList[i].transform.position + new Vector3(0, yOffset, 0);同時注意cardList.count>6即滿槽時,移出卡牌、刪除卡牌、集合中移除即:iTween.MoveTo(cardList[0],outCard.position,1f);  Destroy(cardList[0],2f);cardList.RemoveAt(0)。

手持卡牌設計:封裝兩個方法:GetCard()獲取卡牌和LoseCard()失去卡牌。GetCard():用NGUITools.AddChild()新增卡牌,iTween.MoveTo(go,toPosition,1f)移動卡牌到手持牌位置(製作UI,定好兩個標記位card1card2),其中toPosition = card1.position + new Vector3(yOffset, 0, 0)*myCard.Count,這裡myCard是集合用於接收新生成的卡牌(myCard.Add(go))。LoseCard():用Destroy()和RemoveAt()分別把該物體刪除和從集合中移除。然後移動該卡牌後卡牌的位置, for (int i = index; i < myCard.Count; i++){Vector3 toPosition = card1.position + new Vector3(yOffset, 0, 0)*i;iTween.MoveTo(myCard[i], toPosition, 0.5f);}這裡index表示第幾張卡牌。

隨機生成卡牌:封裝一個RandomGenerateCard()方法,使用NGUITools.AddChild()生成卡牌,新增兩個卡牌fromCard和toCard用來設定新卡牌位置。在Update()中變換卡片,首先定義計時器timer、變換持續時間transformTime和裝卡牌sprite名字的陣列cardName,通過變換陣列的Index來變換卡牌內容即:index %= cardName.Length;nowGenerateCard.spriteName = cardName[index];這裡的Index是當前播放到了第幾幀(當前時間除以播放一幀需要的時間)即:int index = (int)(timer / (1 / transformCard))。在RandomGenerateCard()中移動動畫播放那一刻開始設定標誌位isTransforming=true,這樣在Update()中就開始變換卡片了。

計時繩:定義一個週期時間cycleTime,一個計時器timer。當一週期內時間只剩下15秒時計時繩開始顯示並播放動畫計時即:if(clycleTime-timer<15){wickPopeSprite.width = (int)(((cycleTime - timer) / 15f) * width);}(把繩子分成15份,隨著時間流逝,長度越來越小;width為初始繩長)當計時繩計時完畢即if(timer>cycleTime){強制切換回合}。

血量顯示:在hero1中建立其子物體Lable顯示血量,封裝TakeDamage(int damage)和Treat(int treat)方法,利用形參傳遞傷害和治療值。定義最大最小血量hpMax和hpMin,呼叫Treat()方法時如果hp>hpMax則hp=hpMax。這裡注意hero1和hero2程式碼幾乎類似,所有定義一個Hero類,讓原先的hero1和hero2類繼承Hero可使程式碼更簡潔,需要注意的是原先private訪問修飾符有些需要改成protected讓子類也能訪問父類中變數。

完成發牌:在遊戲控制裡面新增給hero1發牌方法GenerateCardForHero1(),在此方法中分別呼叫預製體card中指令碼CardGenerate中RandomGenerateCard()和MyCard中的AddCard()方法一次,表示發一張牌。為了讓卡牌變換播放完成,需要留足兩秒再發下一張,因此要做成協程模式。即方法前加IEnumerator,Update()中用StartCoroutine()呼叫它。注意生成卡牌方法需要有返回值,型別為GameObject,這樣在發牌的指令碼中能取到該卡牌,而AddCard()方法也要做成形參,這樣能把卡牌傳遞到AddCard()中(手持卡牌)進行卡牌排序操作。

血量攻擊卡牌三者depth設定:在原始卡牌Card中定義SetDepth(int depth)方法計算三者depth,即:sprite.depth = depth;hpLable.depth = depth + 1;attackLable.depth = depth + 1。在手持卡牌MyCard中,等生成卡牌變成手持卡牌後(卡牌被新增到集合中後)把引數傳遞過來,這個引數在每張卡間相差2即:go.GetComponent().SetDepth(startDepth + myCard.Count*2)。

卡牌可拖拽:給卡牌掛一個指令碼DragableCard,讓其繼承UIDragDrogItem,並重寫OnDragDrogRelease()方法。即protected override void OnDragDropRelease(GameObject surface){base.OnDragDropRelease(surface);}推拽區域設定:用widget畫一個區域,通過判斷surface.tag是否為該widget否則呼叫卡牌順序更新方法即MyCard中的UpdateShow()。即:if(surface.tag!=null&&surface.tag=="widget"){呼叫卡牌排序方法}

解決Lable只能自適應一次:血量和攻擊的Lable只能自適應一次,我們只需要重新執行下UIAnchor指令碼即可,所以我們在卡牌縮小的時候(即MyCard指令碼)加上執行UIAnchor的指令碼即可。在MyCard指令碼中調Card指令碼中的ResetShow()方法,在ResetShow()中寫顯示UIAnchor的程式碼即:hpLable.GetComponent().enabled = true;

卡牌屬性初始化:在Card指令碼中完成卡牌消耗水晶needCraystal、攻擊力harm、血量hp的初始化。因卡牌的sprite名字上面帶有了這三者資訊所以只要從sprite.spriteName提取相關資訊即可。needCraystal=spriteName[5]-'0';harm=spriteName[7]-'0';hp=spriteName[9]-'0'。

如何出牌:要做兩個事情,一是卡牌從手持挪到桌面,二是桌面卡牌排序擺放。在桌面卡牌擺放區容器上掛上指令碼FightCard,裡面分別新增AddCard()和CalsPosition()方法分別處理以上兩件事。AddCard()中把當前拖拽卡牌父類掛到容器上然後在集合中新增此卡牌即go.transform.parent = this.transform;cardList.Add(go);並且確定卡牌擺放位置用itween播放位置移動動畫即iTween.MoveTo(go,targetPos,0.5f)。在CalsPosition()中計算卡牌擺放的位置資訊得到targetPos的值,如果是偶數擺放在左邊並返回一個位置即if (Index%2==0){Vector3 pos = new Vector3(card1.position.x-(Index/2*xOffset),card1.position.y,card1.position.z);return pos。最後在拖拽指令碼中呼叫AddCard()方法和MyCard指令碼中Remove()方法(只一條程式碼:myCard.Remove(go)),這裡注意拖拽指令碼的引數surface即代表當前容器。

水晶的消耗和回合重新整理:在水晶槽管理指令碼Hero1Crystal中分別封裝消耗水晶方法GetCrystal()和回合重置水晶方法ResetCrystalNumber()。一個回合後水晶總數totalCrystal會加1且可用水晶usableCrystal注滿即usableNumber = totalNumber,然後再呼叫水晶顯示方法UpdateShow()更新顯示。消耗水晶需要有返回值且要帶形參,形參是把卡牌消耗值傳遞過來,這時如果可用水晶usableCrystal>卡牌消耗水晶number,則usableCrystal-=number;UpdateShow();return true。返回值是判斷是否成功取得水晶值,沒有說明水晶不夠用返回flase即return false。最後在推拽指令碼中把卡牌水晶消耗值傳遞給水晶消耗處理函式即bool isSuccess = hero1Crystal.GetCrystal(needCrystal);然後通過判斷isSuccess判斷是否能進行出牌操作。

敵人卡牌管理和戰鬥區:分為獲取卡牌和卡牌移除。AddCard()新增卡牌分為制定卡牌父類、加入到集合中、移動到手中動畫,Remove()移除卡牌只要直接刪除即可cardList.Remove(go)。同英雄一樣新增一個容器然後掛上FightCard指令碼。

初始化卡牌數值和顯示:在卡牌建立的時候初始化卡牌,即Card中初始化函式InitProperty()在CardGenerate指令碼等sprite顯示後呼叫此方法。

轉自http://blog.sina.com.cn/s/blog_48e72b7c0102wm1z.html

相關推薦

Unity3d筆記傳說功能實現解析

播放片頭動畫:在void OnGUI()中用GUI.DrawTexture()方法顯示視訊,用GUI.Label()顯示提示;Start()中使用MovieTexture().Play()方法播放視訊。此介面互動分兩種情況:點選一次彈出提示,再點選一次退出視訊;動畫自動播

回歸測試筆記回歸測試只包含功能測試

功能 質量需求 ext mar 包含 開發 spa -i 測試的 一、定義:測試人員只執行了變更引起的相關功能的回歸測試 二、發生時間段Always 三、陷阱表現1.只測試了系統或軟件功能2.回歸測試未包含系統質量測試3.未對架構、設計和實現約束的回歸測試 四、負面後果1

張高興的 Windows 10 IoT 開發筆記BMP180 氣壓感器

bsp git left margin 氣壓 play 氣壓傳感器 分享 get 原文:張高興的 Windows 10 IoT 開發筆記:BMP180 氣壓傳感器  註意:海拔高度僅供參考   GitHub : https://github.com/ZhangGaoxin

張高興的 Windows 10 IoT 開發筆記紅外溫度感器 MLX90614

ima master lock right win hang tps iot pla   GitHub : https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/MLX90614 張高興的 Windows

php學習筆記第三節--php的字串

 PHP 中的字串 字串變數用於包含字串的值。 在本教程中,我們打算介紹幾個在 PHP 中用於操作字串的最常用的函式和運算子。 在建立字串之後,我們就可以對它進行操作了。您可以直接在函式中使用字串,或者把它儲存在變數中。 在下面,PHP 指令碼把字串 "Hello Worl

SpringBoot2.0學習筆記(十) Spring Boot整合Redis

一、關於Lettuce 關於在SpringBoot2.0.x版本中整合Redis,我們先看一下官方的遷移文件有什麼說的: Spring Boot2.0遷移指南 當你使用spring-boot-starter-redis的時候,Lettuce現已取代Jedis作為Redis驅動

資料結構 筆記二叉樹屬性操作的實現

二叉樹的屬性操作 count() = 10; height() = 4; degree() = 2; 二叉樹結點的數目 -定義功能:count(node) ·在node為根結點的二叉樹中統計結點數目 int count(BTreeNode<T>* nod

資料結構 筆記二叉樹的結點刪除與清除

刪除的方式 -基於資料元素值的刪除 ·SharedPointer<Tree<T>>remove(const T& value) -基於結點的刪除 ·SharedPointer<Tree <T>>remove(TreeNode&l

資料結構 筆記二叉樹的結點插入操作

是否能夠在二叉樹的而已結點出插入子結點? -不能,二叉樹結點的每個結點的子結點是固定的,只存在左孩子和右孩子. 是否需要指定新資料元素(新結點)的插入位置? -需要指定為左孩子或者右孩子 enum BTNodePos { ANY, LEFT, RIGHT };

資料結構 筆記二叉樹的結點查詢操作

查詢的方式 -基於資料元素值的查詢 ·BTreeNode<T>* find(const T& value) const -基於結點的查詢 ·BTreeNode<T>* find(TreeNode<T>* node) const 基於資料

SpringBoot2.0學習筆記(九) Spring Boot整合Mybatis與Druid

一、專案的搭建 Druid對Spring boot做了很好的適配,所有的工作都只需要在配置檔案中完成。 具體的Druid在Spring Boot中的配置可以看:GitHub文件 首先看一下專案引入的jar包: <dependencies> &

筆記在C#程式呼叫C++編寫的類

假設C++中有一個類c定義如下:class c { private: int count; public: void add(int n); int get(); }; 其中add函式定義如下:void C:: add(int n){ count +

筆記elasticsearch在專案的使用需求

(摘抄自公司大牛的筆記,自己總結一下) 類比mysql,我們需要=、>、>=、<、<= 、or、and、in、like、count、sum、group by、order by、limit 在高版本的ES裡面使用了boolquery替換

CCF CSP 程式設計題目和解答-----試題名稱傳說 -------201609-3

#include<iostream> #include<algorithm> #include<vector> #include<string> using namespace std; bool endgame = false;//遊戲是否結束的標誌位

Python機器學習筆記深入理解Keras序貫模型和函式模型

  先從sklearn說起吧,如果學習了sklearn的話,那麼學習Keras相對來說比較容易。為什麼這樣說呢?   我們首先比較一下sklearn的機器學習大致使用流程和Keras的大致使用流程: sklearn的機器學習使用流程: 1 2 3 4

java筆記Java字串陣列判斷是否存在某元素的方法

/** * JAVA判斷字串陣列中是否包含某字串元素 * * @param substring 某字串 * @param source 源字串陣列 * @return 包含則返回true,否則

筆記防止 Safari 瀏覽器的數字被識別為電話號碼

在Safari瀏覽器中,有一個預設開啟的功能, 會把網頁中的數字自動識別為電話號碼, 並且改變文字的顏色和樣式(藍色),這種情況下如果我們需要相應位置背景色也為藍色或其他,就有點尷尬,而 這個預設樣式貌似也改不了。 解決方法: 在<head>&l

讀書筆記新類庫的構件

1.CountDownLatch:被用來同步一個或多個的同步任務,強制它們等待由其他任務執行的一組操作完成。可以向CountDownLatch物件設定一個初始計數值,任何在這個物件上呼叫wait()方法都將阻塞,直到這個計數值到達0。其他任務在結束工作的時候,可以在這個物件上

Flask學習筆記檔案上原生實現

import os from flask import Flask, request, redirect, url_for from werkzeug.utils import secure_filename UPLOAD_FOLDER = '/path/to/the/up

一、Linux學習筆記虛擬機器設定的各種網路連線方式詳解

說明:我本機安裝的VMWare10,吳老師的視訊教程用的是VirtualBox,配置虛擬機器連線方式是HostOnly。我在本機用VMWare使用HostOnly連線方式未配置成功:虛擬機器能ping通宿主機,但是宿主機ping不同虛擬機器,不知原因何在。因此改用