📄 engine.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Copyright(c) 2004 Jordi Martin Perez
*/
package org.piratis.j2me.core.game;
import javax.microedition.lcdui.Graphics;
import org.piratis.j2me.core.BBox2D;
/**
* Default Engine class. All game engines based on J2MEGL must
* override this one because of the tight binding between this class
* and the Canvas.<br>
* <br>
* Once started, the engine enters and endlessly loop which won't
* stop until nextRunLoop return false (good candidate to be
* overwritten, isn't it?).<br>
* <br>
* A game might contain more than one engine, depending on the status
* of the game and if it has playable sections/levels which
* differ among them in great measure, etc.. It is reponsibility of the
* programmer to stop one and start the other.
*
* @author Jordi Mart韓
* @copyright Copyright (c) 2004
* @created 24-jun-2004
* @version $Id: Engine.java,v 1.5 2004/07/22 16:50:39 piratis Exp $
*/
public abstract class Engine
implements Runnable
{
/**
* Key status constants
*/
public static final int IS_UP = 1 << Canvas.UP;
public static final int IS_DOWN = 1 << Canvas.DOWN;
public static final int IS_LEFT = 1 << Canvas.LEFT;
public static final int IS_RIGHT = 1 << Canvas.RIGHT;
public static final int IS_FIRE = 1 << Canvas.FIRE;
public static final int IS_GAME_A = 1 << Canvas.GAME_A;
public static final int IS_GAME_B = 1 << Canvas.GAME_B;
public static final int IS_GAME_C = 1 << Canvas.GAME_C;
public static final int IS_GAME_D = 1 << Canvas.GAME_D;
/**
* Keep stored current key status
*/
private int keyState;
private int keyReleaseState;
/**
* Default FPS setting
*/
public static int DEFAULT_FPS = 10;
/**
* Engine and canvas are tightly bound
*/
protected Canvas canvas = null;
/**
* Where to store all the layers/sprites/tiles
*/
protected LayerManager layers = null;
/**
* Boolean attribute to see if it is running
*/
private boolean running;
/**
* Engine/Canvas FPS refresh rate
*/
private int fps = Engine.DEFAULT_FPS;
/**
* Creates a new Engine. FPS are set to the default value.
* @param canvas the canvas of this engine
*/
public Engine(Canvas canvas)
{
this(canvas, Engine.DEFAULT_FPS);
}
/**
* Creates a new Engine. FPS is not ensured: the engine/library
* will do its best to accomplish it!
* @param canvas the canvas of this engine
* @param fps desired frames per second refresh rate
*/
public Engine(Canvas canvas, int fps)
{
super();
this.initialize(canvas, fps);
}
/**
* @see java.lang.Runnable#run()
*/
public void run()
{
try
{
// time variables
long startTime;
int interval = 1000 / this.fps;
// initial settings
setRunningStatus();
Thread currentThread = Thread.currentThread();
while (nextRunLoop() &&
currentThread == Thread.currentThread())
{
startTime = System.currentTimeMillis();
// handle keys pressed
this.input();
// do engine work
this.work();
// paint what is needed/required
this.paint();
// wait
this.waitSomething(startTime, interval);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* Performs a stop
*/
public void stop()
{
this.running = false;
}
/**
* Wait method to synchronize work & repainting. Subclasses can override
* this method to adjust waiting times. It is called at the end of the
* engine loop.
* @param loopStartTime the start time of the engine loop
* @param interval adjusted to the engine/canvas FPS
*/
protected void waitSomething(long loopStartTime, long interval)
{
// let's see if we have to wait
long time2 = System.currentTimeMillis() - loopStartTime;
if (time2 < interval)
{
try { Thread.sleep(interval - time2); }
catch (InterruptedException e) {}
}
else
Thread.yield();
}
/**
* Real engine method that should be implemented in subclasses
*/
protected abstract void work();
/**
* Engine's key management method. This must be implemented in
* subclasses in order to react to user key strokes
*/
protected abstract void input();
/**
* Default paint method.
*
*/
protected void paint()
{
Graphics g = this.canvas.getGraphics();
this.canvas.paintBackground(g,
new BBox2D(0, 0, this.canvas.getWidth(), this.canvas.getHeight()));
// TODO: remove & parametrise this below!
this.layers.paint(g, 0, 0);
// call repainting request
this.canvas.getDisplay().callSerially(this.canvas);
}
/**
* Initialize method..
*/
protected void initialize(Canvas canvas, int newFps)
{
// store canvas for further use
this.canvas = canvas;
// new layer manager
this.layers = new LayerManager();
// store FPS
this.fps = newFps;
// initial engine status
setInitialStatus();
// set canvas' engine
this.canvas.setEngine(this);
}
/**
* Sets the status variables to an initial status
*/
protected void setInitialStatus()
{
this.running = false;
this.keyState = this.keyReleaseState = 0;
}
/**
* Checks if the run loop needs to continue running (based on engine status)
* @return
*/
protected boolean nextRunLoop()
{
return this.running;
}
/**
* Engine Status to a running status
*/
protected void setRunningStatus()
{
this.running = true;
}
/**
* Canvas calls this method upon a key is pressed. The key pressed
* status will be automaticaly updated.
* @param keyCode which key has been pressed
*/
protected void keyPressed(int keyCode)
{
// set bit key pressed status -> 1
this.keyState = this.keyState |
(1 << this.canvas.getGameAction(keyCode));
// key released status -> 0
keyReleaseState = keyReleaseState &
~(1 << this.canvas.getGameAction(keyCode));
}
/**
* Canvas call this method upon a key is released. The key pressed
* status will be automaticaly updated.
* @param keyCode which key has been released
*/
protected void keyReleased(int keyCode)
{
// key released status -> 1
this.keyReleaseState = this.keyReleaseState |
(1 << this.canvas.getGameAction(keyCode));
}
/**
* Gets the states of the game keys. The key's status must be checked
* bitwise.<br>
* <br>
* After calling this method, the key status will be cleared.
* @return
*/
public int getKeyStates() {
// store var to be returned
int result = this.keyState;
// apply release status
this.keyState = this.keyState & ~this.keyReleaseState;
// nullify release status
this.keyReleaseState = 0;
// return key status
return result;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -