【Unity3d】手機游戲關卡制作


很多手機游戲的關卡都是采用激活和未激活的狀態

當某一關通過以后 則再次進入關卡選擇界面時 相應的圖標顯示激活狀態 否則為未激活狀態

如憤怒的小鳥

 

這里使用unity3d內置GUI系統

繪制按鈕之前我們需要知道哪些關卡是已經通過了的

在unity3d中可以使用PlayerPrefs來保存關卡信息 詳見PlayerPrefs

我們使用一個boolean數組來標識關卡的激活狀態

var m_bActive : boolean[];

在初始化過程中讀取PlayerPrefs保存的關卡信息 

如果已經通過則為true  否則為false  關卡通過條件取決於具體的游戲規則  例如每關所用時間小於3分鍾為通過等等

m_bActive = new boolean[m_iLevelTotals];

for (idx = 1; idx < m_iLevelTotals; ++idx)
(關卡通過條件) ? m_bActive[idx] = true : m_bActive = false;
m_bActive[0] = true;

這里將第一關默認為激活狀態  不然所有關卡全鎖定  則現場直憋了

通過初始化  已經知道了關卡的通過信息

繪制關卡圖標之前 我們知道unity3d的GUI有GUISkin和GUIStyle

GUISkin可以指定多個GUI的風格

而GUIStyle只是針對一個GUI風格

因此我們要為關卡的按鈕定義一個GUIStyle 

 

var m_GuiStageBtn    : GUIStyle;

並有一個激活狀態的圖片和未激活狀態的圖片

 

var m_texLocked : Texture2D;
var m_texActive : Texture2D;

下面開始繪制關卡圖標  這里假設當前頁有16關  則要繪制16個圖標  4行4列

 

// col_1
for ( i = 0; i < 13; i += 4)
{
if (!m_bEasyActive[i])
m_GuiStageBtn.normal.background = m_texLocked;
else
m_GuiStageBtn.normal.background = m_texActive;

if (GUI.Button(Rect(81, 29 * i + 220 , 57, 52), "", m_GuiStageBtn))
{
if (!m_bEasyActive[i])
return;
if (m_bEffectActive)
audio.PlayOneShot(g_ButtonDownClip);

g_iCurrentLevel = i + 1;
LoadSelectLevel(g_iCurrentLevel);
}
}
// col_2
for ( i = 1; i < 14; i += 4)
{
if (!m_bEasyActive[i])
m_GuiStageBtn.normal.background = m_texLocked;
else
m_GuiStageBtn.normal.background = m_texActive;

if (GUI.Button(Rect(165, 29 * (i - 1) + 220, 57, 52), "", m_GuiStageBtn))
{
if (!m_bEasyActive[i])
return;
if (m_bEffectActive)
audio.PlayOneShot(g_ButtonDownClip);

g_iCurrentLevel = i + 1;
LoadSelectLevel(g_iCurrentLevel);
}
}
// col_3
for (i = 2; i < 15; i += 4)
{
if (!m_bEasyActive[i])
m_GuiStageBtn.normal.background = m_texLocked;
else
m_GuiStageBtn.normal.background = m_texActive;

if (GUI.Button(Rect(250, 29 * (i - 2)+ 220, 57, 52), "", m_GuiStageBtn))
{
if (!m_bEasyActive[i])
return;
if (m_bEffectActive)
audio.PlayOneShot(g_ButtonDownClip);

g_iCurrentLevel = i + 1;
LoadSelectLevel(g_iCurrentLevel);
}
}
// col_4
for ( i = 3; i < 16; i += 4)
{
if (!m_bEasyActive[i])
m_GuiStageBtn.normal.background = m_texLocked;
else
m_GuiStageBtn.normal.background = m_texActive;

if (GUI.Button(Rect(345, 29 * (i - 3) + 220, 57, 52 ), "", m_GuiStageBtn))
{
if (!m_bEasyActive[i])
return;
if (m_bEffectActive)
audio.PlayOneShot(g_ButtonDownClip);

g_iCurrentLevel = i + 1;
LoadSelectLevel(g_iCurrentLevel);
}
}

當然  可以在繪制之前  也就是 if (GUI.Button(...)) 之前  直接根據當前關卡的激活狀態來處理按鈕的激活狀態  加上GUI.enabled = m_bActive[i];

很簡單  但是在循環繪制時候要細心  設想這只是繪制16個圖標  若是繪制很多  再加上Easy模式  Hard模式  Expert模式等等  則很容易出錯 

但是原理基本上不變  

使用Unity3d的內置GUI  則繪制GUI時的位置是很頭疼的  而且GUI的繪制函數OnGUI是消耗比較大的  再加上drawcall帶來的渲染效率

在手機游戲的應用中都是不容忽視的問題  另外Unity3d中GUI的自適應縮放可以查看另一篇文章 

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM