📄 pogoroomidlet.java
字号:
/******************************************************************************//** * @file PogoRooMIDlet.java * @brief A simple example of a game using M3G * * Copyright (C) 2004 Superscape plc * * This file is intended for use as a code example, and * may be used, modified, or distributed in source or * object code form, without restriction, as long as * this copyright notice is preserved. * * The code and information is provided "as-is" without * warranty of any kind, either expressed or implied. *//******************************************************************************/package com.superscape.m3g.wtksamples.pogoroo;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Display;import javax.microedition.lcdui.Displayable;import javax.microedition.lcdui.Command;import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Font;import javax.microedition.lcdui.CommandListener;import java.lang.IllegalArgumentException;import java.io.IOException;import java.io.InputStream;import java.io.ByteArrayOutputStream;import javax.microedition.lcdui.Image;import java.util.Timer;import java.util.TimerTask;import javax.microedition.m3g.*;public class PogoRooMIDlet extends MIDlet implements CommandListener{ // UserIDs for objects we use in the scene. static final int POGOROO_MOVE_GROUP_TRANSFORM_ID= 554921620; static final int CAMERA_GROUP_TRANSFORM_ID = 769302310; static final int POGOROO_TRANSFORM_ID = 347178853; static final int ROO_BOUNCE_ID = 418071423; // Key event type IDs public static final int KEY_REPEATED = 0; public static final int KEY_PRESSED = 1; public static final int KEY_RELEASED = 2; // Key IDs static final int keyNone = 0; static final int keyForward = 1; static final int keyBackward = 2; static final int keyLeft = 3; static final int keyRight = 4; static final int MaxHops = 10; static final float GroundEdge = 9.0f; private Display myDisplay = null; private PogoRooCanvas myCanvas = null; private Timer myRefreshTimer = new Timer(); private TimerTask myRefreshTask = null; private Command exitCommand = new Command("Exit", Command.ITEM, 1); Graphics3D myGraphics3D = Graphics3D.getInstance(); World myWorld = null; // Control objects for game play // control for 'roo - group transform and cameras private AnimationController animRoo = null; private Group tRoo = null; private Group tCams = null; private Group acRoo = null; private float dirRoo = 0.0f; private float dirCam = 0.0f; private int keyMoveRoo = keyNone; private int keyTurnRoo = keyNone; private int hopCount = 0; private int animTime = 0; private int animLength = 0; private int animLastTime = 0; private boolean okToHop = false; private float[] posRoo = new float[3]; private float[] posRooLast = new float[3]; private float[] posTemp = new float[3]; private int edgeCount = 0; private float turnAngle; // lookup table for roo hops private float[] hopSteps = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.05f, 0.1f, 0.2f, 0.1f, 0.05f, 0.0f}; int viewport_x; int viewport_y; int viewport_width; int viewport_height; /** * PogoRooMIDlet - default constructor. */ public PogoRooMIDlet() { super(); // Set up the user interface. myDisplay = Display.getDisplay(this); myCanvas = new PogoRooCanvas(this); myCanvas.setCommandListener(this); myCanvas.addCommand(exitCommand); } /** * startApp() */ public void startApp() throws MIDletStateChangeException { myDisplay.setCurrent(myCanvas); try { // load the world from the M3D file myWorld = (World)Loader.load("/com/superscape/m3g/wtksamples/pogoroo/content/pogoroo.m3g")[0]; getObjects(); setupAspectRatio(); } catch(Exception e) { e.printStackTrace(); } myRefreshTask = new RefreshTask(); // scehdule a repeating timer to give us a framerate of 20fps. myRefreshTimer.schedule(myRefreshTask, 0, 50); } /** * Make sure that the content is rendered with the correct aspect ratio. */ void setupAspectRatio() { viewport_x = 0; viewport_y = 0; viewport_width = myCanvas.getWidth(); viewport_height = myCanvas.getHeight(); Camera cam = myWorld.getActiveCamera(); float[] params = new float[4]; int type = cam.getProjection(params); if(type != Camera.GENERIC) { //calculate window aspect ratio float waspect=viewport_width/viewport_height; if (waspect<params[1]) { float height = viewport_width/params[1]; viewport_height=(int)height; viewport_y=(myCanvas.getHeight()-viewport_height)/2; } else { float width = viewport_height*params[1]; viewport_width=(int)width; viewport_x=(myCanvas.getWidth()-viewport_width)/2; } } } /** * getObjects() * get objects from the scene tree for use in the game AI */ public void getObjects() { try { tRoo = (Group) myWorld.find(POGOROO_MOVE_GROUP_TRANSFORM_ID); tCams = (Group) myWorld.find(CAMERA_GROUP_TRANSFORM_ID); acRoo = (Group) myWorld.find(POGOROO_TRANSFORM_ID); animRoo = (AnimationController) myWorld.find(ROO_BOUNCE_ID); // get length of animation AnimationTrack track = acRoo.getAnimationTrack(0); animLength = 1000; // default length, 1 second if (track != null) { KeyframeSequence ks = track.getKeyframeSequence(); if (ks != null) animLength = ks.getDuration(); } } catch(Exception e) { e.printStackTrace(); } } /** * hopRoo() * Hops the roo backwards or forwards */ private void hopRoo() { // Move the kangeroo across the ground, but synchronise with animation if (animTime == 0) // OK to start! { hopCount = 0; okToHop = true; } // in hopping sequence if (okToHop) { switch(keyMoveRoo) { case keyForward: case keyBackward: // move according to direction and increment from look up table // to get nice hop effect int oldHopCount = hopCount; hopCount = (animTime * 10)/animLength; // end of sequence if (hopCount >= MaxHops) { okToHop = false; hopCount = MaxHops-1; } // add up all the steps inbetween positions in animation // this code always misses out increment zero, but that's // OK because it's zero anyway! turnAngle = (dirRoo * 3.14159f) / 180.0f; float h = 0f; for (int i = (oldHopCount+1); i <= hopCount; i++) h += hopSteps[i]; float x = h * (float)Math.cos(turnAngle); float y = h * (float)Math.sin(turnAngle); if (keyMoveRoo == keyForward) tRoo.translate(-x, -y, 0.0f); else tRoo.translate(x, y, 0.0f); break; } } } /** * checkWorldEdge() * Stops the roo going off the edge of the world */ private void checkWorldEdge() { // going off edge of ground tRoo.getTranslation(posRoo); if (edgeCount > 0) edgeCount--; try { // check to see if we have reached the edge of the world if (Math.abs(posRoo[0]) > GroundEdge || Math.abs(posRoo[1]) > GroundEdge) { edgeCount = 10; tRoo.setTranslation(posRooLast[0], posRooLast[1], posRooLast[2]); } } catch(Exception e) { e.printStackTrace(); } } /** * turnRoo() * Turns the roo and makes sure the camera follows. */ private void turnRoo() { // turning Roo can happen any time switch(keyTurnRoo) { case keyLeft: dirRoo += 5f; dirCam -= 5f; tRoo.setOrientation(dirRoo, 0, 0, 1); tCams.setOrientation(dirCam, 0, 0, 1); break; case keyRight: dirRoo -= 5f; dirCam += 5f; tRoo.setOrientation(dirRoo, 0, 0, 1); tCams.setOrientation(dirCam, 0, 0, 1); break; default: if (dirCam > 4.9f) dirCam -= 5.0f; else if (dirCam < -4.9f) dirCam += 5.0f; else dirCam = 0.0f; tCams.setOrientation(dirCam, 0, 0, 1); break; } } /** * animateRoo() * Makes sure that the hopping animation loops correctly. */ private void animateRoo(int worldTime) { // control the kangeroo animation sequence if (animLastTime == 0) animLastTime = worldTime; animTime += (worldTime-animLastTime); // initialise animation at end of sequence if (animTime > animLength) // sequence is ~1000ms { animRoo.setActiveInterval(worldTime, worldTime+2000); animRoo.setPosition(0, worldTime); animTime = 0; } // update storage of last position and time animLastTime = worldTime; } /** * moveRoo() * Act on key presses and any collision detection to move the kangeroo */ private void moveRoo(int worldTime) { hopRoo(); checkWorldEdge(); turnRoo(); animateRoo(worldTime); tRoo.getTranslation(posRooLast); } /** * pauseApp() */ public void pauseApp() { } /** * destroyApp() */ public void destroyApp(boolean unconditional) throws MIDletStateChangeException { myRefreshTimer.cancel(); myRefreshTimer = null; myRefreshTask = null; } /** * MIDlet paint method. */ public void paint(Graphics g) { // clear any area of the screen that is not drawn to by m3g if(g.getClipWidth() != viewport_width || g.getClipHeight() != viewport_height || g.getClipX() != viewport_x || g.getClipY() != viewport_y) { g.setColor(0x00); g.fillRect(0, 0, myCanvas.getWidth(), myCanvas.getHeight()); } // render the 3D scene if ((myGraphics3D != null) && (myWorld != null)) { myGraphics3D.bindTarget(g); myGraphics3D.setViewport(viewport_x, viewport_y, viewport_width, viewport_height); myGraphics3D.render(myWorld); myGraphics3D.releaseTarget(); } } /** * MIDlet keyEvent method. */ public void keyEvent(int type, int keyCode) { switch(type) { case KEY_REPEATED : break; case KEY_PRESSED : // game movement keys - Roo requires synchronised move with animation, // so can only accept key press when last move is complete if (keyMoveRoo == keyNone) { switch(myCanvas.getGameAction(keyCode)) { case Canvas.FIRE: break; case Canvas.UP: keyMoveRoo = keyForward; break; case Canvas.DOWN: keyMoveRoo = keyBackward; break; } if (keyMoveRoo != keyNone) hopCount = MaxHops; } // Roo can turn when it likes switch(myCanvas.getGameAction(keyCode)) { case Canvas.LEFT: keyTurnRoo = keyLeft; break; case Canvas.RIGHT: keyTurnRoo = keyRight; break; } break; case KEY_RELEASED : switch(myCanvas.getGameAction(keyCode)) { case Canvas.LEFT: //intentional fall through case Canvas.RIGHT: keyTurnRoo = keyNone; break; case Canvas.UP: //intentional fall through case Canvas.DOWN: keyMoveRoo = keyNone; break; } break; default : throw new IllegalArgumentException(); } } /** * Handle commands. */ public void commandAction(Command cmd, Displayable disp) { if (cmd == exitCommand) { try { destroyApp(false); notifyDestroyed(); } catch(Exception e) { e.printStackTrace(); } } } /** * Inner class for refreshing the view. */ private class RefreshTask extends TimerTask { public void run() { // Get the canvas to repaint itself. if(myCanvas != null && myGraphics3D != null && myWorld != null) { int startTime = (int)System.currentTimeMillis(); // update the control and game AI moveRoo(startTime); // Update the world to the current time. int validity = myWorld.animate(startTime); // Cause a repaint myCanvas.repaint(viewport_x, viewport_y, viewport_width, viewport_height); } } } /** * Inner class for handling the canvas. */ class PogoRooCanvas extends Canvas { PogoRooMIDlet myRooMIDlet; /** * Construct a new canvas */ PogoRooCanvas(PogoRooMIDlet Testlet) { myRooMIDlet = Testlet; } /** * Initialize self. */ void init() { } /** * Cleanup and destroy. */ void destroy() { } /* * Ask myRooMIDlet to paint itself */ protected void paint(Graphics g) { myRooMIDlet.paint(g); } /* * Ask myRooMIDlet to handle keyPressed events */ protected void keyPressed(int keyCode) { myRooMIDlet.keyEvent(myRooMIDlet.KEY_PRESSED, keyCode); } /* * Ask myRooMIDlet to handle keyReleased events */ protected void keyReleased(int keyCode) { myRooMIDlet.keyEvent(myRooMIDlet.KEY_RELEASED, keyCode); } /* * Ask myRooMIDlet to handle keyRepeated events */ protected void keyRepeated(int keyCode) { myRooMIDlet.keyEvent(myRooMIDlet.KEY_REPEATED, keyCode); } /* * Ask myRooMIDlet to handle pointerDragged events */ protected void pointerDragged(int x, int y) { } /* * Ask myRooMIDlet to handle pointerPressed events */ protected void pointerPressed(int x, int y) { } /* * Ask myRooMIDlet to handle pointerReleased events */ protected void pointerReleased(int x, int y) { } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -