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

📄 mw_canvas3d.java

📁 一个在J2ME手机平台上两个人通过蓝牙建立连接从而进行赛车游戏
💻 JAVA
字号:
import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.*;
import java.io.*;
import java.lang.*;
import java.util.*;
import com.mascotcapsule.micro3d.v3.*;

/*
 * Main canvas - used to create, manage and display 3D world
 */
public class MW_Canvas3D extends Canvas implements CommandListener
{
  // reference to main appplication class
  private MW_Main app;
 
  // Soft keys
  Command finishWorkWithCamCommand;
  Command finishWorkWithCarCommand;
  Command exitCommand;

  // constants
  private final int WIDTH, HEIGHT;
  private final int moveStep = 30;
  private final int rotStep = 50;
  private final int moveObjStep = 20;
  private final int rotObjStep = 208;

  // to obtain current frame rate
  FPS mFps = new FPS();

  private Light light = new Light(new Vector3D(-146, 293, 439), 3730, 1626 );
  private Effect3D effect = new Effect3D();

  // variable used to init camera position
  private Vector3D POS = new Vector3D(0, 0, 250);
  private Vector3D LOOK  = new Vector3D(0, 0, -4096);
  private Vector3D UP    = new Vector3D(0, 4096, 0);
  private int pers = 512;    // angle of space visible
  // transformates used to control camera position and orientation
  private AffineTrans mCamMove = new AffineTrans();
  private AffineTrans mCamRotX = new AffineTrans();
  private AffineTrans mCamRotY = new AffineTrans();
  private AffineTrans mCamRotZ = new AffineTrans();
  private AffineTrans mCamera = new AffineTrans();
  // camera's current angles
  private int mCamAngleX = 0;
  private int mCamAngleY = 0;
  private int mCamAngleZ = 0;
  // true if position or rotation was changed and need update
  private boolean mCamereNeedUpdate = true;
  // true - camera is moving, false - car is moving
  private boolean mControlOnCamera = true;
  // precalculated table of sin and cos values: 0-360 degrees
  float[] sinTab;
  float[] cosTab;
  // main cube, "borders" for our world
  WallContainer walls;
  // a net of stationary, rotating cubes
  SpinObstacleContainer obstacles;
  // car that can be controled by user
  CarUnit myCar;

  // constructor
  public MW_Canvas3D(MW_Main app)
  {
    this.app = app;

    setFullScreenMode(true);

    // Init the Soft keys
    finishWorkWithCamCommand = new Command("UsingCam",Command.SCREEN,1);
    finishWorkWithCarCommand = new Command("UsingCar",Command.SCREEN,1);
    exitCommand = new Command("Quit",Command.EXIT,1);
    this.addCommand(exitCommand);
    this.addCommand(finishWorkWithCamCommand);
    this.setCommandListener(this);

    effect.setShadingType(Effect3D.NORMAL_SHADING);
    effect.setLight(light);

    // set screen width and height variables
    WIDTH = getWidth();
    HEIGHT = getHeight();

    // get random position of car and camera (placed above the car)
    // note: carX == -worldX
    Random rn = new Random();
    int pos = rn.nextInt(400);
    if(rn.nextInt(100) > 50 )
      pos *= -1;

    // init camera
    mCamMove.setIdentity();
    mCamMove.lookAt( POS, LOOK, UP);
    mCamMove.m03 -= pos;

    mCamRotX.setIdentity();
    mCamRotX.rotationX(mCamAngleX);
    mCamRotY.setIdentity();
    mCamRotY.rotationY(mCamAngleY);
    mCamRotZ.setIdentity();
    mCamRotZ.rotationZ(mCamAngleZ);

    mCamera.setIdentity();
    mCamera.mul(mCamRotX, mCamMove);
    mCamereNeedUpdate = false;

    // init sin and cos table
    sinTab = new float[361];
    cosTab = new float[361];
    for( int i=0; i<361; ++i ) {
      sinTab[i] = (float)Math.sin(Math.toRadians((double)i));
      cosTab[i] = (float)Math.cos(Math.toRadians((double)i));
//      System.out.println("i: " + i + ", sin: " + sinTab[i] + ", cos: " + cosTab[i]);
    }
    // create objects
    try {
      walls = new WallContainer(WIDTH, HEIGHT, mCamera, effect);
      obstacles = new SpinObstacleContainer(WIDTH, HEIGHT, -400, 80,
                                            mCamera, effect);
      myCar = new CarUnit(pos, 0, -400,
                          WIDTH, HEIGHT, mCamera, effect,
                          sinTab, cosTab);
    }
    catch (Exception e) { e.printStackTrace(); }
  }

