📄 m3gcanvas.java
字号:
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.m3g.Camera;
import javax.microedition.m3g.Graphics3D;
import javax.microedition.m3g.Light;
import javax.microedition.m3g.Loader;
import javax.microedition.m3g.Object3D;
import javax.microedition.m3g.Transform;
import javax.microedition.m3g.World;
public class M3GCanvas
extends GameCanvas
implements Runnable {
// Thread-control
boolean running = false;
boolean done = true;
// If the game should end
public static boolean gameOver = false;
// Rendering hints
public static final int STRONG_RENDERING_HINTS = Graphics3D.ANTIALIAS | Graphics3D.TRUE_COLOR | Graphics3D.DITHER;
public static final int WEAK_RENDERING_HINTS = 0;
public static int RENDERING_HINTS = STRONG_RENDERING_HINTS;
// Key array
boolean[] key = new boolean[5];
// Key constants
public static final int FIRE = 0;
public static final int UP = FIRE + 1;
public static final int DOWN = UP + 1;
public static final int LEFT = DOWN + 1;
public static final int RIGHT = LEFT + 1;
// Global identity matrix
Transform identity = new Transform();
// Global Graphics3D object
Graphics3D g3d = null;
// The global world object
World world = null;
// The global camera object
Camera cam = null;
// Camera rotation
float camRot = 0.0f;
double camSine = 0.0f;
double camCosine = 0.0f;
// Head bobbing
float headDeg = 0.0f;
/** Constructs the canvas
*/
public M3GCanvas(int fps)
{
// We don't want to capture keys normally
super(true);
// We want a fullscreen canvas
setFullScreenMode(true);
// Load our world
loadWorld();
// Load our camera
loadCamera();
}
/** When fullscreen mode is set, some devices will call
* this method to notify us of the new width/height.
* However, we don't really care about the width/height
* in this tutorial so we just let it be
*/
public void sizeChanged(int newWidth, int newHeight)
{
}
/** Loads our camera */
private void loadCamera()
{
// BAD!
if(world == null)
return;
// Get the active camera from the world
cam = world.getActiveCamera();
// Create a light
Light l = new Light();
// Make sure it's AMBIENT
l.setMode(Light.AMBIENT);
// We want a little higher intensity
l.setIntensity(3.0f);
// Add it to our world
world.addChild(l);
}
/** Loads our world */
private void loadWorld()
{
try
{
// Loading the world is very simple. Note that I like to use a
// res-folder that I keep all files in. If you normally just put your
// resources in the project root, then load it from the root.
Object3D[] buffer = Loader.load("/res/map.m3g");
// Find the world node, best to do it the "safe" way
for(int i = 0; i < buffer.length; i++)
{
if(buffer[i] instanceof World)
{
world = (World)buffer[i];
break;
}
}
// Clean objects
buffer = null;
}
catch(Exception e)
{
// ERROR!
System.out.println("Loading error!");
reportException(e);
}
}
/** Draws to screen
*/
private void draw(Graphics g)
{
// Envelop all in a try/catch block just in case
try
{
// Move the camera around
moveCamera();
// Get the Graphics3D context
g3d = Graphics3D.getInstance();
// First bind the graphics object. We use our pre-defined rendering hints.
g3d.bindTarget(g, true, RENDERING_HINTS);
// Now, just render the world. Simple as pie!
g3d.render(world);
}
catch(Exception e)
{
reportException(e);
}
finally
{
// Always remember to release!
g3d.releaseTarget();
}
}
/**
*
*/
private void moveCamera() {
// Check controls
if(key[LEFT])
{
camRot += 5.0f;
}
else if(key[RIGHT])
{
camRot -= 5.0f;
}
// Set the orientation
cam.setOrientation(camRot, 0.0f, 1.0f, 0.0f);
// Calculate trigonometry for camera movement
double rads = Math.toRadians(camRot);
camSine = Math.sin(rads);
camCosine = Math.cos(rads);
if(key[UP])
{
// Move forward
cam.translate(-2.0f * (float)camSine, 0.0f, -2.0f * (float)camCosine);
// Bob head
headDeg += 0.5f;
// A simple way to "bob" the camera as the user moves
cam.translate(0.0f, (float)Math.sin(headDeg) / 3.0f, 0.0f);
}
else if(key[DOWN])
{
// Move backward
cam.translate(2.0f * (float)camSine, 0.0f, 2.0f * (float)camCosine);
// Bob head
headDeg -= 0.5f;
// A simple way to "bob" the camera as the user moves
cam.translate(0.0f, (float)Math.sin(headDeg) / 3.0f, 0.0f);
}
// If the user presses the FIRE key, let's quit
if(key[FIRE])
M3GMidlet.die();
}
/** Starts the canvas by firing up a thread
*/
public void start() {
Thread myThread = new Thread(this);
// Make sure we know we are running
running = true;
done = false;
// Start
myThread.start();
}
/** Run, runs the whole thread. Also keeps track of FPS
*/
public void run() {
while(running) {
try {
// Call the process method (computes keys)
process();
// Draw everything
draw(getGraphics());
flushGraphics();
// Sleep to prevent starvation
try{ Thread.sleep(30); } catch(Exception e) {}
}
catch(Exception e) {
reportException(e);
}
}
// Notify completion
done = true;
}
/**
* @param e
*/
private void reportException(Exception e) {
System.out.println(e.getMessage());
System.out.println(e);
e.printStackTrace();
}
/** Pauses the game
*/
public void pause() {}
/** Stops the game
*/
public void stop() { running = false; }
/** Processes keys
*/
protected void process()
{
int keys = getKeyStates();
if((keys & GameCanvas.FIRE_PRESSED) != 0)
key[FIRE] = true;
else
key[FIRE] = false;
if((keys & GameCanvas.UP_PRESSED) != 0)
key[UP] = true;
else
key[UP] = false;
if((keys & GameCanvas.DOWN_PRESSED) != 0)
key[DOWN] = true;
else
key[DOWN] = false;
if((keys & GameCanvas.LEFT_PRESSED) != 0)
key[LEFT] = true;
else
key[LEFT] = false;
if((keys & GameCanvas.RIGHT_PRESSED) != 0)
key[RIGHT] = true;
else
key[RIGHT] = false;
}
/** Checks if thread is running
*/
public boolean isRunning() { return running; }
/** checks if thread has finished its execution completely
*/
public boolean isDone() { return done; }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -