跳轉到內容

GBA 開發/HAM IDE

來自 Wikibooks,開放的書籍,開放的世界
Game Boy Advance 開發
示例繪圖應用程式的開發

使用 HAM IDE 和編譯器進行 GBA 開發

[編輯 | 編輯原始碼]

步驟 1 - 設定

[編輯 | 編輯原始碼]

這個專案的第一步是從這些連結下載並安裝必要的程式。

開啟第一個可執行檔案並執行它,當它完成檔案解壓縮後,會提示你輸入 'OK'(所以就輸入),還要指定一個安裝路徑。將安裝路徑設定為 C:\GBADev 。完成這些步驟後,點選 '安裝',它應該能順利完成。

接下來執行第二個可執行檔案,點選 '下一步',然後選擇 '我接受協議',再次點選下一步,選擇 vham 將要安裝到的資料夾(它應該已經被選中,但如果沒選,就將其放到 C:\GBADev\vham 下),然後點選 '下一步' -> '下一步' -> '下一步' -> '安裝' -> '完成'。如果一切順利,你應該已經設定好了 Gameboy Advance 開發環境,並且可以開始製作遊戲了!

步驟 2 - 開始一個新專案

[編輯 | 編輯原始碼]

如果你還沒有開啟 VHam 環境,請雙擊桌面的 'VisualHAM' 圖示。開啟後,我們將建立一個新專案,所以請點選 '檔案' >> '新建' >> '新建專案'。我們要建立的專案型別是 '[C++ 空白]' 型別專案,所以選擇它,然後輸入專案名稱和位置。專案名稱是什麼並不重要,只要你記住它就行,位置可以是硬碟上的任何資料夾。(如果你想不出合適的專案名稱或位置,就輸入 "etchasketch" 作為專案名稱,輸入 "c:\projects\etchasketch" 作為位置)。

步驟 3 - 熟悉 main.cpp 檔案

[編輯 | 編輯原始碼]

專案建立完成後,在左側視窗中會有兩個可以編輯的檔案,main.cpp 和 makefile。不要對 makefile 進行任何更改(在這個專案中不需要它),它只在更高階的專案中需要。我們唯一要更改的檔案是 main.cpp 檔案。基本上,這個檔案是遊戲執行時執行的程式碼。請雙擊左側窗格中的 'main.cpp'。

這個檔案大多是空的,除了幾行程式碼。目前,你的遊戲所做的就是顯示 HAM 徽標,然後顯示一個空白的黑色螢幕。讓我解釋一下檔案中的一些專案及其作用。

#include <mygba.h>

這行程式碼將大量其他函式和宣告包含到程式中,供我們使用。除非你想在機器級別上做所有事情(很不方便),否則這是必需的。

MULTIBOOT

允許你的遊戲從連線線啟動,而無需遊戲卡。在這個專案中不需要,可以刪除它。

int main(void)
{}

第一個花括號和最後一個花括號之間的所有內容都是程式的主體。遊戲從第一個花括號開始,在最後一個結束花括號處結束。

ham_Init();

程式主體中的第一條語句。初始化所有 HAM 功能。還會導致在遊戲開始時顯示那個小型的 '用 HAM 建立" 徽標。

while(true)
{}

一個不斷執行且永不結束的迴圈。這基本上會使遊戲停滯,導致它永遠不會結束(大多數情況下,控制檯遊戲會由使用者關閉電源而結束)。如果遊戲執行到最後,它會從頭開始重新啟動。這個語句只是為了防止遊戲結束。

return 0;

這個語句只是告訴你的 main() 函式退出,返回值為 '0'。通常這表示程式已成功結束。當執行這行程式碼時,遊戲將結束,然後重新啟動(如果電源仍然開啟)。

步驟 4 - 構建並執行你的遊戲

[編輯 | 編輯原始碼]

這一步應該很容易。在你對 main.cpp 檔案進行任何更改後,如果你想檢視它們對遊戲的影響,只需點選 '檔案' >> '全部儲存' 儲存程式碼,然後按鍵盤上的 'F6' 鍵編譯並執行你的遊戲。你也可以透過點選紅色 ! 符號使用其他選項進行構建。如果一切正常,你應該有一個執行的遊戲!恭喜你...... 它現在還不太完善,但很快就會好起來的。

步驟 5 - 向 main.cpp 新增第一個附加函式

[編輯 | 編輯原始碼]

現在,我們將開始真正地向這個遊戲新增一些有用的程式碼。我們希望我們的遊戲在螢幕上顯示一些東西,對吧?讓我們新增一個函式,它將一個特定顏色的畫素繪製到螢幕上。如果你對畫素或函式有疑問,我會在課堂上解釋。

在程式碼行 ham_Init(); 後面,你需要新增以下程式碼行

ham_SetBgMode(3);

這將使 Game Boy 硬體進入特定的影片模式(模式 3),這將使我們能夠以順序記憶體陣列的形式直接訪問影片記憶體(我會在課堂上解釋這個術語)。這樣可以方便地在螢幕上放置一個畫素。

現在,我們需要向程式新增一個函式。所有函式都將在 main() 函式上方,但位於 #include <mygba.h> 部分下方。任何呼叫其他函式的函式只能呼叫宣告在其上方的函式。main() 將呼叫我們所有其他的函式,因此它需要位於最底部。請將以下函式新增到你的 main.cpp 檔案中

//Function that draws a single pixel to the screen
void drawPix(int xPos, int yPos, int color)
{
unsigned short* videoBuffer = (unsigned short*)0x6000000;
videoBuffer[(yPos*240) + xPos] = color;
}

