J2ME專業手機遊戲開發基礎(1)

2021-06-16 02:55:12 字數 4676 閱讀 5218

遊戲的基本結構遊戲是什麼呢?在遊戲中,往往是顯示各種各樣的畫面,玩家可以做一些設定好的控制,畫面根據玩家的控制有所變化。從這兒可以看出,遊戲至少需要三個功能-顯示畫面,接受玩家輸入和對輸入產生反饋。這就是常說的渲染,輸入輸出和邏輯三個模組。將這三個模組組合在一起有很多方法。比如事件驅動-畫面保持不變直到接受到輸入事件,程式進行邏輯運算然後改變畫面。而遊戲往往不是這樣,遊戲是時間驅動的。也就是說無論有沒有輸入,遊戲都在不停的迴圈-檢查是否有輸入,執行邏輯,渲染畫面。這裡我多說一句,其實什麼樣的結構並不能區別乙個程式是不是遊戲,其實只要可以互動娛樂的程式就可以稱為遊戲,也不一定要用時間驅動,但採用時間驅動是專業遊戲的普遍做法,也是很容易接受的方法-因為從一定程度上講,遊戲很像電影,隨著時間流逝畫面在改變。

0 初始化遊戲

1 是否結束遊戲(yes:轉到6)

2 蒐集玩家輸入資訊

3 執行遊戲邏輯

4 更新下一幀,顯示下一幀

5 回到1

6 清理,結束遊戲

這是乙個最基本的結構,特別對於比較簡單的j2me遊戲來說,這個結構更加有代表性。下面我們將分別講述專業手機遊戲如何實現這個結構中的各個內容。

遊戲迴圈的實現

我們需要乙個進入後就一直迴圈下去直到遊戲結束的結構。執行緒正好可以實現。最通常的做法是讓canvas實現runnable介面。於是我們就可以實現run方法。下面是乙個run方法簡化版:

public void run()

catch (interruptedexception ex) {}

}endmidlet() ;

}看到我們的

while

迴圈了嗎?除非在程式邏輯中設定

exitmidlet

為true

-那是當玩家選擇了退出遊戲,我們的遊戲將一直執行下去。在

while

迴圈之前,

gameinit

方法的作用是進行遊戲初始化-比如初始化變數值,載入全域性資料,生成全域性物件等。在

while

迴圈中,我們先是呼叫了

acquirekey

方法,這個方法將鍵盤輸入資訊進行緩衝以便邏輯中判斷按鍵狀態,下面講會講到鍵盤緩衝。

gameloop

是我們遊戲的主體,每幀中的邏輯運算,圖形處理都在這裡面進行。然後是

repaint

和servicerepaints

,重新整理螢幕-新的一幀呈現在螢幕上。最後當跳出

while

之後,我們執行

endmidlet

結束這個

midlet

。endmidlet

的內容只是呼叫了

和notifydestroyed

方法。好了整個遊戲迴圈就是這樣了,下面講分別講述鍵盤緩衝和

gameloop

如何組織。不過再這之前先讓我解釋下

lock fps

。fps

就是frame per second

。為了防止遊戲在不同的機器上速度變化太大,我們設定乙個最大的

fps值,或者說設定乙個每幀至少要花費的時間(這裡的

min_delay

)。比如我們設定

min_delay=50

,那麼max fps = 1000/50 = 20 幀/

秒。鎖定

fps有多種方法,這裡的方法是判斷如果一幀所有的時間還沒達到最大時間,那麼就讓執行緒

sleep

一會兒。順便在說一下

fps的計算,顧名思義用

1000

除以一幀所有時間即可,不過要注意的是,一般計算的

fps是平均

fps,所以

fps=

累計幀數

*1000/

累計花費時間。

鍵盤緩衝

蒐集玩家輸入資訊是乙個很重要的內容,我們知道

j2me

中可以在

keypressed

和keyreleased

事件中處理按鍵內容,但這樣勢必將邏輯**分散與

gameloop

和keypressed

中。如果你說將所有邏輯**放在

keypressed

中,那可不行,因為

keypressed

只有在按鍵的時候才產生,而即使沒有按鍵遊戲也有很多邏輯運算要做。所以專業遊戲開發中採用鍵盤緩衝將按鍵資訊存起來,然後在

gameloop

中就可以判斷這一幀按鍵的狀態,利用按鍵緩衝,除了可以判斷乙個鍵是否按下鬆開,還可以判斷乙個鍵是否一直被按住了,甚至可以判斷組合鍵。不過在這裡,我只介紹一種最簡單的按鍵緩衝。由於篇幅所限,只講述原理並不給出具體**。

