冰浪

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

          j2me游戲引擎程序結構

          Posted on 2009-04-09 09:15 冰浪 閱讀(133) 評論(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;

           }

           

          }

          主站蜘蛛池模板: 陆川县| 介休市| 江山市| 贺州市| 兰考县| 新疆| 云安县| 西林县| 宁陕县| 东城区| 林西县| 长岛县| 云安县| 保康县| 宾阳县| 马山县| 邹平县| 深圳市| 扶绥县| 东至县| 绥棱县| 九台市| 宁蒗| 蒙山县| 新丰县| 四子王旗| 塘沽区| 城固县| 武义县| 江孜县| 宝山区| 宜川县| 浑源县| 钦州市| 韩城市| 彰化市| 疏勒县| 闻喜县| 包头市| 右玉县| 东城区|