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

📄 jpctdemo.java

📁 Java 3D API, 一套完整的3d引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
         frame.createBufferStrategy(2);
         bufferStrategy=frame.getBufferStrategy();
         Graphics g=bufferStrategy.getDrawGraphics();
         bufferStrategy.show();
         g.dispose();
      } else {
         frame=new Frame();
         frame.setTitle("jPCT "+Config.getVersion());
         frame.pack();
         Insets insets = frame.getInsets();
         titleBarHeight=insets.top;
         leftBorderWidth=insets.left;
         frame.setSize(width+leftBorderWidth+insets.right, height+titleBarHeight+insets.bottom);
         frame.setResizable(false);
         frame.show();
         gFrame=frame.getGraphics();
      }

      /**
       * The listeners are bound to the AWT frame...they are useless in OpenGL mode.
       */
      frame.addWindowListener(new WindowEvents());
      keyMapper=new KeyMapper(frame);
   }

   /**
    * The fps counter is blitted into the rendered framebuffer here and the results
    * will be displayed (hence the name of the method...:-))
    */
   private void display() {
      blitNumber((int) totalFps, 5, 2);
      blitNumber((int) lastPps, 5, 12);

      if (!openGL) {
         if (!fullscreen) {
            buffer.display(gFrame, leftBorderWidth, titleBarHeight);
         } else {
            Graphics g=bufferStrategy.getDrawGraphics();
            g.drawImage(buffer.getOutputBuffer(), 0, 0, null);
            bufferStrategy.show();
            g.dispose();
         }
      } else {
         buffer.displayGLOnly();
      }
   }

   /**
    * 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 player.
    */
   private void doMovement() {

      /**
       * The first part handles the "physics", i.e. it allows the player to fall down.
       */

      SimpleVector camPos=camera.getPosition();
      camPos.add(new SimpleVector(0, PLAYER_HEIGHT/2f, 0));
      SimpleVector dir=new SimpleVector(0, GRAVITY, 0);
      dir=theWorld.checkCollisionEllipsoid(camPos, dir, ELLIPSOID_RADIUS, 1);
      camPos.add(new SimpleVector(0, -PLAYER_HEIGHT/2f, 0));
      dir.x=0;
      dir.z=0;
      camPos.add(dir);
      camera.setPosition(camPos);

      /**
       * The "falling" part of the player is now finished. Now we care for the horizontal movement.
       * Nothing special here and no problems either. One thing worth mentioning is, that the player is
       * always moving in the same plane regardless of where he's looking. playerDirection takes
       * care of this.
       */

      // forward and back may change during excution (threaded!), so we have to ensure to
      // reset the camera only if has been changed before.
      boolean cameraChanged=false;

      if (forward) {
         camera.moveCamera(new SimpleVector(0,1,0), PLAYER_HEIGHT/2f);
         cameraChanged=true;
         tempVector=playerDirection.getZAxis();
         theWorld.checkCameraCollisionEllipsoid(tempVector, ELLIPSOID_RADIUS, MOVE_SPEED, 5);
      }
      if (back) {
         if (!cameraChanged) {
            camera.moveCamera(new SimpleVector(0,1,0), PLAYER_HEIGHT/2f);
            cameraChanged=true;
         }
         tempVector=playerDirection.getZAxis();
         tempVector.scalarMul(-1f);
         theWorld.checkCameraCollisionEllipsoid(tempVector, ELLIPSOID_RADIUS, MOVE_SPEED, 5);
      }

      if (left) {
         camera.rotateAxis(camera.getBack().getYAxis(), -TURN_SPEED);
         playerDirection.rotateY(-TURN_SPEED);
      }
      if (right) {
         camera.rotateAxis(camera.getBack().getYAxis(), TURN_SPEED);
         playerDirection.rotateY(TURN_SPEED);
      }

      if (up) {
         camera.rotateX(TURN_SPEED);
      }
      if (down) {
         camera.rotateX(-TURN_SPEED);
      }

      if (cameraChanged) {
         camera.moveCamera(new SimpleVector(0, -1, 0), PLAYER_HEIGHT/2f);
      }
   }


   /**
    * Move the elevator up/down
    */
   private void moveElevator() {

      if ((elevator.wasTargetOfLastCollision()&&elevatorCountdown--<=0)||
          (elevatorPosition!=-90f&&elevatorPosition!=-180f)) {

         float tempElevator=elevatorPosition+elevatorOffset;
         float tempOffset=elevatorOffset;

         if (tempElevator<-180f) {
            tempOffset=-180f-elevatorPosition;
            elevatorCountdown=50;
            elevatorOffset*=-1f;
         } else {
            if (tempElevator>-90f) {
               tempOffset=-90f-elevatorPosition;
               elevatorCountdown=50;
               elevatorOffset*=-1f;
            }
         }
         elevatorPosition+=tempOffset;
         elevator.translate(0, tempOffset, 0);
      }
   }

   /**
    * Poll the keyboard using the KeyMapper from com.threed.jpct.util
    */
   private void poll() {
      KeyState state=null;
      do {
         state=keyMapper.poll();
         if (state!=KeyState.NONE) {
            keyAffected(state);
         }
      } while (state!=KeyState.NONE);
   }

   /**
    * 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 calling doMovement() to handle 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();

      long timerTicks=0;

      while (!exit) {

         if (!isIdle) {

            long ticks=timer.getElapsedTicks();
            timerTicks+=ticks;

            for (int i=0; i<ticks; i++) {
               /**
                * Do this as often as ticks have passed. This can
                * be improved by calling the method only once and letting
                * the collision detection somehow handle the ticks passed.
                */
                doMovement();
                moveElevator();
            }

            poll();

            if (switchMode!=0) {
               switchOptions();
            }

            buffer.clear();

            weapon.getTranslationMatrix().setIdentity();
            weapon.translate(camera.getPosition());
            weapon.align(camera);
            weapon.rotateAxis(camera.getDirection(), (float) Math.sin(timerTicks/6f)/20f);

            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) {}
         }
      }

      buffer.dispose();
      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.
    */
   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();
               keyMapper.destroy();
               buffer.enableRenderer(IRenderer.RENDERER_OPENGL, IRenderer.MODE_OPENGL);
               buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
               openGL=true;
               keyMapper=new KeyMapper();
            }
            isIdle=false;
            break;
         }
      }
      switchMode=0;
   }


   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_PAGE_UP): {
            up=event;
            break;
         }
         case (KeyEvent.VK_PAGE_DOWN): {
            down=event;
            break;
         }
         case (KeyEvent.VK_UP): {
            forward=event;
            break;
         }
         case (KeyEvent.VK_DOWN): {
            back=event;
            break;
         }
         case (KeyEvent.VK_1): {
            if (event&&buffer.supports(FrameBuffer.SUPPORT_FOR_RGB_SCALING)) {
               theWorld.getLights().setRGBScale(Lights.RGB_SCALE_DEFAULT);
            }
            break;
         }

         case (KeyEvent.VK_2): { // 2x scaling
            if (event&&buffer.supports(FrameBuffer.SUPPORT_FOR_RGB_SCALING)) {
               theWorld.getLights().setRGBScale(Lights.RGB_SCALE_2X);
            }
            break;
         }

         case (KeyEvent.VK_4): { // 4x scaling
            if (event&&buffer.supports(FrameBuffer.SUPPORT_FOR_RGB_SCALING)) {
               theWorld.getLights().setRGBScale(Lights.RGB_SCALE_4X);
            }
            break;
         }

         case (KeyEvent.VK_W): { // wireframe mode (w)
            if (event) {
               wireframe=!wireframe;
            }
            break;
         }

         case (KeyEvent.VK_X): { // change renderer  (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 + -