冰浪

          哥已不再年輕 - 堅定夢想,畢生追求!
          posts - 85, comments - 90, trackbacks - 0, articles - 3
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          j2me游戲引擎程序結構

          Posted on 2009-04-09 09:15 冰浪 閱讀(129) 評論(0)  編輯  收藏 所屬分類: J2ME

          唐良

                 游戲引擎的結構很多,不過基本上都是在一個游戲主循環內實現。程序里面的主循環包含了程序框架的最主要的結構體。J2me的程序一般都包含兩個class文件,一個是MIDlet,一個是Displayable。一般我都是把游戲的主要代碼放在Displayable這個類里面。這個類是基于事件驅動的程序,有三個主要相應函數void paint(Graphics g),void keyPressed(int keyCode),void keyReleased(int keyCode)

           

          1.         使用Runnable和創建線程的主循環

          一般主體的做法就是讓Displayable這個類實現Runnable這個接口,然后在其構造函數中創建一個線程,啟動其run()函數,run函數里面就包含了游戲的主循環。下面是我在仙劍里面的片斷代碼。

           

          public class GameMIDlet extends MIDlet {

           static GameMIDlet instance;

           Display display;

           GameDisplayable displayable = null;

           

           public GameMIDlet() {

              instance = this;

              display = Display.getDisplay(this);

              displayable = new GameDisplayable();

           }

           

           public void startApp() {

              display.setCurrent(displayable);

           }

           

           public void pauseApp() {

           }

           

           public void destroyApp(boolean unconditional) {

              displayable.running = false;

           }

           

           public static void quitApp() {

              instance.destroyApp(true);

              instance.notifyDestroyed();

              instance = null;

           }

          }

           

          public class GameDisplayable extends FullCanvas implements Runnable {

           /** 主控制線程 */

           Thread MainThread = null;

           /** 游戲時鐘間隔 毫秒為單位 */

           public static long timeinterval = 20;

           public static boolean Isstable = true;

           

           /* 用于游戲時鐘的變量 */

           public static long timeold = 0;

           public static long timenow = 0;

           public long interval = 0;

           public static long frames_per_second = 0;

           int count = 0;

           long second = 0;

           public static boolean running = true;

          public GameDisplayable() {

               // 開始主線程

              Thread MainThread = new Thread(this);

              MainThread.start();

           }

          public void run() {

              while (running) {

                timenow = System.currentTimeMillis();

                interval = timenow - timeold;

           

                if (interval >= timeinterval) {

                  timeold = timenow;

                  Game_Process();

                  if (second != (System.currentTimeMillis() / 1000)) {

                    second = System.currentTimeMillis() / 1000;

                    frames_per_second = count;

                    count = 1;

                  }

                  else

                    count++;

                }

                lib.sleep(30);

              }

           

           }

           

          其中關于控制主循環速度的代碼可以不要,但是lib.sleep(30)必須保留,因為在Nokia 60的手機上,如果去除了sleep(30),那么游戲將無法切換回來。同時,在游戲中任何一個內部循環中,也必須加入sleep(30)這個等待,才能讓游戲可以切換回來,至于為什么這樣做,我暫時還不清楚。30ms是我測試過沒有問題的數值,可能比30ms還小的值也是沒有問題的。

           

          同時,在MOTO的手機上,必須將游戲的主循環放在一個線程中,游戲才能切換回來,不過可以不加上面說的sleep(30)延時。

           

          2.         不使用線程的主循環辦法

          這個辦法只能在Nokia的平臺上實現,而我只建議在Nokia 40的平臺上做,這樣不需要線程,道理上來說節約了一些內存,如果不是內存很緊張的機型,那么最好還是使用上一種辦法。

           

          游戲的主循環放在MIDletclass里面,具體做法如下:

          public class GameMIDlet extends MIDlet {

           GameDisplayable displayable = null;

           

           /** 游戲時鐘間隔 毫秒為單位 */

           public static long timeinterval = 0;

           //用于游戲時鐘的變量

           public static long timeold = 0;

           public static long timenow = 0;

           public long interval = 0;

           public static long frames_per_second=0;

           int count=0;

           long second =0;

           public static boolean running = false;

           static boolean exitApp =false;

           

           public GameMIDlet() {

              displayable = new GameDisplayable();

              running =true;

           }

           

           public void startApp() {

              running =true;

              Display.getDisplay(this).setCurrent(displayable);

              while(running) {

                timenow = System.currentTimeMillis();

                interval = timenow - timeold;

                if (interval >= timeinterval) {

                  timeold = timenow;

                  displayable.Game_Process();

                  if(second != (System.currentTimeMillis() /1000)){

                      second = System.currentTimeMillis()/1000;

                      frames_per_second = count;

                      count = 1;

                    }else

                      count ++;

                }

              }

              if(exitApp) {

                destroyApp(true);

                notifyDestroyed();

              }

           

           }

           

           public void pauseApp() {

              running =false;

           }

           

           public void destroyApp(boolean unconditional) {

              running = false;

           }

           

           public static void quitApp() {

              running =false;

              exitApp =true;

           }

           

          }

          主站蜘蛛池模板: 台北市| 波密县| 韶山市| 江永县| 呼图壁县| 普兰县| 遂昌县| 赤峰市| 额尔古纳市| 衡南县| 永定县| 长春市| 哈巴河县| 米易县| 临朐县| 莫力| 连州市| 湖北省| 繁昌县| 吉木乃县| 天峨县| 高邑县| 寿光市| 汕头市| 大同县| 宜黄县| 罗江县| 怀来县| 花垣县| 郴州市| 莎车县| 台中县| 巴林右旗| 淮南市| 安丘市| 亳州市| 玉山县| 汾西县| 荃湾区| 凤冈县| 巩义市|