現在你有了這個函式,你可以在 main() 函式中的任何位置呼叫 drawPix()。你需要告訴函式在螢幕右側多遠(xPos)、在螢幕下方多遠(yPos)以及畫素要是什麼顏色(color)。我會在課堂上詳細解釋。但例如,如果你想在螢幕右側 50 畫素、下方 100 畫素的地方繪製一個白色畫素,你可以在 main() 函式中呼叫以下程式碼行

drawPix(50,100,0xFFFFFF);

你可以測試它,儲存你的專案,然後執行你的程式(有關詳細資訊,請參閱步驟 4)。

步驟 6 - 使用變數儲存資訊

[編輯 | 編輯原始碼]

在我們的 Etch-A-Sketch 程式中,我們需要儲存一些關於 Etch-A-Stetch 筆的位置和當前繪製顏色的資訊。這將需要 5 個變數。其中 2 個用於儲存筆的位置(水平和垂直方向的距離),另外 4 個用於顏色(筆中紅色、綠色和藍色的值,以及總的筆顏色)。

在剛剛宣告的函式上方,我們將建立 6 個全域性變數。將以下行放在 #include <mygba.h> 部分的下方(但在其他函式之上)。

// Global variables
int curX, curY, curColor;
u8 cR, cG, cB;

我們還需要在 main() 函式中初始化這些變數,以便將它們的值設定為零,而不是一些隨機的垃圾值。在語句 ham_SetBgMode(3); 的下方新增以下行

curX = 0;
curY = 0;
cR = 0xFF;
cG = 0xFF;
cB = 0xFF;
curColor = 0xFFFF;

現在,您可以透過檢查變數的值或更改變數的值來跟蹤繪製筆的狀態。我們將在後面從按鍵獲取輸入時進行操作。事實上,這直接引出了下一部分。

第 6 步 - 從鍵盤獲取輸入

[編輯 | 編輯原始碼]

如果不能控制遊戲,那它有什麼用呢?輸入其實很簡單。只需要檢查某些值是真還是假。基本上,“A”按鈕在特定時間要麼被按下,要麼沒有被按下。棘手的是決定每個按鍵被按下意味著什麼。讓我們在 drawPix() 函式下方再建立一個函式,從按鍵獲取輸入,並根據輸入更改變數的值。

//Gets input from the joypad
void query_input()
{

}

請注意花括號之間有一些空白。我們將在其中新增更多程式碼,這些程式碼實際上會檢查按鍵。這是透過使用 If() 語句完成的。如果語句為真,則其下方的程式碼行將被執行,否則將被跳過。假設我們想要在按下向下鍵時將筆向下移動。我們將使用以下兩行程式碼

if (F_CTRLINPUT_DOWN_PRESSED)
curY++;

如果在執行這段程式碼時向下鍵被按下,則變數 curY 將增加 1。variable++ 等同於 varible = variable + 1。將以下程式碼放入 query_input() 函式中

if (F_CTRLINPUT_UP_PRESSED)
curY--;
if (F_CTRLINPUT_DOWN_PRESSED)
curY++;
if (F_CTRLINPUT_LEFT_PRESSED)
curX--;
if (F_CTRLINPUT_RIGHT_PRESSED)
curX++;
if (F_CTRLINPUT_B_PRESSED)
curColor = RGB(--cR, cG, cB);
if (F_CTRLINPUT_A_PRESSED)
curColor = RGB(cR, --cG, cB);
if (F_CTRLINPUT_L_PRESSED)
curColor = RGB(cR, cG, --cB);
if (F_CTRLINPUT_R_PRESSED)
{
cR = 0xFF;
cG = 0xFF;
cB = 0xFF;
curColor = RGB(cR, cG, cB);
}

這段程式碼片段有點長而且不好看,我會在課堂上解釋更多細節,但它基本上做的事情是檢查按鍵上的向上、向下、向左、向右、B、A、L 和 R 鍵。當這些鍵被按下時,它會將變數設定為某些值。

第 7 步 - 製作遊戲迴圈

[編輯 | 編輯原始碼]

我們有一個函式用於從使用者獲取輸入,還有一個函式用於在螢幕上放置內容,現在我們只需要將它們組合起來,製作我們的主要遊戲迴圈。我們將在每次螢幕重新整理時呼叫另一個函式,基本上每秒大約 60 次。每次螢幕重新整理時,我們將檢查輸入按鍵,然後在螢幕上繪製。在 drawPix() 和 query_input() 函式之後,但在 main() 函式之前,您需要建立另一個函式,該函式呼叫這兩個函式。

// Function called every screen refresh
void vbl_func()
{
query_input();
drawPix(curX,curY, curColor);
}

很簡單,不是嗎?確實是。大部分工作已經在我們建立的其他兩個函式中完成了,所以這裡沒有太多工作要做。我們唯一需要做的就是每 1/60 秒呼叫一次這個函式。這可以透過在 main() 中的變數初始化之後新增以下程式碼語句來完成

//Starts running the vbl_func every screen refresh
ham_StartIntHandler(INT_TYPE_VBL,(void*)&vbl_func);

現在它每 1/60 秒檢查一次按鍵,並將您的筆繪製到螢幕上,您的 Etch-A-Sketch 就完成了!儲存檔案,構建並執行它!您仍然可以新增其他增強功能(例如,防止筆從螢幕邊緣掉落,或新增螢幕上的說明來解釋如何使用遊戲)。您有一個在 Gameboy Advance 系統上執行的互動式,我還要補充說,它非常有趣。

一旦您正確地運行了基本程式,請儲存並備份它,然後嘗試自己對程式進行其他更改,看看您是否可以使程式更加獨特和個性化。也許您可以將筆做得更大或形狀不同,而不是隻是一個點,或者當您按下開始按鈕時讓筆旋轉,或者其他一百種不同的操作。

結尾說明 & 資源

[編輯 | 編輯原始碼]
華夏公益教科書