package framework.gameMain;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import framework.RWT.RWTFrame3D;
import framework.schedule.ScheduleManager;
/**
* ゲームの基本クラス
* @author 新田直也
*
*/
public abstract class AbstractGame implements Runnable {
protected RWTFrame3D mainFrame;
private ScheduledExecutorService t;
private long minimumFrameTime = 5;
private long maximumFrameTime = 15;
private boolean bWaitForRender = true;
private long prevTime = 0L;
public abstract RWTFrame3D createFrame3D();
protected abstract IGameState getCurrentGameState();
public AbstractGame() {
mainFrame = createFrame3D();
}
public void start() {
if (getCurrentGameState() != null) {
activateState(getCurrentGameState());
}
}
public void stop() {
if (getCurrentGameState() != null) {
deactivateState(getCurrentGameState());
}
}
public void setFramePolicy(long minimumFrameTime, boolean bWaitForRender) {
this.minimumFrameTime = minimumFrameTime;
this.bWaitForRender = bWaitForRender;
}
public void setFramePolicy(long minimumFrameTime, long maximumFrameTime, boolean bWaitForRender) {
this.minimumFrameTime = minimumFrameTime;
this.maximumFrameTime = maximumFrameTime;
this.bWaitForRender = bWaitForRender;
}
public void run() {
if (bWaitForRender) {
// レンダリングの終了と同期してゲームを進める
ScheduleManager.getInstance().getController("rendering").waitForActivation();
}
mainFrame.doRender();
long curTime = System.currentTimeMillis();
long interval;
if (prevTime == 0L) {
interval = minimumFrameTime;
} else {
interval = curTime - prevTime;
if (interval > maximumFrameTime) {
interval = maximumFrameTime;
}
}
prevTime = curTime;
// 今のゲーム状態のupdateを呼ぶ。
getCurrentGameState().update(mainFrame.getVirtualController(), interval);
}
protected void activateState(IGameState s) {
s.init(mainFrame);
if(s.useTimer()){
timerRun();
}
}
protected void deactivateState(IGameState s) {
if(s.useTimer()){
timerCancel();
}
}
private void timerCancel() {
if (t != null) t.shutdownNow();
}
private void timerRun() {
t = new ScheduledThreadPoolExecutor(1);
// scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
t.scheduleWithFixedDelay(this, minimumFrameTime, minimumFrameTime, TimeUnit.MILLISECONDS);
}
}