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

📄 mazecanvas.java

📁 这个也是一个手机上面的3d例子
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.m3g.*;

// Main class. It setups the 3D scene and does the movements
// and rendering
class MazeCanvas
  extends GameCanvas
  implements Runnable
{
  // Height of the walls
  private final static float WALL_HEIGHT = 10.f;
  // overall side of the maze
  private final static float MAZE_SIDE_LENGTH =200f;
  // amount to advance at each step
  private final static float STEP = 3.0f;
  // amount to rotate each time
  private final static float ANGLE_STEP = 8.0f;
  // millis to wait in the main loop
  private final static int MILLIS_PER_TICK = 5;

  // Size of the steps to directions x and z
  // stored to avoid extra trigonometric calculations
  private float stepz = -STEP, stepx = 0f;
  // player's location
  private float locationx = 0f, locationz = 0;
  // player's rotation
  private float angley = 0f;
  // flags whether we are looking the game from the top
  private boolean topView = false;
  // flags to keep the drawing going
  private volatile boolean playing = true;
  // stores the amount of frames per second being displayed
  private volatile float fps = 0;
  // stores how long has taken to run thorugh the maze
  private volatile long gameStart = 0;
  // stores how long has taken to run thorugh the maze
  private volatile long duration = 0;
  // indicates whether the game has finished
  private boolean finished;

  // Parent MIDlet
  private final Maze3DMIDlet midlet;

  // Graphics 3D global instance
  private Graphics3D g3d;
  // the world of the application
  private World world;
  // the world has 2 cameras
  private Camera camera, topCamera;
  // world's background
  private Background background = null;

  // simple rectangular mesh used to locate the player
  private Mesh locationSquare = null;

  // wall alternate appeareances
  private Appearance wallClearAppearance = new Appearance();
  private Appearance wallAppearance = new Appearance();
  // points to the mesh last made semi transparent
  private Mesh transparentMesh = null;
  private Maze maze = new Maze(10, MAZE_SIDE_LENGTH, WALL_HEIGHT);

  private Thread mainThread = null;


  // Construct the Displayable
  MazeCanvas(Maze3DMIDlet midlet)
  {
    super(true);

    this.midlet = midlet;
  }

  // (Re)Starts the game
  void start()
  {
    playing = true;
    gameStart = System.currentTimeMillis() - duration;
    mainThread = new Thread(this);
    mainThread.start();
  }

  // stops/pauses the game
  void stop()
  {
    duration = System.currentTimeMillis() - gameStart;
    playing = false;
  }

  // switches from top view to normal view and vice versa
  void switchView()
  {
    topView = !topView;
    setView();
    // informs the MIDLet since this can be switched internally
    midlet.viewSwitched();
  }


  void setView()
  {
    // reset the locaiton and draw on top of the maze
    locationSquare.setTranslation(locationx,
                                  2 * WALL_HEIGHT + 3f, locationz);
    // the square is rendered only in top view
    locationSquare.setRenderingEnable(topView);
    // the background is removed in top view
    world.setBackground(topView ? null : background);
    // sets the actual active camera
    if (topView)
    {
      world.setActiveCamera(topCamera);
    }
    else
    {
      world.setActiveCamera(camera);
    }
  }

  // Builds the world
  void init()
  {
    setFullScreenMode(true);
    duration = 0;

    // get a Graphics3D instance
    g3d = Graphics3D.getInstance();
    // build the world and the cameras
    world = new World();
    camera = new Camera();
    topCamera = new Camera();
    world.addChild(camera);
    world.addChild(topCamera);
    float w = (float)getWidth();
    float h = (float)getHeight();

    // set the perspective
    camera.setPerspective(60.f, w / h, 0.1f, 1000.f);
    topCamera.setPerspective(60.f, w / h, 0.1f, 1000.f);

    // the top camer has a fixed transform looking from the top
    Transform topCameraTransform = new Transform();
    topCameraTransform.postRotate(90, -1f, 0f, 0f);
    topCameraTransform.postTranslate(0f, 0f,MAZE_SIDE_LENGTH);
    //topCameraTransform.postTranslate(0f, 0f, 1.2f * MAZE_SIDE_LENGTH);
    topCamera.setTransform(topCameraTransform);

    // Setup the background
    background = new Background();
    Image backgroundImage = Maze3DMIDlet.makeImage("/background.png");
    if (backgroundImage != null)
    {
      background.setImage(new Image2D(Image2D.RGB, backgroundImage));
      background.setImageMode(Background.REPEAT, Background.REPEAT);
    }
    world.setBackground(background);

    createFloor();
    createLocationSquare();
    setUpMaze();
    createStartEndMarks();
    setView();

    // setup the initial location
    locationx = maze.findStartLocationX();
    locationz = maze.findStartLocationZ();
    // look at the center
    angley = -180f;


    setupCamera();

    start();
  }

  // creates the labeld at the start and at the end of the maze
  private void createStartEndMarks()
  {
    // The marks' appearance
    Appearance startMarkAppearance = new Appearance();
    Appearance endMarkAppearance = new Appearance();

    // The composite mode is ALPHA to show only the letters
    // the background is hidden using the alpha layer
    CompositingMode markCompositeMode = new CompositingMode();
    markCompositeMode.setBlending(CompositingMode.ALPHA);
    startMarkAppearance.setCompositingMode(markCompositeMode);
    endMarkAppearance.setCompositingMode(markCompositeMode);

    // The label's text is built using a texture
    Texture2D startMarkTexture = null;
    Image startMarkTextureImage =
        Maze3DMIDlet.makeImage("/start_label.png");
    if (startMarkTextureImage != null)
    {
      startMarkTexture = new Texture2D(
          new Image2D(Image2D.RGBA, startMarkTextureImage));
      // the texture is not repeated
      startMarkTexture.setWrapping(Texture2D.WRAP_CLAMP,
                                   Texture2D.WRAP_CLAMP);
      startMarkTexture.setBlending(Texture2D.FUNC_REPLACE);
      startMarkTexture.setFiltering(Texture2D.FILTER_NEAREST,
                                    Texture2D.FILTER_NEAREST);
      startMarkAppearance.setTexture(0, startMarkTexture);
    }

    Texture2D endMarkTexture = null;
    Image endMarkTextureImage =
        Maze3DMIDlet.makeImage("/end_label.png");
    if (endMarkTextureImage != null)
    {
      endMarkTexture = new Texture2D(
          new Image2D(Image2D.RGBA, endMarkTextureImage));
      // the texture is not repeated
      endMarkTexture.setWrapping(Texture2D.WRAP_CLAMP,
                                 Texture2D.WRAP_CLAMP);
      endMarkTexture.setBlending(Texture2D.FUNC_REPLACE);
      endMarkTexture.setFiltering(Texture2D.FILTER_NEAREST,
                                  Texture2D.FILTER_NEAREST);
      endMarkAppearance.setTexture(0, endMarkTexture);
    }
    // create the start mesh
    Plane startMarkPlane = maze.createStartMark();
    Mesh startMarkMesh = startMarkPlane.createMesh();
    startMarkMesh.setAppearance(0, startMarkAppearance);
    // these are not pickable
    startMarkMesh.setPickingEnable(false);
    world.addChild(startMarkMesh);

    // creates the end mesh
    Plane endMarkPlane = maze.createEndMark();
    Mesh endMarkMesh = endMarkPlane.createMesh();
    endMarkMesh.setAppearance(0, endMarkAppearance);
    // is not pickable either
    endMarkMesh.setPickingEnable(false);

    // Create a sequence of 4 keyframes
    KeyframeSequence keyframes =
        new KeyframeSequence(4,3, KeyframeSequence.LINEAR);
    keyframes.setDuration(12000);
    keyframes.setRepeatMode(KeyframeSequence.LOOP);

    float[] trans = new float[4];
    endMarkMesh.getOrientation(trans);
    // create set the keyframes.
    // Basically keep x and z and animate in the y axis
    keyframes.setKeyframe(0, 0,
        new float[]{trans[0], trans[1], trans[2]});
    keyframes.setKeyframe(1, 4000,
        new float[]{trans[0], trans[1] - WALL_HEIGHT / 4, trans[2]});
    keyframes.setKeyframe(2, 8000,
        new float[]{trans[0], trans[1] + WALL_HEIGHT / 4, trans[2]});
    keyframes.setKeyframe(3, 12000,
        new float[]{trans[0], trans[1], trans[2]});
    AnimationTrack animationTrack =
        new AnimationTrack(keyframes, AnimationTrack.TRANSLATION);

    AnimationController anim = new AnimationController();
    animationTrack.setController(anim);

    // add the animation track
    endMarkMesh.addAnimationTrack(animationTrack);

    world.addChild(endMarkMesh);
  }


  // creates the floor
  private void createFloor()
  {
    float floorSide = MAZE_SIDE_LENGTH / 2;

    // define the location and size of the floor
    Transform floorTransform = new Transform();
    floorTransform.postRotate(90.0f, -1.0f, 0.0f, 0.0f);
    floorTransform.postScale(floorSide, floorSide, 1.0f);

    // The floor appearance. Basically a texture repeated many times
    Appearance floorAppearance = new Appearance();
    // The floor needs that perspective correction is enabled
    PolygonMode floorPolygonMode = new PolygonMode();
    floorPolygonMode.setPerspectiveCorrectionEnable(true);
    floorAppearance.setPolygonMode(floorPolygonMode);

    // load the texture
    Texture2D floorTexture = null;
    Image floorTextureImage = Maze3DMIDlet.makeImage("/floor.png");
    if (floorTextureImage != null)
    {
      floorTexture = new Texture2D(
          new Image2D(Image2D.RGB, floorTextureImage));
      // the texture is repeated many times
      floorTexture.setWrapping(Texture2D.WRAP_REPEAT,
                               Texture2D.WRAP_REPEAT);
      floorTexture.setBlending(Texture2D.FUNC_REPLACE);
      floorTexture.setFiltering(Texture2D.FILTER_LINEAR,
                                Texture2D.FILTER_NEAREST);
      floorAppearance.setTexture(0, floorTexture);
    }
    Plane floor = new Plane(floorTransform, 10);

    // build the mesh
    Mesh floorMesh = floor.createMesh();
    floorMesh.setAppearance(0, floorAppearance);
    // the floor is not pickable
    floorMesh.setPickingEnable(false);
    // add to the world
    world.addChild(floorMesh);
  }


  // create the player location square
  private void createLocationSquare()
  {
    // initial location of the square
    // we are only interested in rotating and scaling it
    Transform locationSquareTransform = new Transform();
    locationSquareTransform.postRotate(90.0f, -1.0f, 0.0f, 0.0f);
    locationSquareTransform.postScale(8, 8, 1.0f);

    // the location apparance is a simple texture decal
    Appearance locationSquareAppearance = new Appearance();
    Texture2D locationSquareTexture = null;
    Image locationSquareImage = Maze3DMIDlet.makeImage("/location.png");
    if (locationSquareImage != null)
    {
      locationSquareTexture = new Texture2D(
          new Image2D(Image2D.RGB, locationSquareImage));
      // the texture is not repeated

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -