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

📄 race_canvas3d.java

📁 j2me的手机源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
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 Race_Canvas3D extends GameCanvas implements CommandListener
{
  private Race_Main app;    // reference to main appplication class
  Command exitCommand;      // Soft keys

  // constants
  private final int WIDTH, HEIGHT;              // screen coordinates
  private final static int KMaxSpeed = 40;      // maximum speed car can have
  private final static int KAccelerateSpeed = 4;// accelerate with this value
  private final static int KBreakSpeed = 10;    // brake with this speed value
  private final static int KRotStep = 200;      // turn car and camera step
  private final static int KShiftWord = 30;     // to shift camera position
  float KDegreeFactor = (360.0f/4096.0f);       // used for calculating degrees

  // precalculated table of sin and cos values: 0-360 degrees
  float[] sinTab;
  float[] cosTab;

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

  // variables used to init camera position
  private Vector3D POS = new Vector3D(0, RoadDef.mGameInitY, -RoadDef.KDistance+15);
  private Vector3D LOOK  = new Vector3D(0, 0, -4096);
  private Vector3D UP    = new Vector3D(0, 4096, 0);
  private int pers = 512;    // angle of visible space

  // transformates used to control camera position and orientation
  private AffineTrans mCamMove = new AffineTrans();
  private AffineTrans mCamRotZ = new AffineTrans();
  private AffineTrans mCamera = new AffineTrans();
  private int mCamAngleZ = 0;       // camera's current angles
  // if position or rotation was changed, objects need to update themselves according to camera
  private boolean mCamereNeedUpdate = true;

  // true - car goes toward finish; false - car goes back to start position
  private boolean carMoveForward = true;
  // car's speed vector
  private Vector3D carSpeedVect = new Vector3D(0, 0, 0);
  // car's speed value (speed vector length)
  private int carSpeedValue = 0;

  // this is a counter for number of game reiteration step
  private int canvasStepCounter = 0;

  private FPS mFps = new FPS();     // to obtain current frame rate
  private WallContainer road;      // road for our world
  private CarUnit myCar;            // car that can be controled by user

////////////////////////////////////////////////////////////////////////////////
// multi-player part
  private boolean mIsMulti = false; // true - 2 players game, awatar is created
  
  private CarUnit awatarCar = null; // avatar car is our party's car
  private Vector3D awatarSpeedVect = new Vector3D(0, 0, 0);
  private int mAvatarUpdateStep = 0;

  private int mCarTwiceRadSqare = (2*30)*(2*30); // square of twice of car radius

  Vector3D aCarPosVect = new Vector3D(0, 0, 0) ;// current car position, to send to other player
  private boolean mMovingFunctionPending = false;

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//                             FUNCTIONS                                     //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

  public Race_Canvas3D(Race_Main app, boolean aIsOtherParty, boolean aPosServer)
  {
    super(false);
    this.app = app;
    mIsMulti = aIsOtherParty;

    setFullScreenMode(true);

    exitCommand = new Command("Quit", Command.EXIT, 1);
    addCommand(exitCommand);
    setCommandListener(this);

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

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

    // init camera
    mCamMove.setIdentity();
    mCamMove.lookAt( POS, LOOK, UP);

    mCamRotZ.setIdentity();
    mCamRotZ.rotationZ(mCamAngleZ);

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

    try {
      // 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));
      }
      // build road (road also reads map)
      road = new WallContainer(WIDTH, HEIGHT, mCamera, effect);
      AffineTrans tmpAT = new AffineTrans();
      // if one player game - build only car
      if(!mIsMulti)
        myCar = new CarUnit(0, RoadDef.mGameInitY, RoadDef.KDistance+5,
                            WIDTH, HEIGHT, mCamera, tmpAT, effect);
      // in two players' mode build also awatar
      else
      {
        // Cars are placed both at start line, moved by either +/- 50 on X from
        // initial position. Server's car on one side, client's car on the other.
        if(aPosServer)
        {
          myCar = new CarUnit(50, RoadDef.mGameInitY, RoadDef.KDistance+5,
                              WIDTH, HEIGHT, mCamera, tmpAT, effect);
          moveWorldCam(-50, 0, 0);
          awatarCar = new CarUnit(-50, RoadDef.mGameInitY, RoadDef.KDistance+5,
                                  WIDTH, HEIGHT, mCamera, tmpAT, effect);
        }
        else
        {
          myCar = new CarUnit(-50, RoadDef.mGameInitY, RoadDef.KDistance+5,
                              WIDTH, HEIGHT, mCamera, tmpAT, effect);
          moveWorldCam(50, 0, 0);
          awatarCar = new CarUnit(50, RoadDef.mGameInitY, RoadDef.KDistance+5,
                                  WIDTH, HEIGHT, mCamera, tmpAT, effect);
        }
      tmpAT = null;
      }
    }
    catch (Exception e) {
      System.out.println("ERROR: Race_Canvas3D::Race_Canvas3D()" + e);
    }
    System.out.println("Race_Canvas3D created");
  }

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

    // before drawing elements, make sure they have updated their positions with relation to camera
    if( mCamereNeedUpdate )
    {
      setCamera();
      road.updateCamPosition(mCamera);
      myCar.updateCamPosition(mCamera);
      if(mIsMulti)
        awatarCar.updateCamPosition(mCamera);
    }
    g3d.bind(g);
    road.render(g3d);
    myCar.render(g3d);
    if(mIsMulti)
      awatarCar.render(g3d);
    g3d.flush();
    g3d.release( g );
    g3d = null;

    // draw some usefull text
    int textPosY = HEIGHT - 30;
    mFps.calculateFps();
    g.setColor(0xFFFFFF);
    g.drawString(mFps.getFpsString(), 0, textPosY, 0);  // frames per second
    g.drawString(myCar.getCarString(), 50, textPosY, 0);// car's X,Y position

    textPosY = HEIGHT - 15;
    g.drawString(road.getRoadString(), 0, textPosY, 0); // no of road units existing
    String str = "Step: " + canvasStepCounter;
    g.drawString(str, 50, textPosY, 0);                 // no of steps since begining of the game
    String strDir;
    if(carMoveForward)
      strDir = "Front";
    else
      strDir = "Back";
    g.drawString(strDir, 140, textPosY, 0);             // car's move on the road direction
    System.gc();
  }

  public void doMove()
  {
    mMovingFunctionPending = true;
    moveObjects();
    mMovingFunctionPending = false;
  }

  public void clearResource()
  {
  }

  // handle soft keys command
  public void commandAction(Command command, Displayable displayable)
  {
    if(command == exitCommand)
    {
      clearResource();
      try {
        app.destroyApp(true);
      }
      catch(Exception e) {}
    }
  }

  public void handleKey()
  {
    int key = getKeyStates();
    if( (key & UP_PRESSED) != 0)      // accelerate
    {
      if(carSpeedValue >= KMaxSpeed)
        return;
      // break faster than normal acceleration
      if( carSpeedValue < 0 )
        carSpeedValue += KBreakSpeed;
      else
        carSpeedValue += KAccelerateSpeed;
      // set top speed limit
      if(carSpeedValue > KMaxSpeed)
        carSpeedValue = KMaxSpeed;
      updateCarMoveDirection(true);
      return;
    }
    if( (key & DOWN_PRESSED) != 0)  // deaccelerate
    {
      if(carSpeedValue <= -KMaxSpeed)
        return;
      if( carSpeedValue > 0 )
        carSpeedValue -= KBreakSpeed;
      else
        carSpeedValue -= KAccelerateSpeed;
      // set top speed limit
      if(carSpeedValue < -KMaxSpeed)
        carSpeedValue = -KMaxSpeed;
      updateCarMoveDirection(true);
      return;
    }
    if( (key & LEFT_PRESSED) != 0)
    {
      myCar.rotate(0, KRotStep, 0);   // turn left
      rotateWorldCam(KRotStep);       // turn left
      updateCarMoveDirection(true);
      return;
    }
    if( (key & RIGHT_PRESSED) != 0)
    {
      myCar.rotate(0, -KRotStep, 0);  // turn right
      rotateWorldCam(-KRotStep);      // turn right
      updateCarMoveDirection(true);
      return;
    }
    if( (key & FIRE_PRESSED) != 0)
    {
      carSpeedValue = 0;
      updateCarMoveDirection(true);
      return;
    }
  }

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

    mCamera.setIdentity();
    mCamera.mul(mCamRotZ, mCamMove);

    mCamereNeedUpdate = false;
  }

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

  private void rotateWorldCam(int aZ)
  {
    mCamereNeedUpdate = true;
    mCamAngleZ += aZ;
    mCamAngleZ = mCamAngleZ & 4095;
  }

  // canvas main loop, it performes actual move and colision handling
  private void moveObjects()
  {
    ++canvasStepCounter;
    if( !mIsMulti ) {
      // if single player and speed is 0, car is not moving so no need to carry on
      if( carSpeedValue == 0 )
        return;
    }
    else {
      if( !isCarCollisionWithAvatar() )
        moveAvatar();
      else
      {
        // get current car's position
        myCar.getLocation(aCarPosVect);
        if(app.sendSignalColision(aCarPosVect, myCar.getSpinAngleY(), carSpeedVect))
        {
          // if collision signal message was sent, stop moving to wait for responce
          mAvatarUpdateStep = 0;
          return;
        }
      }
    }
    // check if car collides with road's side borders
    if( !isCarCollidesWithRoadSides() )
    {
      myCar.move(carSpeedVect.x, carSpeedVect.y);
      // camera folows the car
      moveWorldCam(-carSpeedVect.x, carSpeedVect.y, 0);
    }
    try
    {
      // update road - remove invisible parts, add new ones that becomes visible
      road.updateRoad(carMoveForward, myCar.getPosX(), myCar.getPosY(),
                       WIDTH, HEIGHT, mCamera);
      // car shouldn't leave track at the start or the end of the road
      if( road.isOutOnFinish(myCar.getPosY()) || 
          road.isOutOnStart(myCar.getPosY()) )
      {

⌨️ 快捷键说明

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