J2ME游戏引擎程序结构- -
j2me游戏引擎程序结构
2004-11-17
唐良
游戏引擎的结构很多,不过基本上都是在一个游戏主循环内实现。程序里面的主循环包含了程序框架的最主要的结构体。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;
}
}
版权声明:优快云是本Blog托管服务提供商。如本文牵涉版权问题,优快云不承担相关责任,请版权拥有者直接与文章作者联系解决。
发表于 2004年11月17日 10:44 PM
评论
# j2me游戏引擎程序结构 2004-11-19 2:00 PM 属于我地
Ping Back来自: [url]www.donews.net[/url]
# 回复:j2me游戏引擎程序结构 2004-11-19 8:39 PM Tony.ming
呵呵~~唐唐今天看到你的Blog了~~
关于游戏结构
>>同时,在游戏中任何一个内部循环中,也必须加入sleep(30)这个等待,才能让游戏可以切换回来至于为什么这样做,我暂时还不清楚。30ms是我测试过没有问题的数值,可能比30ms还小的值也是没有问题的。
这是因为如果没有让线程暂停一定时间,循环线程将抢占所有系统资源,切换时系统就没有资源给其他线程了。
>>这个办法只能在Nokia的平台上实现,而我只建议在Nokia 40的平台上做,这样不需要线程,道理上来说节约了一些内存,如果不是内存很紧张的机型,那么最好还是使用上一种办法。
我觉得还是不要用下面这种算法,哪怕是在40的机器上面。采取剥夺式循环很容易造成很多问题。要解决这些问题,需要很多技巧,在这个层面上来讲唐唐的智商非常了得,但代码将会缺乏易读性和可移植性了。
# 回复:j2me游戏引擎程序结构 2004-11-20 11:46 AM tangl_99
楼上的是哪位哦?
# 回复:j2me游戏引擎程序结构 2004-11-20 11:22 PM eltonto
不错不错
# 回复:j2me游戏引擎程序结构 2004-11-22 3:47 PM wangtao
那个是小明
# 回复:j2me游戏引擎程序结构 2004-11-24 2:18 PM vlee
这就叫游戏引擎?
# 回复:j2me游戏引擎程序结构 2004-11-25 10:51 AM tangl_99
晕死,没有人说这是引擎啊。
说了是程序结构。
# 回复:j2me游戏引擎程序结构 2004-11-28 9:21 PM 阿泉
我总结了一下GameLoft的游戏循环,是这种方式
public void run() {
while (game_run) {
game_time = System.currentTimeMillis();
Game_Cycle(); /*游戏更新*/
DeviceControl.setLights(0, 100); /*开灯*/
/*辅助信息,桢率测试*/
if (game_second < (game_time / 1000)) {
game_second = game_time / 1000;
game_framePreSec = game_count;
game_count = 1;
} else {
game_count++;
}
/*辅助信息,桢率测试*/
/*阻塞一段时间*/
while (System.currentTimeMillis() - game_time < 60L) {
sleep(1L);
}
}
}
2004-11-17
唐良
游戏引擎的结构很多,不过基本上都是在一个游戏主循环内实现。程序里面的主循环包含了程序框架的最主要的结构体。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;
}
}
版权声明:优快云是本Blog托管服务提供商。如本文牵涉版权问题,优快云不承担相关责任,请版权拥有者直接与文章作者联系解决。
发表于 2004年11月17日 10:44 PM
评论
# j2me游戏引擎程序结构 2004-11-19 2:00 PM 属于我地
Ping Back来自: [url]www.donews.net[/url]
# 回复:j2me游戏引擎程序结构 2004-11-19 8:39 PM Tony.ming
呵呵~~唐唐今天看到你的Blog了~~
关于游戏结构
>>同时,在游戏中任何一个内部循环中,也必须加入sleep(30)这个等待,才能让游戏可以切换回来至于为什么这样做,我暂时还不清楚。30ms是我测试过没有问题的数值,可能比30ms还小的值也是没有问题的。
这是因为如果没有让线程暂停一定时间,循环线程将抢占所有系统资源,切换时系统就没有资源给其他线程了。
>>这个办法只能在Nokia的平台上实现,而我只建议在Nokia 40的平台上做,这样不需要线程,道理上来说节约了一些内存,如果不是内存很紧张的机型,那么最好还是使用上一种办法。
我觉得还是不要用下面这种算法,哪怕是在40的机器上面。采取剥夺式循环很容易造成很多问题。要解决这些问题,需要很多技巧,在这个层面上来讲唐唐的智商非常了得,但代码将会缺乏易读性和可移植性了。
# 回复:j2me游戏引擎程序结构 2004-11-20 11:46 AM tangl_99
楼上的是哪位哦?
# 回复:j2me游戏引擎程序结构 2004-11-20 11:22 PM eltonto
不错不错
# 回复:j2me游戏引擎程序结构 2004-11-22 3:47 PM wangtao
那个是小明
# 回复:j2me游戏引擎程序结构 2004-11-24 2:18 PM vlee
这就叫游戏引擎?
# 回复:j2me游戏引擎程序结构 2004-11-25 10:51 AM tangl_99
晕死,没有人说这是引擎啊。
说了是程序结构。
# 回复:j2me游戏引擎程序结构 2004-11-28 9:21 PM 阿泉
我总结了一下GameLoft的游戏循环,是这种方式
public void run() {
while (game_run) {
game_time = System.currentTimeMillis();
Game_Cycle(); /*游戏更新*/
DeviceControl.setLights(0, 100); /*开灯*/
/*辅助信息,桢率测试*/
if (game_second < (game_time / 1000)) {
game_second = game_time / 1000;
game_framePreSec = game_count;
game_count = 1;
} else {
game_count++;
}
/*辅助信息,桢率测试*/
/*阻塞一段时间*/
while (System.currentTimeMillis() - game_time < 60L) {
sleep(1L);
}
}
}
0
收藏
转载于:https://blog.51cto.com/hagejid/74848