程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> j2me游戲教程(二)——什麼是狀態機,怎樣在上次的代碼中建立狀態機,什麼是FPS?

j2me游戲教程(二)——什麼是狀態機,怎樣在上次的代碼中建立狀態機,什麼是FPS?

編輯:J2ME

在講述如何構建一個無限循環,來反復不停的往屏幕上繪圖的程序之前,
先說一下什麼是狀態機。
(都是按我自己的理解來的,和實際可能有出入!)
首先需要一台不斷提供能量的機器。
一個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裡加。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved