?? race_canvas3d.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 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 + -