📄 mazecanvas.java
字号:
locationSquareTexture.setWrapping(Texture2D.WRAP_CLAMP,
Texture2D.WRAP_CLAMP);
locationSquareTexture.setBlending(Texture2D.FUNC_REPLACE);
locationSquareTexture.setFiltering(Texture2D.FILTER_NEAREST,
Texture2D.FILTER_NEAREST);
locationSquareAppearance.setTexture(0, locationSquareTexture);
}
Plane locationPlane = new Plane(locationSquareTransform, 1);
locationSquare = locationPlane.createMesh();
locationSquare.setAppearance(0, locationSquareAppearance);
locationSquare.setRenderingEnable(false);
locationSquare.setPickingEnable(false);
world.addChild(locationSquare);
}
private void setUpMaze()
{
// the walls need perspection correction enabled
PolygonMode wallPolygonMode = new PolygonMode();
wallPolygonMode.setPerspectiveCorrectionEnable(true);
// build the wall semi transparent appearance
wallClearAppearance.setPolygonMode(wallPolygonMode);
// this is to make a wall semi transparent
CompositingMode wallClearCompositeMode = new CompositingMode();
wallClearCompositeMode.setBlending(CompositingMode.ALPHA_ADD);
wallClearAppearance.setCompositingMode(wallClearCompositeMode);
// build the normal wall appearance
wallAppearance.setPolygonMode(wallPolygonMode);
// load the wall texture
Image wallTextureImage = Maze3DMIDlet.makeImage("/wall.png");
if (wallTextureImage != null)
{
Texture2D wallTexture = null;
wallTexture = new Texture2D(
new Image2D(Image2D.RGB, wallTextureImage));
// the texture is repeated
wallTexture.setWrapping(Texture2D.WRAP_REPEAT,
Texture2D.WRAP_CLAMP);
wallTexture.setBlending(Texture2D.FUNC_REPLACE);
wallTexture.setFiltering(Texture2D.FILTER_LINEAR,
Texture2D.FILTER_NEAREST);
// set the texture
wallAppearance.setTexture(0, wallTexture);
wallClearAppearance.setTexture(0, wallTexture);
}
// The maze create the planes and they are added to the world
Enumeration wallsEnum = maze.createPlanes();
while (wallsEnum.hasMoreElements())
{
Mesh wallMesh = ((Plane) wallsEnum.nextElement()).createMesh();
wallMesh.setAppearance(0, wallAppearance);
world.addChild(wallMesh);
}
}
// decides whether it is allowed to move to a given place
// otherwise it is possible to cross walls and go outside the maze
private boolean canMove(float stepx, float stepz, boolean forward)
{
float x = locationx + stepx;
float z = locationz + stepz;
// First check if inside the maze area
float mazeSize = MAZE_SIDE_LENGTH / 2 - 2;
if (x <= -mazeSize
|| z <= -mazeSize
|| x > mazeSize
|| z > mazeSize)
{
return false;
}
// collision with walls is easily implemented using picking
// if there is something in front of the camera and the distance is too
// small, the movement is not allowed
RayIntersection ri = new RayIntersection();
// inverse the point of view to detect if it is moving
// bacwards
if (!forward)
{
camera.postRotate(180, 0f, 1f, 0f);
}
if (world.pick(-1, 0.5f, 0.5f, camera, ri))
{
Node selected = ri.getIntersected();
if (selected instanceof Mesh)
{
// multiply per 9 since that's the size of a step
float distance = ri.getDistance() * 9;
if (distance <= 0.1)
{
return false;
}
}
}
if (!forward)
{
// revert to the original view
camera.postRotate(-180, 0f, 1f, 0f);
}
return true;
}
// the method checks whenever the keys are pressed
private void checkKeys()
{
int keyState = getKeyStates();
boolean moved = false;
// if fire is detected the mesh in front of you is made semi transparent
if ((keyState & FIRE_PRESSED) != 0)
{
RayIntersection ri = new RayIntersection();
if (world.pick(-1, 0.5f, 0.5f, camera, ri))
{
// if there is something to pick
Node selected = ri.getIntersected();
if (selected instanceof Mesh)
{
// make the wall semi transparent
transparentMesh = ((Mesh) selected);
transparentMesh.setAppearance(0, wallClearAppearance);
transparentMesh.setAlphaFactor(0.8f);
}
}
}
// here we assume only one button is pressed otherwise the "second"
// press is ignored
if ((keyState & LEFT_PRESSED) != 0)
{
// move to the left
angley += ANGLE_STEP;
stepx = STEP * (float) Math.sin(Math.toRadians(angley));
stepz = STEP * (float) Math.cos(Math.toRadians(angley));
// shift the background a bit to the right
background.setCrop(background.getCropX() + 3,
0,
getWidth(),
getHeight());
moved = true;
}
else if ((keyState & RIGHT_PRESSED) != 0)
{
// move to the right
angley -= ANGLE_STEP;
stepx = STEP * (float) Math.sin(Math.toRadians(angley));
stepz = STEP * (float) Math.cos(Math.toRadians(angley));
// shift the background a bit to the left
background.setCrop(background.getCropX() - 3,
0,
getWidth(),
getHeight());
moved = true;
}
else if ((keyState & UP_PRESSED) != 0)
{
// move forward, but first check if it is allowed
if (canMove(-stepx, -stepz, true))
{
locationx -= stepx;
locationz -= stepz;
}
moved = true;
}
else if ((keyState & DOWN_PRESSED) != 0)
{
// move backwards, but first check if it is allowed
if (canMove(stepx, stepz, false))
{
locationx += stepx;
locationz += stepz;
}
moved = true;
}
// if moved we make the last transparent wall normal
// and reset the view
if (moved)
{
if (!finished && maze.isAtTheEnd(locationx, locationz, 4f))
{
finished = true;
}
// if there was a mesh semi transparent
// return to normal
if (transparentMesh != null)
{
transparentMesh.setAppearance(0, wallAppearance);
transparentMesh.setAlphaFactor(1f);
transparentMesh = null;
}
// if we move we reset the top view state
if (topView)
{
switchView();
}
setupCamera();
}
}
// key pressed used to show the main menu
protected void keyPressed(int key)
{
if (key < 0)
{
midlet.showMenu();
}
}
// sets the camera location
private void setupCamera()
{
camera.setOrientation(angley, 0f, 1f, 0f);
camera.setTranslation(locationx, 10f, locationz);
}
// draw 2d information on top of the screen
private void draw2D(Graphics g)
{
// text color
g.setColor(45, 235, 45);
StringBuffer status = new StringBuffer(finished ? "Done" : "");
if (finished)
{
duration = System.currentTimeMillis() - gameStart;
status.append(" Time:").append(duration / 1000);
}
else
{
status.append(" Time:");
status.append((System.currentTimeMillis() - gameStart) / 1000);
}
// draw time on the top right
g.drawString(status.toString(),
getWidth(),
0,
Graphics.TOP | Graphics.RIGHT);
// draw FPS on the bottom left
g.drawString("FPS: " + fps,
0,
getHeight(),
Graphics.BOTTOM | Graphics.LEFT);
}
// paint the scene
private void draw3D(Graphics g)
{
boolean bound = false;
try
{
// binds the target
g3d.bindTarget(g);
bound = true;
// advance the animation
world.animate((int)(System.currentTimeMillis() - gameStart));
// do the rendering
g3d.render(world);
}
finally
{
// release the target
if (bound)
{
g3d.releaseTarget();
}
}
}
public void run()
{
Graphics g = getGraphics();
while (playing)
{
try
{
long startTime = System.currentTimeMillis();
if (isShown())
{
// update the world if the player has moved
checkKeys();
long drawingTime = System.currentTimeMillis();
// draw the 3d part
draw3D(g);
drawingTime = System.currentTimeMillis() - drawingTime;
// calculate fps
fps = 1000 / drawingTime;
// draw the 2d part
draw2D(g);
// flush to the screen
flushGraphics();
}
// wait for a little and give the other threads
// the chance to run
long timeTaken = System.currentTimeMillis() - startTime;
if (timeTaken < MILLIS_PER_TICK)
{
synchronized (this)
{
wait(MILLIS_PER_TICK - timeTaken);
}
}
else
{
Thread.currentThread().yield();
}
}
catch (Exception e)
{
// ignore. Not much to but we want to keep the loop running
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -