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

j2me游戲引擎程序結構

編輯: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的平台上做,這樣不需要線程,道理上來說節約了一些內存,如果不是內存很緊張的機型,那麼最好還是使用上一種辦法。



游戲的主循環放在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