2010-06-21 61 views
1

好的。 我在本質上試圖對NES硬件做出我自己的解釋,所以我可以製作一個理想的遊戲,類似於NES遊戲的樣子。我目前堅持如何調整如何將視頻內存拖放到顯存(後臺緩衝區)。在遊戲中渲染2D地圖 - 裁剪和滾動

後備緩衝

的NES對的nametable,或後備緩衝限制。對於我的例子,後緩衝器是256x240像素大,或一個屏幕的大小。如果我把它畫到電視上,它會完美地填滿屏幕。現在,如果我將它繪製到屏幕上,偏移量爲X = 5,則整個圖像將被移動並將圍繞屏幕。

例如.....

ORIGINAL, NO OFFSET:      DRAWN WITH OFFSET OF X=5: 
ABCDEFGHIJK        GHIJKABCDEF 

DRAWN WITH OFFSET OF X=-5: 
FGHIJKABCDE 

屏幕被分成的每個正方形8×8像素,共32x30行和列。 (256x240像素)。偏移量以像素表示 - 不是列;所以在理論上,我可以將屏幕偏移5個像素,每列將向右移動5個像素。

級設計

我的階段是由屏幕,包含在16x15的行和列,每個由16×16像素所表示的數據。這是爲了模擬有多少NES遊戲存儲了關卡數據 - 每個瓦片擁有關於每個8x8塊應該在哪裏的信息。

例如爲:

AA 
BC  with A,B,C,D representing what 8x8 graphic should go where 

關卡設計是由這是很好的體現,每個數字是不同的屏幕和 - 沒啥意思,空。

----- 
-123- 
---4- 
--54- 
----- 

字符的位置 這很容易。我已經知道如何根據它們的絕對位置來確定我的角色所在的表,行和列。我也可以確定屏幕內的相對位置。

有了這個信息,我很容易找出哪些列於字符的左側和右側,如果有的話(如果字符是在屏幕1的左側,thered是左沒有更多的級)

這就是問題鄧駿鈞 我該如何在屏幕上繪製自己的關卡,讓他們從一個滾動到另一個。 一次畫一個全屏幕會比較容易,而當角色到達邊緣時只會翻到另一個屏幕。

但是,我在概念上存在的問題是我需要將電平數據「流」到屏幕上。那可以說,角色向右移動了24個像素。 BG也需要移動。

所以,我需要調整後緩衝滾動24個像素。但是,僅滾動屏幕就會導致屏幕旋轉,從而影響關卡的舊部分。所以,在滾動時,我需要確保將新的關卡繪製到後臺緩衝區。但在我能做到這一點之前,我需要弄清楚哪些瓷磚需要首先繪製。如果這個人向左走24像素,我需要重新繪製瓦片到後緩衝區,並相應地改變偏移量。

另外我們不要忘記,如果角色向右移動並且沒有更多等級數據要繪製,則不應該有偏移,而是角色靠近屏幕一側(而不是居中在屏幕通過X軸)。

基本上,我只是有很多不同數量和停留在我的腦海裏,現在值的 - 試圖總結我的頭周圍的許多概念和他們造成我的大腦變成咕。任何人對我如何處理這個問題都有任何看法?

編輯:使用VB.Net。 C#是適用以及(在兩個予程序)

回答

3

的方式NES做的是與4個表,每個256x240。當你從屏幕上滾動一個時,相鄰的一個會滾動。要獲得大於512x480的「世界」,您需要在屏幕外的位置更新名稱表。

通常,盒將具有巨大的表中的所有級別的數據的ROM,以及將跟蹤用1或2的RAM變量的總體位置。然後,當遊戲滾動時,它將更新RAM變量,使用它們查找級別數據表,並將新級別數據複製到名稱表中不在屏幕上的部分。

所以實際上你的背部緩衝區應該是512x480,而你只顯示它的256x240部分。

你看着拆卸任何NES遊戲擁有大量滾動的世界?我認爲銀河戰士的部分拆卸就在某處...

...是啊,發現了一些文檔在romhacking.net

Metroid disassembly;不是很好的評論,但有一點點努力,找出它應該不會太難。

Another disassembly被評價更好。

編輯:在上面貼了第二拆解,看看在MetroidGameEnginePage.txt在「SetupRoom」程序和「DrawRoom」家常便飯;標籤LEB4D上的例程也顯示了在一種情況下如何更新名稱表。還請看「GetNameTable」例程上面的大量註釋。通常,在整個文檔中對「名稱表」進行文本搜索將爲您帶來更多。

EDIT編輯:另外在romhacking.net; memory map for SMB可能會有用。

+1

作爲一個romhacker,我贊同這個答案。 – Kawa 2010-06-23 18:53:59

0

我會從一個數據庫,其存儲什麼列和行每個圖象是相對於水平設置的圖像控制的網格,並加載水平。一旦表示遊戲角色的圖像變得足夠遠(您將不得不將其位置存儲在某些模塊級別變量中),您將加載下一列圖像(同時將所有其他圖像移動到離開並移除第一列)。