首先我們需要乙個資料結構儲存按鍵資訊。你可以為每個鍵用乙個

bool

值儲存它的狀態,不過專業一點的做法是用乙個位表示乙個鍵的狀態,乙個

int有

32個位,足夠表示大多數手機的所有按鍵了。因為我們要判斷鍵是否按下或鬆開,為了方便,我們再用

2個整數記錄這兩種狀態。所以現在我們一共有三個

int了

: static int key , pressedkey, releasedkey ;

ok! 有了儲存的地方,我們還需要一些常量表示每個位,我們設定

key中某個位為

0表示某鍵沒有按下,為

1表示按下。如果用第

1位表示

0鍵,第

2位表示

1鍵,那麼可以這樣設定常量:

final static int gkey_0=1<<0, gkey_1=1<<1 ;

明白了嗎?這些常量是用來指定某個位用的,比如

gkey_1

其實就是第2為

1其它位均為

0的乙個整數。如果還不明白,先看下面的。

keypressed

和keyreleased

裡將分別將按下的鍵和鬆開的鍵進行記錄。

public void keypressed(int keycode)

public void keyreleased(int keycode) 在

keypressed

裡面,我們先將

keycode

轉換成我們的按鍵常量,就是上面的

gkey_0

等。因為

keycode

可不是像我們的常量那樣可以用某個位表示的,而且不同手機的

keycode

是有可能不一樣的,所以我們必須用乙個函式

getkeyvalue

進行轉化。得到常量後

key|=value

的作用是將

key裡面常量所代表的位置

1,現在你應該明白常量的作用了吧!

pressedkey|=value

同理。不過

keyreleased

有些不同,由於

releasedkey

只記錄這一幀裡哪些鍵「被鬆開」了,所以仍然用或運算。但

key是記錄整個按鍵的狀態,所以用異或。

接下來就是如何判斷按鍵狀態了:

private static void acquirekey()

public static boolean keyhold(int gamekey)

public static boolean keydown(int gamekey)

public static boolean keyup(int gamekey)

還記得acquirekey

吧,我們在

while

迴圈中首先要呼叫它,其作用就是記錄下這一幀的按鍵狀態,所有我們用了三個新

int變數記錄他們,分別是

framekey

,framepressedkey

和framereleasedkey

。acquirekey

所做的就是將按鍵狀態記錄在這

3個變數中,其實

framepressedkey

和framereleasedkey

不是必須的,只是這樣看上去比較清楚。記錄完後我們將

pressedkey

和releasedkey

清空,以便下次有鍵按下或鬆開時記錄新的資訊。關鍵的三個函式登場了,

keydown

判斷某個鍵是否在這一幀裡被按下,引數

gamekey

是我們定義的按鍵常量中的某個值。如果對位運算還算明白的話,很容易看懂這

3個函式。唯一要說明的就是

keyhold

和keydown

的區別,

keyhold

表示某個鍵一直被按著,也就是至少從前一幀開始它就被按下了,而不是在這一幀裡被按下的。現在你應該明白我們為什麼要清空

pressedkey

和releasedkey了。

說到這裡也差不多了,有了這個按鍵緩衝我們就可以在

gameloop

中呼叫keydown

等方法判斷按鍵的狀態了。不過我還是要說一句,這只是最簡單的按鍵緩衝,只能緩衝一次按鍵,如果乙個鍵被多次按下就不行啦。更專業的內容需要你在實際工作中探索。

J2ME開發之手機鍵值適配

本來不想寫j2me開發的時候要根據不同手機平台適配各種鍵值這個問題,覺得沒撒意思,也沒什麼技術含量,但是今天看到了乙個讓我很無語的東西,所以我決定要寫出來。稍候再說這個讓我不爽的東西,先不要影響我們分享技術的心情。now begin 很多人都說,要適配所有手機的鍵值是不可能的。因為,已是j2me中沒...

j2me 遊戲開發 背景篇 TiledLayer

在 中背景是個有意思的東東,先前沒做過應用開發,發覺這個背景開發 有點和其他的應用開發一樣,幾個小圖合成乙個圖,遊戲用的時候再去分開,重複組成背景。其主要常用的函式有 建構函式 tiledlayer int column,int row,image img,int width,int height ...

J2ME 開發工具

j2me wireless toolkit 手機廠商sdk wtk 的全稱是sun j2me wireless toolkit sun的無線開發工具包。這一工具包的設計目的是為了幫助開發人員簡化j2me的開發過程。該工具箱包含了完整的生成工具 實用程式以及裝置 器。a.wtk 2.2 目前各大手機廠...