📄 nokia3d.java
字号:
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.m3g.*;
import java.util.*;
public class Nokia3D extends Canvas
{
// Debug output flag
private static final boolean DEBUG = false;
// Graphics3d context
private Graphics3D g3d;
// Random generator
private Random m_random = new Random();
// Some flags
private boolean m_tunnelFadeOut = false;
private boolean m_fogOn = false;
private float m_lightIntensity = 1.0f;
private GameMIDlet m_midlet;
// Nokia scene params
private static final int SCENE_NOKIA_LENGTH = 33000;
private static final int SCENE_NOKIA_HIDEBUG = 22000;
// Snowflake count
private static final int NUM_SNOWFLAKES = 20;
private static final float SNOWFLAKE_SCALE = 6f;
private static final float GROUND_LEVEL = 0f;
// Bug scene length in ms
private static final int SCENE_BUG_LENGTH = 6700;
// The tunnel scene length
private static final int SCENE_TUNNEL_LENGTH = 3000;
// Current scene index
private int m_currentScene;
// Number of scenes
private static final int SCENE_COUNT = 5;
// Scene indices
private static final int SCENE_NOKIA = 0;
private static final int SCENE_BUG = 1;
private static final int SCENE_TUNNEL = 2;
private static final int SCENE_POND = 3;
private static final int SCENE_LOWPOLY = 4;
// User IDs for the ant polygon image
private static final int UID_NOKIA_ANTIMAGE = 47364324;
// Items in the tunnel scene..
private static final int UID_TUNNEL_MESH = 116237701;
private static final int UID_TUNNEL_CAMERA = 457572229;
private static final int UID_TUNNEL_LIGHT = 131143914;
// For the pond scene
private static final int UID_POND_CAMERA1 = 653251478;
private static final int UID_POND_CAMERA2 = 124296655;
private static final int UID_POND_CAMERA3 = 901844788;
private static final int UID_POND_CAMERA4 = 468090727;
private static final int UID_POND_ANTHEAD = 296699498;
// Fov value for pond scenes
private float[] m_cameraFOVs = {35, 25, 30, 30};
private int m_currentCamera = 0;
// Switches for the tunnel
private static final int NO_TEXTURE = 0;
private static final int ONE_TEXTURE = 1;
private static final int DUAL_TEXTURE = 2;
private static final int TOGGLE_FOG = 3;
// We load .m3g scenes here
private World[] m_scenes;
// Time counter
private int m_currentTime;
// Time in millisecs
private long m_lastFrame;
private int m_deltaTime;
//
public Nokia3D( GameMIDlet m )
{
m_midlet = m;
}
//
public void startApp(boolean b)
{
// Create a new 3D graphics context
g3d = Graphics3D.getInstance();
try
{
// Allocate some scenes
m_scenes = new World[SCENE_COUNT];
// Load the nokia scene
m_scenes[SCENE_NOKIA] = loadScene("/nokia_on_ice.m3g");
preInitNokiaScene();
// Start from the first scene
m_currentScene = SCENE_NOKIA;
m_currentTime = 0;
}
catch (Exception e)
{
e.printStackTrace();
}
//
if (DEBUG)
System.out.println("Loaded");
}
// Loads a scene with given name
private World loadScene(String name)
{
long mem = Runtime.getRuntime().freeMemory();
Object3D[] o = null;
try
{
o = Loader.load(name);
} catch (java.lang.OutOfMemoryError e) {
System.err.println("Not enough memory.\nUse '-heapsize 1M' to increse heap size.");
m_midlet.destroyApp( true );
} catch (Exception e) {
e.printStackTrace();
}
long memNow = mem - Runtime.getRuntime().freeMemory();
if (DEBUG)
{
System.out.println("Scene took " + memNow + " bytes..");
// Show free mem
showMemory();
}
return (World) o[0];
}
public void executeOnce()
{
Display display = Display.getDisplay( m_midlet );
if ( display.getCurrent() == this )
{
long frm = System.currentTimeMillis();
// make sure we don't do a huge skip on the first frame
if (m_lastFrame == 0)
{
m_deltaTime = 0;
}
else
{
m_deltaTime = (int) (frm - m_lastFrame);
}
m_lastFrame = frm;
repaint();
serviceRepaints();
}
}
//
protected void keyPressed( int keyCode )
{
int gameAction = getGameAction( keyCode );
if (m_currentScene == SCENE_TUNNEL)
{
if (keyCode == Canvas.KEY_NUM1)
{
switchTunnelMode(NO_TEXTURE);
}
else
if (keyCode == Canvas.KEY_NUM2)
{
switchTunnelMode(ONE_TEXTURE);
}
else
if (keyCode == Canvas.KEY_NUM3)
{
switchTunnelMode(DUAL_TEXTURE);
}
else
if (keyCode == Canvas.KEY_NUM4)
{
switchTunnelMode(TOGGLE_FOG);
}
else
if (keyCode == Canvas.KEY_NUM5)
{
m_tunnelFadeOut = true;
}
}
if (m_currentScene == SCENE_POND)
{
// Find the pond scene..
World pond = m_scenes[SCENE_POND];
// Switch active cameras
if (keyCode == Canvas.KEY_NUM1)
{
Camera c = (Camera) pond.find(UID_POND_CAMERA1);
pond.setActiveCamera(c);
m_currentCamera = 0;
}
else
if (keyCode == Canvas.KEY_NUM2)
{
Camera c = (Camera) pond.find(UID_POND_CAMERA2);
pond.setActiveCamera(c);
m_currentCamera = 1;
}
else
if (keyCode == Canvas.KEY_NUM3)
{
Camera c = (Camera) pond.find(UID_POND_CAMERA3);
pond.setActiveCamera(c);
m_currentCamera = 2;
}
else
if (keyCode == Canvas.KEY_NUM4)
{
Camera c = (Camera) pond.find(UID_POND_CAMERA4);
pond.setActiveCamera(c);
m_currentCamera = 3;
}
else
// Adjust current FOV factor
if (gameAction == Canvas.UP)
{
float fo = m_cameraFOVs[m_currentCamera];
if (fo > 15)
fo-=5;
m_cameraFOVs[m_currentCamera] = fo;
// Set the field-of-view
Camera c = pond.getActiveCamera();
c.setPerspective(fo, 1.0f, 0.1f,5);
}
else
if (gameAction == Canvas.DOWN)
{
float fo = m_cameraFOVs[m_currentCamera];
if (fo < 45)
fo+=5;
m_cameraFOVs[m_currentCamera] = fo;
// Set the field-of-view
Camera c = pond.getActiveCamera();
c.setPerspective(fo, 1.0f, 0.1f,5);
}
}
if (keyCode == Canvas.KEY_NUM0)
{
m_midlet.destroyApp( true );
}
}
// Do something..
public void paint( Graphics g )
{
int w = getWidth();
int h = getHeight();
// if we don't have a g3d context, fill screen with red color
if (g3d == null)
{
g.setClip(0,0, w,h);
g.setColor(100,10,15);
g.fillRect(0,0, w,h);
return;
}
//
int delta = m_deltaTime * 3/4;
// update demo
updateDemo(m_currentTime, delta);
// bind to graphics
g3d.bindTarget(g);
try
{
// get currently displayed scene
World scn = m_scenes[m_currentScene];
scn.animate(m_currentTime);
// do something after animation
postAnimate();
g3d.render(scn);
scn = null;
}
finally
{
// release g3d
g3d.releaseTarget();
}
// update timer by delta value
m_currentTime+=delta;
}
// updates the demo
private void updateDemo(int time, int delta)
{
if (m_currentScene == SCENE_NOKIA)
{
updateNokiaScene(time);
}
else
if (m_currentScene == SCENE_BUG)
{
updateBugScene(time);
}
else
if (m_currentScene == SCENE_TUNNEL)
{
updateTunnelScene(time, delta);
}
}
// does some post-animate() tasks
private void postAnimate()
{
/** target the current camera's group to ant's head */
if (m_currentScene == SCENE_POND)
{
World scn = m_scenes[m_currentScene];
Node camGroup = scn.getActiveCamera().getParent();
camGroup.align(null);
}
}
// Frees the old scene (destroys it's references) and frees up mem
private void freeOldScene()
{
// Get mem
long mem = Runtime.getRuntime().freeMemory();
// Null any references we stored when setting up the scene
removeSnowFlakes();
removeTunnelScene();
// Null the current scene reference
// This is now the only stored reference to a node in the scene,
// so this should allow the whole scene (including all its childen)
// to be garbage collected.
m_scenes[m_currentScene] = null;
// try to free some memory...
System.gc();
// Show how much we actually freed
if (DEBUG)
{
long memNow = Runtime.getRuntime().freeMemory() - mem;
System.out.println("Freed " + memNow + " bytes ...");
// Show free mem
showMemory();
}
}
//
private void showMemory()
{
if (DEBUG)
System.out.println("Memory available : " + Runtime.getRuntime().freeMemory() + " / " + Runtime.getRuntime().totalMemory());
}
//
private void preInitNokiaScene()
{
// Search the node with the 2d bug image and hide it for now..
World nokia = m_scenes[SCENE_NOKIA];
Mesh m = (Mesh) nokia.find(UID_NOKIA_ANTIMAGE);
m.setRenderingEnable(false);
// Add some snowflakes to the scene
initSnowFlakes();
}
//
private boolean showBug = false;
private void updateNokiaScene(int time)
{
// Do not show the bug node before certain time has been reached..
if (time > SCENE_NOKIA_HIDEBUG && !showBug)
{
// Search the image node & display it
World nokia = m_scenes[SCENE_NOKIA];
Mesh m = (Mesh) nokia.find(UID_NOKIA_ANTIMAGE);
m.setRenderingEnable(true);
// Show the lil' fellah :)
showBug = true;
}
// Animate the snowflakes..
animateSnowFlakes(time);
// Switch to bug scene when
if (time > SCENE_NOKIA_LENGTH)
{
//
freeOldScene();
// Load the bug scene
m_scenes[SCENE_BUG] = loadScene("/otokka_jump2.m3g");
//
m_currentScene = SCENE_BUG;
m_currentTime = 0;
}
}
//
private void updateBugScene(int time)
{
// Switch to bug scene when
if (time > SCENE_BUG_LENGTH)
{
//
freeOldScene();
// Load the pond scene
m_scenes[SCENE_TUNNEL] = loadScene("/tunnel.m3g");
preInitTunnelScene();
//
m_currentScene = SCENE_TUNNEL;
m_currentTime = 0;
}
}
//
private void preInitTunnelScene()
{
/** Select the world... */
World w = m_scenes[SCENE_TUNNEL];
// Find the tunnel mesh
Mesh tnl = (Mesh) w.find(UID_TUNNEL_MESH);
// Get the appearance from the mesh
Appearance ap = tnl.getAppearance(0);
// Get the vertex buffer for the tunnel mesh
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -