?? gametimerthread.java
字號:
package javagapi;import javax.microedition.midlet.MIDlet;import javax.microedition.lcdui.Display;/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! For speed, this is not threadsafe. However if the following assumptions hold, it should work. Assumptions made: read or write from byte or boolean is atomic operation. The user will not press keys at a rate that is faster than this thread can handle them. The keys presses are stored in an 8 slot circular buffer in GameShell. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*//** (C) 2002 Sony Ericsson Mobile Communications AB. All rights reserved. * Sends GATimerEvents periodically to a game. * @author LD/SEM/GUN/MI Stefan Olsson, ecssnon * @version 1.0 */class GameTimerThread extends Thread{ /** Used by GASetTimer and GAKillTimer to communicate the new period. * A killed timer has the period Long.MAX_VALUE. */ public long[] period = { Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE }; /** Used by GASetTimer and GAKillTimer to communicate to the thread the * fact that the period has been updated. */ public boolean[] periodUpdated = { false, false, false}; GameShell game; MIDlet midlet; /** GACheckForRefresh calls repaint() and * sets this to false. The ensuing call to paint() sets it to true. * While it is false, the game loop will only steal clock cycles, * waiting for it to become true, so that the canvas will not repaint * while the game is handling an event. */ public boolean paintNotScheduled; byte keysUpdated = 0; /** Allocates a new GameTimerThread object. The purpose of this thread * is to send all events except GAMenuSettingsEvent and GAStartEvent to * the game. * <p> * As soon as game.gameMain returns false a GATerminateEvent is sent and * the thread exits after the game has handled this event. * * @param g The game that will receive events. */ public GameTimerThread(GameShell g){ game = g; } public void setMIDlet(MIDlet m) { midlet = m; } /** Creates and dispatches events to the game. Once the game has begun, * this thread will actually excecute the game code. There is only one * GameTimerThread per game. * <p> * Please note that this method does a busy wait, i.e. it uses clock cycles * even when waiting to dispatch the next timer event. */ public void run() { ///*timer*/long t0; ///*timer*/long dt=0; boolean notQuit = true; GAEvent curEvent = new GAEvent(); int keyPos = -1; long newT; long[] oldT = new long[3]; oldT[0] = System.currentTimeMillis(); oldT[1] = oldT[0]; oldT[2] = oldT[0]; int i = 0; long[] oldPeriod = new long[3]; try{ while(notQuit) { //System.out.println("Loop da loop! paintNotScheduled = "+paintNotScheduled); newT = System.currentTimeMillis(); if(paintNotScheduled) { //System.out.println("keysUpdated = "+keysUpdated); if(keysUpdated>0) { keysUpdated--; keyPos++; if(keyPos == 8) keyPos = 0; curEvent.type = GameShell.GAKeyboardEvent; curEvent.press = game.keyPressedArray[keyPos]; curEvent.key = game.keyArray[keyPos]; oldPeriod[0]=period[0]; oldPeriod[1]=period[1]; oldPeriod[2]=period[2]; //System.out.println("::::::Sending key event"); //System.out.println("MAIN THREAD SENDING KEY EVENT"); if(!game.gameMain(curEvent)) notQuit = false; if(periodUpdated[0]) { if(oldPeriod[1]==Long.MAX_VALUE) oldT[1]=newT; periodUpdated[1]=false; } if(periodUpdated[1]) { if(oldPeriod[1]==Long.MAX_VALUE) oldT[1]=newT; periodUpdated[1]=false; } if(periodUpdated[2]) { if(oldPeriod[2]==Long.MAX_VALUE) oldT[2]=newT; periodUpdated[2]=false; } } else if(newT-oldT[0]>period[0]) { //System.out.println("Timer thread 0 is late by "+(newT-oldT[0]-period[0])+" millis"); oldT[0] = newT; curEvent.type = GameShell.GATimerEvent; curEvent.timerId = 0; //System.out.println("::::::Sending timer 0 event"); oldPeriod[1]=period[1]; oldPeriod[2]=period[2]; ///*timer*/t0 = System.currentTimeMillis(); if(!game.gameMain(curEvent)) notQuit = false; ///*timer*/dt = System.currentTimeMillis()-t0; //System.out.println("The call to game.gameMain took "+dt+" millis to execute"); if(periodUpdated[1]) { if(oldPeriod[1]==Long.MAX_VALUE) oldT[1]=newT; periodUpdated[1]=false; } if(periodUpdated[2]) { if(oldPeriod[2]==Long.MAX_VALUE) oldT[2]=newT; periodUpdated[2]=false; } } else if(newT-oldT[1]>period[1]) { //System.out.println("Timer thread 1 is late by "+(newT-oldT[1]-period[1])+" millis"); oldT[1] = newT; curEvent.type = GameShell.GATimerEvent; curEvent.timerId = 1; //System.out.println("::::::Sending timer 1 event"); oldPeriod[0]=period[0]; oldPeriod[2]=period[2]; if(!game.gameMain(curEvent)) notQuit = false; if(periodUpdated[0]) { if(oldPeriod[0]==Long.MAX_VALUE) oldT[0]=newT; periodUpdated[0]=false; } if(periodUpdated[2]) { if(oldPeriod[2]==Long.MAX_VALUE) oldT[2]=newT; periodUpdated[2]=false; } } else if(newT-oldT[2]>period[2]) { //System.out.println("Timer thread 2 is late by "+(newT-oldT[2]-period[2])+" millis"); oldT[2] = newT; curEvent.type = GameShell.GATimerEvent; curEvent.timerId = 2; //System.out.println("::::::Sending timer 2 event"); oldPeriod[0]=period[0]; oldPeriod[1]=period[1]; if(!game.gameMain(curEvent)) notQuit = false; if(periodUpdated[0]) { if(oldPeriod[0]==Long.MAX_VALUE) oldT[0]=newT; periodUpdated[0]=false; } if(periodUpdated[1]) { if(oldPeriod[1]==Long.MAX_VALUE) oldT[1]=newT; periodUpdated[1]=false; } } } } } catch( Exception ex ) { ex.printStackTrace(); } //System.out.println("MAIN THREAD SENDING TERMINATE EVENT"); curEvent.type = GameShell.GATerminateEvent; try{ game.gameMain(curEvent); } catch( Exception ex ) { ex.printStackTrace(); } Display display = Display.getDisplay(midlet); MenuReturner mr = new MenuReturner(midlet); //System.out.println("MAIN THREAD SERIALLY INVOKING MENURETURNER"); display.callSerially(mr); }}class MenuReturner implements Runnable { MIDlet midlet; public MenuReturner(MIDlet m) { midlet = m; } public void run() { if(midlet instanceof GameMIDlet) ((GameMIDlet)midlet).returnToMenu(); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -