import java.awt.event.*; import javax.media.opengl.*; import java.util.*; public class World implements GLEventListener, KeyListener { private GL gl; // the local tank Tank local_tank = null; // used to compute the time spent in a draw loop double lastTime = -1; public World() { local_tank = new Tank(); } public void init(GLAutoDrawable drawable) { gl = drawable.getGL(); gl.glEnable(GL.GL_CULL_FACE); gl.glEnable(GL.GL_DEPTH_TEST); } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { float h = (float)height / (float)width; gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 6000.0f); gl.glMatrixMode(GL.GL_MODELVIEW); } public void display(GLAutoDrawable drawable) { gl.glClearColor(0.3f, 0.3f, 0.99f, 1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // compute the time spent in between two calls Date date = new Date(); double time = date.getTime() / 1000.0; if (lastTime != -1) { // unpdates the local tank local_tank.update(time - lastTime); } lastTime = time; // loads the view matrix gl.glLoadIdentity(); // this is to take care of the tank modelisation gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); // allows for the tank to be seen from a bit behind and over gl.glTranslatef(20.f, -4.f, 0.0f); // follow the tank gl.glRotatef(-(float)local_tank.currentAngle, 0.0f, 1.0f, 0.0f); gl.glTranslatef(-local_tank.x, -local_tank.y, -local_tank.z); // draw the tank local_tank.draw(gl); // draw the floor drawFloor(); // draw the pyramids drawScenery(); } public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void keyPressed(KeyEvent evt) { switch (evt.getKeyCode()) { case KeyEvent.VK_ESCAPE: System.exit (0); break; case KeyEvent.VK_LEFT: // left turns the tanks 2 degrees towards the left local_tank.rotate(2.0); System.out.println("Left"); break; case KeyEvent.VK_RIGHT: // right turns the tanks 2 degrees towards the right local_tank.rotate(-2.0); System.out.println("Right"); break; case KeyEvent.VK_UP: // up increases the velocity local_tank.setVelocity(local_tank.getVelocity() + 10); System.out.println("Up"); break; case KeyEvent.VK_DOWN: // down decreases the velocity local_tank.setVelocity(local_tank.getVelocity() - 10); System.out.println("Down"); break; case KeyEvent.VK_SPACE: // space stops the tank local_tank.setVelocity(0); System.out.println("Space"); break; } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } // draw the floor private void drawFloor() { gl.glBegin(GL.GL_QUADS); gl.glColor3f(0.3f, 0.7f, 0.3f); gl.glVertex3f(-1000.0f, 0.0f, 1000.0f); gl.glVertex3f( 1000.0f, 0.0f, 1000.0f); gl.glVertex3f( 1000.0f, 0.0f, -1000.0f); gl.glVertex3f(-1000.0f, 0.0f, -1000.0f); gl.glEnd(); } // draw the pyramids private void drawScenery() { for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { gl.glPushMatrix(); gl.glTranslatef(i*200.f - 900.f, 5.f, j*200.f - 1000.f); gl.glScalef(10.f, 10.f, 10.f); gl.glColor3f(((float)i) / 10.0f, ((float)j) / 10.0f, ((float)i+j) / 20.0f); gl.glBegin(GL.GL_TRIANGLES); gl.glVertex3f(0.0f, 1.0f, 0.0f); //Top Of Triangle (Front) gl.glVertex3f(-1.0f, -1.0f, 1.0f); //Left Of Triangle (Front) gl.glVertex3f(1.0f, -1.0f, 1.0f); //Right Of Triangle (Front) gl.glVertex3f(0.0f, 1.0f, 0.0f); //Top Of Triangle (Right) gl.glVertex3f(1.0f, -1.0f, 1.0f); //Left Of Triangle (Right) gl.glVertex3f(1.0f, -1.0f, -1.0f); //Right Of Triangle (Right) gl.glVertex3f(0.0f, 1.0f, 0.0f); //Top Of Triangle (Back) gl.glVertex3f(1.0f, -1.0f, -1.0f); //Left Of Triangle (Back) gl.glVertex3f(-1.0f, -1.0f, -1.0f); //Right Of Triangle (Back) gl.glVertex3f(0.0f, 1.0f, 0.0f); //Top Of Triangle (Left) gl.glVertex3f(-1.0f, -1.0f, -1.0f); //Left Of Triangle (Left) gl.glVertex3f(-1.0f, -1.0f, 1.0f); //Right Of Triangle (Left) gl.glEnd(); gl.glPopMatrix(); } } } }