📄 cartest.java
字号:
}
}
/**
* A simple method that does the number-blitting.
*/
private void blitNumber(int number, int x, int y) {
if (numbers!=null) {
String sNum=Integer.toString(number);
for (int i=0; i<sNum.length(); i++) {
char cNum=sNum.charAt(i);
int iNum=cNum-48;
buffer.blit(numbers, iNum*5, 0, x, y, 5, 9, FrameBuffer.TRANSPARENT_BLITTING);
x+=5;
}
}
}
/**
* Does the collision detection and the movement of the car.
*/
private void moveCar() {
if (left) {
car.turnLeft();
}
if (right) {
car.turnRight();
}
/**
* We need to store this matrix for the case that the car can't be placed
* at the current location.
*/
Matrix backUpTrans=car.getTranslationMatrix().cloneMatrix();
if (forward) {
if (speed<15) {speed+=0.1f;}
car.setSpeed(speed);
car.moveForward();
}
if (back) {
if (speed>0) {speed-=0.3f;}
if (speed<0) {speed=0;
}
car.setSpeed(speed);
car.moveForward();
}
if (speed>=0 && !back && !forward) {
/**
* If car is still moving but not accelerating anymore,
* then it should get slower over time.
*/
speed-=0.075f;
if (speed<0) {speed=0;}
car.setSpeed(speed);
car.moveForward();
}
/**
* Try to place the car at its new location
*/
boolean ok=car.place(terrain);
if (!ok) {
/**
* Placing the car failed...we'll restore the backup
* translation matrix in that case (may happen when
* actually leaving the map).
*/
car.setTranslationMatrix(backUpTrans);
speed=0;
car.setSpeed(speed);
} else {
/**
* The car has been placed, so we can draw some skidmarks if required.
*/
skidMan.createSkidMarks(car);
}
}
/**
* Move the camera. The camera will always look at the car from behind and takes
* the last camera position into account, so that the movement gets a smooth
* feeling.
*/
private void moveCamera() {
SimpleVector oldCamPos=camera.getPosition();
SimpleVector oldestCamPos=new SimpleVector(oldCamPos);
oldCamPos.scalarMul(9f);
SimpleVector carCenter=car.getTransformedCenter();
SimpleVector camPos=new SimpleVector(carCenter);
SimpleVector zOffset=car.getZAxis();
SimpleVector yOffset=new SimpleVector(0, -100, 0);
zOffset.scalarMul(-250f);
camPos.add(zOffset);
camPos.add(yOffset);
camPos.add(oldCamPos);
camPos.scalarMul(0.1f);
SimpleVector delta=camPos.calcSub(oldestCamPos);
float len=delta.length();
if (len!=0) {
/**
* Do a collision detection between the camera and the ground to prevent the camera from
* moving into the ground.
*/
theWorld.checkCameraCollisionEllipsoid(delta.normalize(), new SimpleVector(20, 20, 20), len, 3);
}
/**
* And finally: Look at the car
*/
camera.lookAt(car.getTransformedCenter());
}
/**
* Generates and/or move existing bullets
*/
private void processProjectiles() {
if (fire||fireCount!=3) {
fireCount--;
if (fireCount==0) {
bulMan.createBullet(car);
fireCount=3;
}
}
bulMan.moveBullets();
}
/**
* This is the game's main loop. We are doing some additional setup work here and
* rendering the scene in a loop, as well as handling the movement
* and the collision detection before each frame.
*/
private void gameLoop() {
World.setDefaultThread(Thread.currentThread());
buffer=new FrameBuffer(width, height, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.enableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.setBoundingBoxMode(FrameBuffer.BOUNDINGBOX_NOT_USED);
buffer.optimizeBufferAccess();
Timer timer=new Timer(25);
timer.start();
Timer fpsTimer=new Timer(1000);
fpsTimer.start();
while (!exit) {
if (!isIdle) {
long ticks=timer.getElapsedTicks();
for (int i=0; i<ticks; i++) {
moveCar();
processProjectiles();
moveCamera();
}
poll();
if (switchMode!=0) {
switchOptions();
}
buffer.clear();
theWorld.renderScene(buffer);
if (!wireframe) {
theWorld.draw(buffer);
}
else {
theWorld.drawWireframe(buffer, Color.white);
}
buffer.update();
display();
fps++;
pps+=theWorld.getVisibilityList().getSize();
if (fpsTimer.getElapsedTicks()>0) {
totalFps=(fps-lastFps);
lastFps=fps;
lastPps=pps;
pps=0;
}
Thread.yield();
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {}
}
}
if (!openGL && fullscreen) {
device.setFullScreenWindow(null);
}
System.exit(0);
}
/**
* This is for switching settings. Currently, only switching from OpenGL to software and
* back is supported here. This is done to avoid switching modes while polling the keyboard,
* because it may have undesired side-effects otherwise.
*/
private void switchOptions() {
switch (switchMode) {
case (SWITCH_RENDERER): {
isIdle=true;
if (buffer.usesRenderer(IRenderer.RENDERER_OPENGL)) {
keyMapper.destroy();
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.enableRenderer(IRenderer.RENDERER_SOFTWARE, IRenderer.MODE_OPENGL);
openGL=false;
if (fullscreen) {
device.setFullScreenWindow(null);
}
frame.hide();
frame.dispose();
initializeFrame();
} else {
frame.hide();
buffer.enableRenderer(IRenderer.RENDERER_OPENGL, IRenderer.MODE_OPENGL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
openGL=true;
keyMapper.destroy();
keyMapper=new KeyMapper();
}
isIdle=false;
break;
}
}
switchMode=0;
}
/**
* Use the KeyMapper to poll the keyboard
*/
private void poll() {
KeyState state=null;
do {
state=keyMapper.poll();
if (state!=KeyState.NONE) {
keyAffected(state);
}
} while (state!=KeyState.NONE);
}
private void keyAffected(KeyState state) {
int code=state.getKeyCode();
boolean event=state.getState();
switch (code) {
case (KeyEvent.VK_ESCAPE): {
exit=event;
break;
}
case (KeyEvent.VK_LEFT): {
left=event;
break;
}
case (KeyEvent.VK_RIGHT): {
right=event;
break;
}
case (KeyEvent.VK_UP): {
forward=event;
break;
}
case (KeyEvent.VK_SPACE): {
fire=event;
break;
}
case (KeyEvent.VK_DOWN): {
back=event;
break;
}
case (KeyEvent.VK_W): {
if (event) {
wireframe=!wireframe;
}
break;
}
case (KeyEvent.VK_X): {
if (event) {
switchMode=SWITCH_RENDERER;
}
break;
}
}
}
/**
* The WindowApapter used for software mode
*/
private class WindowEvents extends WindowAdapter {
public void windowIconified(WindowEvent e) {
isIdle=true;
}
public void windowDeiconified(WindowEvent e) {
isIdle=false;
}
}
private class Timer {
private long ticks=0;
private long granularity=0;
public Timer(int granularity) {
this.granularity=granularity;
}
public void start() {
ticks=System.currentTimeMillis();
}
public void reset() {
start();
}
public long getElapsedTicks() {
long cur=System.currentTimeMillis();
long l=cur-ticks;
if (l>=granularity) {
ticks=cur-(l%granularity);
return l/granularity;
}
return 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -