程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> J2ME手機游戲引擎程序結構簡述

J2ME手機游戲引擎程序結構簡述

編輯:關於JAVA
游戲引擎的結構很多,不過基本上都是在一個游戲主循環內實現。程序裡面的主循環包含了程序框架的最主要的結構體。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的平台上做,這樣不需要線程,道理上來說節約了一些內存,如果不是內存很緊張的機型,那麼最好還是使用上一種辦法。

  游戲的主循環放在MIDlet的class裡面,具體做法如下:

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;
 }

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