一般來說,最常用的 游戲 結構是這樣的:游戲開始后即進入一個循環,每次循環做三件事情: 1. 獲取玩家的輸入。 2. 更新游戲狀態。 3. 刷新屏幕。 理論" name="description" />

簡單的游戲結構

發表于:2007-04-28來源:作者:點擊數: 標簽:結構簡單游戲
MI LY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"> 一般來說,最常用的 游戲 結構是這樣的:游戲開始后即進入一個循環,每次循環做三件事情: 1. 獲取玩家的輸入。 2. 更新游戲狀態。 3. 刷新屏幕。 理論

MILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一般來說,最常用的游戲結構是這樣的:游戲開始后即進入一個循環,每次循環做三件事情:

1.       獲取玩家的輸入。

2.       更新游戲狀態。

3.       刷新屏幕。

理論上說,刷屏的頻率在24Hz以上,人的眼睛看到的就是動畫了。

 

這個例子游戲的主循環是這樣的:

public void run() {

Graphics g = getGraphics();

Thread currentThread = Thread.currentThread();

try {

while (currentThread == gameThread) {

long startTime = System.currentTimeMillis();

if (isShown()) {

if (isPlay) {

tick();

}

render(g);

}

long timeTake = System.currentTimeMillis() - startTime;

if (timeTake < MILLIS_PER_TICK) {

synchronized (this) {

wait(MILLIS_PER_TICK - timeTake);

}

} else {

currentThread.yield();

}

}

} catch (InterruptedException ex) {

// won't be thrown

}

}

 

說明:

1.       兩個thread。currentThread當然就是當前執行的這個線程,那么gameThread當然也就是運行這個run方法的線程(不然while一開始就不成立,游戲就沒法運行了^_^)。這里它們的作用是控制游戲的循環,當一開始運行時,currentThread==gameThread,循環下去;當游戲需要退出時,將gameThread(類成員)設置為null,那么循環結束,游戲就退出了。強制結束某個線程是很不好的方法,sun的標準庫里早就deprecate這個方法了。

2.       tick方法:處理玩家的輸入以及游戲狀態的變更。

3.       render方法:顧名思義,繪圖。這里MIDP2.0相對于1.0有很大的改進,后面說。

4.       幾個long型的time的用處。代碼看起來很直觀,就是考慮到tickrender方法執行時間可能不固定,用time加以計算,得到需要sleep的時間。這樣的結果就是游戲畫面以一個固定的延時刷新,FixedDelay。當然,還有另外一種控制方式,即固定頻率的刷新,FixedRate。

a)         FixedDelay:固定延時的好處是畫面看起來總是很流暢,而且一定不會出現跳幀的現象。

b)        FixedRate:在一種情況下和FixedDelay有差別,即tickrender方法消耗的時間比預設的時間(MILLIS_PER_TICK)還長。FixedDelay這時不再wait,直接繪制下一幅圖;而FixedRate就不能繪了,否則頻率不固定。它的選擇是不繪這一幅,而是直接進入下一個循環,更新游戲狀態,綜合計算時間,繪下一幅圖——于是產生了跳幀。

CS或星際這樣的游戲,跳幀是必須的,因為聯機游戲必須保證各方的圖像顯示的同步,不固定刷新頻率會導致錯誤。而像仙劍之類的單機游戲倒是可以考慮用固定延時,因為不跳幀不會產生什么錯誤,同時也可以增加游戲畫面的流暢性。

      

       繪圖:

       private void render(Graphics g) {

        // Set Background color to beige

        g.setColor(0xF8DDBE);

        g.fillRect(0, 0, width, height);

        g.setColor(0x0000ff);

        // LayerManager Paint Graphics

        layerManager.paint(g, 0, 0);

        flushGraphics();

}

MIDP1.0里面,Canvas的繪圖只能寫在paint(Graphics g)方法里,因為一來g參數在此方法結束后就沒有意義了,保留它的副本沒有用處;二來此方法由平臺調用,而不是由Canvas這個線程調用。因此在MIDP里繪圖總是一件很痛苦的事情,特別是需要保證Canvas線程與調用paint的那個線程同步(J2meSpecification說的是,可以保證你repaint了以后,paint方法在之后的某個時刻被調用,但不能保證馬上就被調用,因為paint是個比較耗時的方法,它無法確定其他的paint是否及時完成了)。

MIDP2.0里,有所改進了。首先是你可以通過GameCanvas的一個方法getGraphics來獲取那個g,然后這個g就永不失效了(當然是在這個GameCanvas的生命周期內)。當然,這個g1.0里的還是有所區別。這個g實際上是畫在一塊緩沖“畫布”上,即內存里。完全畫好以后,再用flushGraphics刷到屏幕上。緩沖的好處是可以讓屏幕在畫時不顯得閃爍,很有用的東西。flushGraphics還有另外一個作用,就是強制輸出,以達到顯示的那個線程與游戲控制線程的同步(這也是為什么做時間協調時,要把顯示方法所消耗的時間也計算進來)。

Tick…………暫時先不討論。



原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97