  public void paint( Graphics g )
  {
    g.setColor(0x77AAAA);
    g.fillRect(0,0, WIDTH, HEIGHT);

    System.gc();
    Graphics3D g3d = new Graphics3D();

    if( mCamereNeedUpdate ) {
      setCamera();
      walls.updateCamPosition(mCamera);
      myCar.updateCamPosition(mCamera);
    }
    // cubes rotates, so they need to be updated anyway
    obstacles.updateCamPosition(mCamera);

    myCar.updateCamPosition(mCamera);

    try {
      g3d.bind(g);

      walls.render(g3d);
      obstacles.render(g3d);
      myCar.render(g3d);

      g3d.flush();
    }
    catch(Throwable h) {
      h.printStackTrace();
    }
    finally {
      g3d.release( g );
    }

    mFps.calculateFps();
    g.setColor(0x000000);
    g.fillRect(0,0,36,15);
    g.setColor(0xFFFFFF);
    g.drawString(mFps.getFpsString(), 0, 0, 0);
    serviceRepaints();
  }

  public void clearResource()
  {
  }

  // handle soft keys command
  public void commandAction(Command command, Displayable displayable)
  {
    // switch control - now work with car
    if(command == finishWorkWithCamCommand)
    {
      this.removeCommand(finishWorkWithCamCommand);
      this.addCommand(finishWorkWithCarCommand);
      mControlOnCamera = false;
    }
    // switch control - now work with camera
    else if(command == finishWorkWithCarCommand)
    {
      this.removeCommand(finishWorkWithCarCommand);
      this.addCommand(finishWorkWithCamCommand);
      mControlOnCamera = true;
    }
    else if(command == exitCommand)
    {
      clearResource();
      app.destroyApp(true);
    }
  }

  protected void keyPressed(int keyCode)
  {
    if( !handleKeyNum(keyCode) )
      handleKey(getGameAction(keyCode));
  }

  protected void keyRepeated(int keyCode)
  {
    if( !handleKeyNum(keyCode) )
      handleKey(getGameAction(keyCode));
  }

  private void handleKey(int key)
  {
    if(mControlOnCamera) {
      switch(key)
        {
        case Canvas.UP :
          moveWorld(0, 0, -moveStep);   // move forward
            break;
        case Canvas.DOWN :
          moveWorld(0, 0, moveStep);    // move backward
          break;
        case Canvas.LEFT :
          moveWorld(moveStep, 0, 0);    // move left
          break;
        case Canvas.RIGHT :
          moveWorld(-moveStep, 0, 0);   // move right
          break;
        case Canvas.FIRE :
          setInitPosition();
          break;
        }
      }
    else {
      switch(key)
        {
        case Canvas.UP :
        {
          // move forward
          int[] x = new int[1];
          int[] y = new int[1];
          x[0] = 0;
          y[0] = moveObjStep;
          myCar.getMoveLocalToWord(x, y);
          myCar.move(x[0], y[0]);
          moveWorld(-x[0], y[0], 0);
          break;
        }
        case Canvas.DOWN :
        {
          // move backward
          int[] x = new int[1];
          int[] y = new int[1];
          x[0] = 0;
          y[0] = -moveObjStep;
          myCar.getMoveLocalToWord(x, y);
          myCar.move(x[0], y[0]);
          moveWorld(-x[0], y[0], 0);
          break;
        }
        case Canvas.LEFT :
          myCar.rotate(0, rotObjStep, 0);   // turn left
          rotateWorld(0, 0, rotObjStep);    // turn left
          break;
        case Canvas.RIGHT :
          myCar.rotate(0, -rotObjStep, 0);  // turn right
          rotateWorld(0, 0, -rotObjStep);   // turn right
          break;
        case Canvas.FIRE :
          setCamOnObj();
          break;
        }
    }
  }

