⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 engine.java

📁 该源码实现了j2me中用midp1.0实现的midp2.0的game类
💻 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 + -