遊戲的捲軸效果主要有兩種形式,一種是將遊戲分為若干個情境的頁面捲軸,比如FC上的洛克人,當人物走到邊緣時,就會切換整個情境;一種就是魂鬥羅式的那種均勻平鋪的捲軸,這種捲動更為平滑。因為我要用在2.5D顯示引擎中,只能選擇第二種捲軸技術——均勻tile捲軸。
1. 捲軸要捲動哪些東西
首先要清楚捲動的是什麼東西,比如下面的一個KOK1的:
這是一個典型的2.5D遊戲介面,這個介面上的所有元素全都是由位元影像所組成的,但是不難分析出實際要捲動的只有地面的位元影像。因為傳送門和柱子、樹等等都是可以遮擋住人的,即渲染順序是:
(1) 根據全局座標捲動的地面貼圖
(2) 玩家單位、建築、環境元素單位以從上至下的順序渲染,這樣就會產生2.5D效果,即近景遮擋住遠景。
2. 均勻平鋪顯示引擎的設計與實現
由的地板不難看出,其實這些地面是由一小塊一小塊拼接而成的,這樣可以使位元影像得以重用,就像紅警95的地圖編輯器一樣,一個地形可以在地圖中反覆出現。所以我們實際要有一個位元影像檔案來存放這些一塊一塊的地板,比如我隨便畫了這個(第一個是我自己用畫筆畫的,後面兩個是截的,效果都一般,可見優秀美工的重要性),有三塊86*40的地板:
然後在程式中,我們需要建立一個顯示表面的數組來分別存放這三個地板。
LPDIRECTDRAWSURFACE7 lpddsFloor[3];
接著,定義一個int數組來存放地圖中地形的索引,比如我打算要建立一個3×3塊地板的地圖,則:
int map[3*3] = { 0, 0, 0, 1, 1, 1, 2, 2, 2 };
這樣這個地圖等於是第一行都是第0塊地板,第二行都是第1塊地板,第三行都是第2塊地板。
現在就要建立世界表面,把世界載入到一個單獨的大表面上:
lpddsMap = CreateSurface(MAP_WIDTH*TILE_WIDTH, MAP_HEIGHT*TILE_HEIGHT, 0);</p><p>for (int y = 0; y < MAP_HEIGHT; ++y)<br />{<br />for (int x = 0; x < MAP_WIDTH; ++x)<br />{<br />RECT dest_rect = { x * TILE_WIDTH, y * TILE_HEIGHT, (x+1) * TILE_WIDTH, (y+1) * TILE_HEIGHT };<br />lpddsMap->Blt(&dest_rect, lpddsFloor[map[x + MAP_WIDTH * y]], NULL, DDBLT_WAIT, NULL);<br />}<br />}
現在所有的準備工作都做好了,就要在顯示器顯示的每一幀,根據視窗在世界中的座標來Blt相關的地區到離屏表面,並且根據玩家的輸入來調整視窗在世界中的座標:
if (KEY_DOWN(VK_LEFT))<br />screen_x = screen_x > 5 ? screen_x - 5 : screen_x;</p><p>if (KEY_DOWN(VK_UP))<br />screen_y = screen_y > 5 ? screen_y - 5 : screen_y;</p><p>if (KEY_DOWN(VK_RIGHT))<br />screen_x = screen_x < MAP_WIDTH*TILE_WIDTH - SCREEN_WIDTH ? screen_x + 5 : screen_x;</p><p>if (KEY_DOWN(VK_DOWN))<br />screen_y = screen_y < MAP_HEIGHT*TILE_HEIGHT - SCREEN_HEIGHT ? screen_y + 5 : screen_y;</p><p>RECT rect = { screen_x, screen_y, screen_x + SCREEN_WIDTH, screen_y + SCREEN_HEIGHT};<br />lpddsoffscreen->Blt(NULL, lpddsMap, &rect, DDBLT_WAIT, NULL);
3. 放上一個,是完成的效果。