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

📄 cartest.java

📁 Java 3D API, 一套完整的3d引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
      }
   }

   /**
    * 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 + -