第九章 2D遊戲演算法 課前指引 本章中將介紹在遊戲開發過程中,常會運用到一些貼圖技巧,來展現遊戲畫面及動態效果。例如基本貼圖、動畫貼圖、橫向捲軸移動、前景背景移動等,來提高單純2D圖片的變化性。
章節大綱 9-1 2D基本貼圖 9-5 進階動畫顯示技巧 9-2 2D畫面特效 9-6 橫向捲軸移動 9-3 遊戲地圖製作 9-4 遊戲動畫簡介 備註:可依進度點選小節
9-1 2D基本貼圖 2D貼圖的技巧在遊戲製作過程中是非常重要的一環。 不論是遊戲的主畫面選單、戰鬥場景、遊戲環境設定、角色互換、動畫展現等,都可能使用貼圖的技巧,來將美術設計人員精心設計好的圖案,充分呈現在遊戲需要出現的地方。 在2D貼圖過程中,如果還能善加利用某些演算法功能,能使2D貼圖的效果更具多變性,甚至還可以產生動態視覺效果,同時也可以大量降低美術人員的工作量。
9-1 2D基本貼圖 2D座標系統 所謂數學XY座標系統X座標代表的是象限中的橫向座標軸,座標值是向右方遞增。而Y座標代表的是象限中的縱向座標軸。
9-1 2D基本貼圖 像素 電腦螢幕的顯示是由一堆像素(Pixel)所構成,就是螢幕上的點。 一般我們所說的螢幕解析度為1024x768或是畫面解析度為1024x768,指的便是螢幕或畫面可以顯示寬1024個點與高768個點。
9-1 2D基本貼圖 螢幕顯像解析度 螢幕中座標系統的大小,通常可以利用螢幕的顯像解析度來決定,而螢幕的顯像解析度的高或低通常要看顯示卡或螢幕設備是否有支援來決定。 一般而言,經常會用到的螢幕顯像解析度有「320X200」、「640X480」、「800X600」及「1024X768」。 它們是螢幕所能對應的座標點,如「640X480」就是X座標軸上有640個像素點、Y座標軸上有480個像素點的意思。
9-1 2D基本貼圖 貼圖簡介 就是一種將圖片貼在顯示卡記憶體上,再經由顯示卡呈現於螢幕上的過程,您可以使用GDI、Windows API、DirectX或OpenGL等工具來進行遊戲的貼圖動作。
9-1 2D基本貼圖 GDI與貼圖 GDI(Graphics Device Interface)中文可譯為「圖形裝置介面」。 是Windows API中相當重要的一個成員,掌管了所有顯像裝置的視訊顯示及輸出功能,談到遊戲中的貼圖功能,就必須對GDI有所了解。 至於從繪圖觀點來說,所謂裝置內文(Device Context, DC)就是程式可以進行繪圖的地方。 如果要在整個螢幕區上繪圖,那麼Device(裝置)就是螢幕,而Device Context就是螢幕區上的繪圖層。
9-2 2D畫面特效 在前面內容裡面,相信各位對於螢幕繪圖的基本概念與技巧大概有了初步的了解。 透空效果 半透明效果 透空半透明效果
9-2 2D畫面特效 透空效果 當您希望前景圖與背景圖可以完全融合時,就必須將前景圖背後的黑色底框去掉,這項動作就稱為透空處理,或稱為去背。 這時可利用GDI的BitBlt()貼圖函式以及Raster值的運算來將圖片中不必要的部份給去除(又稱去背),使得圖中的主題可以與背景圖完全融合。
9-2 2D畫面特效 遮罩圖 上圖中左邊的圖就是要去背貼到背景上的前景圖,右邊的黑白圖則稱為「遮罩圖」,在去背的過程中會用到它。 接著把要去背的點陣圖與遮罩圖合併成同一張圖,透空的時候再依照需要來進行裁切。 恐龍部分是黑色 要去背的部份必須是黑色 去背部分是白色
9-2 2D畫面特效 貼圖步驟1 將遮罩圖與背景圖做AND(Raster值為SRCAND)運算,貼到目地DC中,如下所示: 000000... AND) 011010... 遮罩圖中黑色圖點的顏色值 背景圖中彩色圖點的顏色值 運算後變成黑色 111111... AND) 101010... 101010... 遮罩圖中白色圖點的顏色值 背景圖中彩色圖點的顏色值 運算後還是原來背景圖的色彩
9-2 2D畫面特效 步驟1結果圖
9-2 2D畫面特效 貼圖步驟2 將前景圖與背景圖做OR(Raster值為SRCPAINT)運算,貼到目DC中,如下所示: 101011... OR) 000000... 前景圖中彩色圖點的顏色值 背景圖中變成黑色的圖點顏色值 運算後變成前景圖的色彩 000000... OR) 101010... 101010... 前景圖中黑色圖點的顏色值 背景圖中彩色圖點的顏色值 運算後還是原來背景圖的色彩
9-2 2D畫面特效 步驟2結果圖 利用BitBlt()貼圖函式以及Raster運算值的設定,很簡單就做出了我所要的透空效果,而這在設計2D遊戲的一些畫面內容時,使用相當頻繁。
9-2 2D畫面特效 半透明效果 半透明在遊戲中通常是用來呈現若隱若現的特殊效果。 要呈現半透明效果,必須將前景圖與背景圖彼此對應像素的顏色依某一比例來進行調配,這一個比例就叫做「不透明度」。 公式如下: 半透明圖色彩 = 前景圖色彩 x 不透明度 + 背景圖色彩 x (1-不透明度)
9-2 2D畫面特效 透空半透明效果 至於透空半透明效果,則必須多使用了一個記憶體DC與點陣圖物件,先在記憶體DC上完成透空,再取出這個DC上的點陣圖內容來進行半透明處理。 例如以下有一張點陣圖將用來製作前景圖的透空:
9-3 遊戲地圖製作 要產生遊戲地圖除了可以直接使用已經繪製好的點陣圖外,對於一些畫面不是說很複雜,且具有重複性質的地圖。 利用地圖拼接的方式,由一小塊一小塊的小地圖組合出更大型的地圖。 遊戲中的場景地圖(Map)是由一定數量的一些圖塊(Tile)所拼接而成的,就像是在鋪設我們自己家中的地板磁磚一樣。 地圖拼接的優點在於節省系統資源,因為一張大型的地圖會佔用比較多的記憶體空間,且載入速度較慢。
9-3 遊戲地圖製作 平面地圖貼圖 這種貼圖方式相當地直覺,就是利用一張張四方形的小圖塊來組成同樣是四方形的大地圖 以上這張地圖它是由4x3張小圖塊所組成,列方向是4張圖塊,行方向是3張圖塊,在這裡使用列與行這樣的字眼,是因為筆者準備使用陣列來定義地圖中出現圖塊的內容。 列 行
9-3 遊戲地圖製作 一維陣列 轉換的公式如下: 列編號 = 索引值 / 每一列的圖塊個數(行數); 行編號 = 索引值 % 每一列的圖塊個數(行數); 3 / 4 = 0(列) 3 % 4 = 3(行) 10 / 4 = 2(列) 10 % 4 = 2(行) 5 / 4 = 1 (列) 5 % 4 = 1(行)
9-3 遊戲地圖製作 斜角地圖貼圖 斜角地圖其實是平面地圖的一種變化,它是將拼接地圖的圖塊內容,由原先的四方形改變成仿彿由45度角俯看四方形時的菱形圖案。 而由這些菱形內容圖案所拼接完成後的地圖,就是一張由45度俯看的斜角地圖了。 1 2 1 2
9-3 遊戲地圖製作 景物貼圖 可以使用一個與地圖陣列相同大小的陣列來定義那個圖塊位置上要出現那些景物。 而接下來因為景物圖大小與圖塊大小並不會相同,因此還要將景物貼圖的座標稍做修正,使得這些景物可以出現在正確位置上。
9-3 遊戲地圖製作 範例: 64x32的斜角圖塊上貼上一張50x60的樹木圖 由圖中各位可以看出,若斜角圖塊的貼圖座標是(x,y),那麼樹木圖的X座標必須向右移動32-25=7個單位,Y座標則必須向上移動60-16=44個單位,則樹木圖的貼圖座標為(x+7,x-44)。 25 44 60 7 16 32 32
9-3 遊戲地圖製作 人物遮掩(1) 可以將它分成兩種情況,一種是人物與人物之間的遮掩,另外一種是人物與地圖中的建築、樹木等陣礙物之間的遮掩。 第一種情況的解決辦法就是通過一個具有位置屬性的基礎圖塊,而此基礎圖塊上又衍生出其它的圖塊,這樣就可以在視覺方向上對人物的位置進行排序了。 從遠到近分別畫出各圖塊與人物,如此一來,便可以實現人物的遮掩了,當然排序演算法的選擇就依照個人的喜好了。
9-3 遊戲地圖製作 人物遮掩(2) 至於第二種情況,每一個圖塊是有高度的,而圖塊高度又是如何來定義的呢? 從下往上依序比較人物與圖塊的高度,如果圖塊的高度大於人物的高度則圖塊就是遮住人物,所以此圖塊要重畫,如果是人物遮住圖塊的話,則圖塊就不須要重畫了。
9-3 遊戲地圖製作 進階斜角地圖貼圖 由於地圖必須重疊拚接,所以要使用貼圖的方式製作斜角地圖時,必須先瞭解前面談到的透空圖作法。 在貼圖時,圖片的背景透明,如此重複貼圖時才不致於使得背景覆蓋了其它的圖片,各位可從下圖中比較出兩者的不同,右方圖就是處理過後的透空圖:
9-4 遊戲動畫簡介 動畫的基本原理,也就是以一種連續貼圖的方式快速播放,再加上人類「視覺暫留」的因素,因而產生動畫呈現效果。 遊戲中展現動畫的方式有兩種: 一種是直接播放影片檔案(如:AVI、MPEG),常用在遊戲的片頭與片尾; 另一種則是遊戲進行時利用連續貼圖的方式,製造動畫的效果。
9-4 遊戲動畫簡介 一維連續貼圖 而動畫播放的基本原理-「視覺暫留」現象,指的就是「眼睛」和「大腦」聯合起來欺騙自己所產生的幻覺。 連續貼圖就是利用這個原理,在相框中一直不斷地更換裡面的相片而已,這些照片會依照動作的順序而排列,就如同播放卡通一樣。
9-4 遊戲動畫簡介 等差級數的公式 假設一個動作圖的長為「W」、寬為「H」,而每一張圖的長與寬都是一樣,這時如果要計算出某一個圖的位置,就可以利用數學中「等差級數」的公式算出。 公式:an=a1+(n-1)*d a1為首項 an為第n項 n為項次 d為等差值
9-4 遊戲動畫簡介 遊戲迴圈 遊戲迴圈是將原先程式中的訊息迴圈加以修改,其中內容判斷目前是否有要處理的訊息,若有則進行處理;否則便依設定的時間間隔來重繪畫面。 由於迴圈的執行速度遠比計時器發出時間訊號來的快,因此使用遊戲迴圈可以更精準的控制程式執行速度並提昇每秒鐘畫面重繪的次數。
9-4 遊戲動畫簡介 迴圈程式碼 1 //遊戲迴圈 2 while( msg.message!=WM_QUIT ) 3 { 1 //遊戲迴圈 2 while( msg.message!=WM_QUIT ) 3 { 4 if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) ) //偵測訊息 5 { 6 TranslateMessage( &msg ); 7 DispatchMessage( &msg ); 8 } 9 else 10 { 11 tNow = GetTickCount(); //取得目前時間 12 if(tNow-tPre >= 40) 13 MyPaint(hdc); 14 } 15 }
9-4 遊戲動畫簡介 二維連續貼圖 這一種排列是將物體的動作串成一張大圖,而大圖中又分成三列,分別是「A」、「B」及「C」三排,看起來像二維行列的排列。 如果只計算A排中的某一個圖素,相信對讀者來說已經不是什麼難事了。 如上節所述,只要使上述所提過的等差級數便可以得知「1」、「2」或「3」的圖素座標了。
9-4 遊戲動畫簡介 透空動畫 「透空動畫」是遊戲中一定會運用到的基本技巧,它結合了圖案的連續顯示以及透空效果來產生背景圖上的動畫效果。 在這個範例中使用了如下的恐龍跑動連續圖,每一張跑動圖片的寬高為95*99。 (95,0) (0,0) (0,99)
9-5 進階動畫顯示技巧 動畫最基本的要求還是在於畫面要流暢度以及真實度。 然而利用貼圖的方式來產生動畫,經常會因為一些小細節沒注意,而使得動畫的效果看起來不太自然。
9-5 進階動畫顯示技巧 貼圖座標修正 動畫製作需要多張連續圖片,如果這些連續圖片規格不一,那麼進行貼圖時就必須還要做貼圖座標修正動作,否則就可能產生動畫晃動、不順暢的情形。
9-5 進階動畫顯示技巧 排序貼圖 「排序貼圖」的問題是源自於物體遠近呈現的一種貼圖概念。 回想之前貼圖的方式,通常會對於距離較遠的物體先進行貼圖動作,然後再進行近距離物體的貼圖動作。 而一旦定出貼圖順序後就無法再改變了,而這樣作法在畫面上物體會彼此遮掩的情況下便不適用。
9-6 橫向捲軸移動 有關2D橫向捲軸或縱向捲軸遊戲中,有時候會以循環移動背景圖的方式,讓玩家在遊戲的過程中,置身在動態的背景環境中。 如大型機台上較為風靡的「越南大戰」系統遊戲。 現在還有一些遊戲結合了橫向捲軸的技術與3D的場景的特效,讓2D的遊戲場景看起來更顯得逼真,或PS平台上的「惡魔城-月下夜想曲」。
9-6 橫向捲軸移動 單一背景捲動 單一背景捲動的方式是利用一張相當大的背景圖,當遊戲進行的時候,隨著畫面中人物的移動,背景的顯示區域便跟著移動。 要製作這樣的背景捲動效果事實上很簡單,我們只要在每次背景畫面更新時,改變要顯示到視窗上的區域就可以。
9-6 橫向捲軸移動 範例:單一背景捲動(一) 當顯示模式為「640X480」,而背景圖是一張「1024X480」的大型圖形,如果將圖放在螢幕中的話,就會在螢幕上看到如下圖所示:
9-6 橫向捲軸移動 範例:單一背景捲動(二) 如果要觀看背景圖上的(X1,Y1)座標,而且畫框長為「W」、寬為「H」的話。 以Direct Draw的貼圖函式為例,語法如下列所示 畫框.BltFast(畫框上的左上角X座標, 畫框上的左上角Y座標,原始圖,Rect(X1,Y1,W,H))
9-6 橫向捲軸移動 單背景循環捲動 循環背景捲動就是不斷地進行背景圖的裁切與接合,也就是將一張圖的前頁貼在自己的後頁上,然後顯示於視窗上所產生的一種背景畫面循環捲動的效果。
9-6 橫向捲軸移動 多背景循環捲軸 多背景循環捲軸的原理其實與前一小節所談的類似。 不過由於不同背景在遠近層次上以及實際視覺移動速度並不會相同。 因此以貼圖方式來製作多背景循環捲軸時,必須要能夠決定不同背景貼圖的先後順序以及捲動的速度。
9-6 橫向捲軸移動 互動地圖捲動 地圖捲動其實比連續背景圖捲動來得容易製作,首先就從基本的橫向地圖捲動開始說明,其中背景圖與顯像窗格如下所示: 只要判斷圖片的哪些區域需貼到顯像窗格之中就可以了,不過必須注意這個地圖是有邊界,而不是像之前的背景圖循環貼圖,所以還得判斷窗格是否已達左右邊界。 可以利用窗格的中心與邊界距離來判斷,程式中只要使用一個變數就可以了。
9-6 橫向捲軸移動 遮罩點的處理 在2D遊戲中,通常出現的狀況是主角或敵人不可能直接通過所謂的障礙物,它們可能要跳起來通過障礙物或者是將障礙物擊破。 這種必須要跳躍的障礙物,可稱為「遮罩點」,這種遮罩點的目的是告訴玩家這個地方不可以直接通過。
本章結束 Q&A討論時間