在講述如何構建一個無限循環,來反復不停的往屏幕上繪圖的程序之前,
先說一下什麼是狀態機。
(都是按我自己的理解來的,和實際可能有出入!)
首先需要一台不斷提供能量的機器。
一個while循環就可以做到這一點。
while (true) {
做事。
}
那麼不管這事是什麼,都可以一直做下去。
機器就有了。
那麼狀態是咋回事?
就是你把好多事放到這個機器裡,一會叫做這個,一會叫做那個。
如果增添一套比較成熟的管理方式,那麼就是一個非常完整的狀態機了.
舉個例子:
while (true) {
第一, 畫一個三角。
第二,畫一個方塊。
}
程序先畫三角,再畫方塊,每一次循環中,兩件事同時做。
加個控制變量把他們分開。
state = 第一
while (true) {
if (state == 第一) {
畫三角。
} else if (state == 第二) {
畫方塊。
}
}
(Java裡,用=號來賦值,用==來做比較)
現在程序總是在畫三角,因為每一次循環總是在畫三角。
如果在畫了三角有5分鐘左右,就想讓畫方塊,代碼這樣寫:
state = 第一
while (true) {
if (state == 第一) {
畫三角。
if (畫了五分鐘) {
state = 第二
}
} else if (state == 第二) {
畫方塊。
}
}
這樣,程序會先畫5分鐘三角,再一直畫方塊.
大概清楚了麼?
一個while循環,然後使用"狀態"來控制做不同事,就構成了狀態機。
整個游戲都是一個狀態機。
比如,游戲一開始畫logo
按了5鍵,轉到畫菜單。
再按5,轉到畫場景。
還有所謂的AI,也是一個狀態機的方式,以後再說了。
--------------------------------------
現在先看一下再JBuilder的那個項目中,如果構造這樣一個狀態機,要這麼這麼這麼:
加個方法,
public void run() {
while (true) {
System.out.println("xx");//這句話的意思是在控制台打印xx
//以後可以自在這裡面可以寫自己的事情.
}
}
然後在類名處,寫成這樣一個:
以前是這樣
public class Game extends Canvas implements CommandListener {
現在變成這樣:
public class Game extends Canvas implements Runnable, CommandListener {
多加了一個Runnable接口.
然後在
GameMidlet這一句
Display.getDisplay(this).setCurrent(displayable);
後面添上
new Thread(displayable).start();
就行了.
現在運行一下,然後按模擬器上的Select按鈕。
如果看到控制台不斷有xx打印出來,就是成功了。
-------------------------------------
剛才這幾個步驟的意思是,
通過implements Runnable 把Game這個Canvas變成一個線程。
然後通過
new Thread(displayable).start();
使這個線程運行。
這個線程運行之後,就會自動調用run方法。
而我們在run裡面搞了一個無限的循環,這就構成了一個狀態機了。
等於說,我們的狀態機,是運行在另一個線程之中。
而不會干擾系統的方法調用。
如果你用一個普通的方法構建狀態機,然後調用,類似這樣:
在class Game不實現Runnable接口
只在裡面加一個gogogo()方法:
public void gogogo() {
while (true) {
}
然後在GameMidlet這一句
Display.getDisplay(this).setCurrent(displayable);
後面添上
displayable.gogogo();
這就完蛋了.因為gogogo裡面有個無限循環,系統永遠退不出
startApp()這個方法了。
如果使用線程,就不會產生這種情況。無限循環是在另一個線程獨立運行的。
(Java怎麼實現的,估計還要看點兒線程之類的書了,可以不用搞那麼深入。)
這樣系統該掉其他方法,還會掉其他方法。
先動手做一下,再往下看。
------------------------------------------------
現在可以說說桢的概念了。英文叫做Frame.
可以這樣理解:
while (true) {
開始
如果 (***) 干這干那
否則如果 (yyy) 干那干這
結束
這從 開始,到 結束
的一個過程,也就是一次循環,叫做一桢。
每一桢用的時間,叫做SPF (Second per frame)
倒過來,每秒運行的桢數,叫FPS (Frame per second)
打CS的時候,有的版本可以看到屏幕上畫著 FPS:
後面一個數字,不停的變。
這個東西越高越好,表示游戲速度越快。
怎麼計算FPS:
在開始的時候記錄一下系統時間,在結束的時候又記錄一下系統時間,
兩個時間一減,就知道這一桢用的時間了(SPF)。 1/SPF
就是FPS.
限桢的概念:
有時候一個循環奇快,有時候一個循環奇慢.
打游戲的時候, 你看著畫面時快時慢, 肯定不中.
就要限制一下.
先規定好一個FPS,假如是每秒20桢,那麼一桢用的時間就是50毫秒。
在 結束
的地方,判斷,如果這一桢用的時間小於50毫秒,記錄下還差多少時間到50毫秒,
然後就讓程序睡覺,睡夠這個差值,使這一桢整體使用的時間達到50毫秒。
這樣平均下來游戲的FPS就是20,很穩定。
如果一桢的時間超出了50毫秒,那就沒辦法了。這就是游戲運行慢的原因,這時要想辦法看看是做了什麼事,導致程序運行緩慢。
魔獸肯定采用了比較高級的控制FPS的方法,如果卡,他就使用很低的FPS,不卡了之後,他就用很快的FPS補上。
這樣看起來游戲
在網絡速度不好的情況下,很遲鈍的樣子,然後再網絡速度好了以後,刷刷刷運行的飛快。
神奇的是,他們能計算出桢的速度變化。
都是我的猜測而已了。
大概明白了沒有?沒有就說。
作業來了,試著寫一下計算FPS的代碼,把FPS打印到控制台。
有啥問題問哦。
下次,講一下繪圖的系統方法是怎麼個調用流程。如何繪制圖形到屏幕上。怎麼察看相關的API文檔。
加個方法,
public void run() {
while (true) {
System.out.println("xx");//這句話的意思是在控制台打印xx
//以後可以自在這裡面可以寫自己的事情.
}
}
的意思是在Game.Java裡加。