2004-11-17
Tang Liang
The game engine has a lot of structure, but it is basically implemented in a game main loop. The primary loop in the program contains the most important structure of the program framework. J2ME procedures generally contain two class files, one is a MIDlet, one is displayable. Generally, I put the main code of the game in the Displayable this class. This class is an event-driven program with three major corresponding functions void Paint (GRAPHICS G), Void KeyPressed (int keycode).
1. Use runnable and create threads of the primary loop
The general subject is to enable DisplayABLE to implement the runnable interface, then create a thread in its constructor, start its Run () function, and the RUN function contains the main loop of the game. Below is the piece code I am in the fairy sword.
Public Class Gamemidlet Extends Midlet {
Static gamemidlet.
Display display;
Gamedisplayable Displayable = null DISPLAY
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 imports runnable {
/ ** Main control thread * /
Thread mainthread = NULL;
/ ** Game clock interval milliseconds * /
Public static long timeInterval = 20;
Public static boolean isstable = true;
/ * Variables for game clock * /
Public static long timeold = 0;
Public static long timenuw = 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 () {
// Start the main thread
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.SLEP (30);
}
}
The code for controlling the main loop speed is not, but lib.sleep (30) must be retained because on the mobile phone of Nokia 60, if Sleep (30) is removed, the game will not switch back. At the same time, in any internal cycle in the game, you must also join Sleep (30) to wait for the game to switch back, as for why do this, I am still unclear. 30ms is the value I have tested without problems, and there may be no problem than the value of 30ms.
At the same time, on the Moto's mobile phone, the main loop of the game must be placed in a thread, and the game can switch back, but can not add Sleep (30) delayed.
2. Main loop approach to the thread
This approach can only be implemented on the NOKIA platform, and I only recommend doing on the platform of Nokia 40, so you don't need threads, in mind, save some memory, if you are not a tight model, then it is best to use Previous method.
The game's main loop is placed in the MIDlet's class, and the specific practice is as follows:
Public Class Gamemidlet Extends Midlet {
Gamedisplayable Displayable = null DISPLAY
/ ** Game clock interval milliseconds * /
Public static long timeInterval = 0;
// Variable for the game clock
Public static long timeold = 0;
Public static long timenuw = 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;
}
}