  private boolean handleKeyNum(int key)
  {
    boolean handled = false;
    if(mControlOnCamera) {
      switch(key)
      {
        case Canvas.KEY_NUM1 :
          rotateWorld(0,0,-rotStep);   // rotate clock wise
          handled = true;
          break;
        case Canvas.KEY_NUM2 :
          rotateWorld(rotStep,0,0);   // turn up
          handled = true;
          break;
        case Canvas.KEY_NUM3 :
          moveWorld(0, moveStep, 0);  // move up
          handled = true;
          break;
        case Canvas.KEY_NUM4 :
          rotateWorld(0,rotStep,0);   // turn left
          handled = true;
          break;
        case Canvas.KEY_NUM6 :
          rotateWorld(0,-rotStep,0);    // turn right
          handled = true;
          break;
        case Canvas.KEY_NUM7 :
          rotateWorld(0,0,rotStep);    // rotate counter clock wise
          handled = true;
          break;
        case Canvas.KEY_NUM8 :
          rotateWorld(-rotStep,0,0);    // turn down
          handled = true;
          break;
        case Canvas.KEY_NUM9 :
          moveWorld(0, -moveStep, 0);   // move down
          handled = true;
          break;
      }
    }
    else {
      switch(key)
      {
        case Canvas.KEY_NUM4 :
        {
          // move left
          int[] x = new int[1];
          int[] y = new int[1];
          x[0] = moveObjStep; y[0] = 0;
          myCar.getMoveLocalToWord(x, y);
          myCar.move(x[0], y[0]);
          moveWorld(-x[0], y[0], 0);
          handled = true;
          break;
        }
        case Canvas.KEY_NUM6 :
        {
          // move right
          int[] x = new int[1];
          int[] y = new int[1];
          x[0] = -moveObjStep; y[0] = 0;
          myCar.getMoveLocalToWord(x, y);
          myCar.move(x[0], y[0]);
          moveWorld(-x[0], y[0], 0);
          handled = true;
          break;
        }
        case Canvas.KEY_NUM2 :
        case Canvas.KEY_NUM8 :
          handled = true;
          break;
      }
    }
    return handled;
  }

  // place camera on top of car
  private void setCamOnObj()
  {
    mCamereNeedUpdate = true;

    mCamAngleX = 0;
    mCamAngleY = 0;
    // car is rotating around Z, it is initially rotated 180 degrees
    mCamAngleZ = myCar.getSpinAngleY() + 2048;

    mCamMove.setIdentity();
    mCamMove.lookAt( POS, LOOK, UP);
    mCamMove.m03 = -myCar.getPosX();     // carX == -worldX
    mCamMove.m13 = myCar.getPosY();
  }

  // place camera in the center of the world
  private void setInitPosition()
  {
    mCamereNeedUpdate = true;

    mCamAngleX = 0;
    mCamAngleY = 0;
    mCamAngleZ = 0;

    mCamMove.setIdentity();
    mCamMove.lookAt( POS, LOOK, UP);
  }

  // update camera's affine transformation according to current position and angles
  private void setCamera()
  {
    mCamRotX.setIdentity();
    mCamRotX.rotationX(mCamAngleX);
    mCamRotY.setIdentity();
    mCamRotY.rotationY(mCamAngleY);
    mCamRotZ.setIdentity();
    mCamRotZ.rotationZ(mCamAngleZ);

    mCamRotX.mul(mCamRotY);
    mCamRotX.mul(mCamRotZ);

    mCamera.setIdentity();
    // one can choose which one is first: rotation or translation
    // this one might be better for moving around the world
//    mCamera.mul(mCamMove, mCamRotX);
    // for folowing car, this order is good
    mCamera.mul(mCamRotX, mCamMove);

    mCamereNeedUpdate = false;
  }

  private void moveWorld(int aX, int aY, int aZ)
  {
    mCamereNeedUpdate = true;
    mCamMove.m03 += aX;
    mCamMove.m13 += aY;
    mCamMove.m23 += aZ;
  }

  private void rotateWorld(int aX, int aY, int aZ)
  {
    mCamereNeedUpdate = true;
    mCamAngleX += aX;
    mCamAngleY += aY;
    mCamAngleZ += aZ;

    if(mCamAngleX >= 2048)
        mCamAngleX = mCamAngleX - 4096;
    else if( mCamAngleX <= -2048 )
        mCamAngleX = mCamAngleX + 4096;

    if(mCamAngleY >= 2048)
        mCamAngleY = mCamAngleY - 4096;
    else if( mCamAngleY <= -2048 )
        mCamAngleY = mCamAngleY + 4096;

    if(mCamAngleZ >= 2048)
        mCamAngleZ = mCamAngleZ - 4096;
    else if( mCamAngleZ <= -2048 )
        mCamAngleZ = mCamAngleZ + 4096;
  }

}


⌨️ 快捷键说明

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