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

📄 pathfollower.java

📁 Vyger offers a D & D and Rogue-like environment in a graphical online roleplay game.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

   /** To set the position from a Point.
    * @param p Point
    */
     public void setPosition( Point p ) {
        xPosition = (float) p.x;
        yPosition = (float) p.y;
     }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

   /** To get the current position as a Point.
    * @return current position
    */
     public Point getPosition() {
        return new Point( (int)xPosition, (int)yPosition );
     }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

   /** To get the target position of the current movement ( last point in the path ).
    * @return returns the target position, can be the current position if we are not moving...
    */
     public Point getTargetPosition() {
        if(path!=null && path.size()>0)
           return (Point)path.elementAt( path.size()-1 );

        if(endPoint!=null)
           return endPoint.toPoint();

        return new Point( -100, -100 ); // out of screen point
     }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** Returns true if we are moving
   */
    public boolean isMoving() {
       return walkingAlongPath;
    }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** To reset our movement along the path.
   */
    public void resetMovement() {
      walkingAlongPath = false;
      turningAlongPath = false;
      path = null;
      nextPoint = null;
      prevPoint = null;
      endPoint = null;
    }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** To stop our movement along the path.
   */
    public void stopMovement() {
      resetMovement();
      
      if(player.isMaster())
         player.sendMessage( new PathUpdateMovementMessage( this, player.getPrimaryKey(), player.getSyncID() ) );
    }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** To set if we want realistic rotations or not.
   * @param realisticRotations true if you want realistic rotations.
   */
     public void setRealisticRotations( boolean realisticRotations ) {
        this.realisticRotations = realisticRotations;
     }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** To get the movement's timeStamp.
   */
     public long getMovementTimeStamp() {
         return movementTimeStamp;
     }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** To set the movement's timeStamp.
   */
     public void setMovementTimeStamp( long movementTimeStamp ) {
         this.movementTimeStamp = movementTimeStamp;
     }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** To get an update message representing the current movement state.
   *  IMPORTANT : We don't set any primaryKey.
   *
   * @return a MovementUpdateMessage 
   */
     public MovementUpdateMessage getUpdate() {
         if(AStarDouble.isInitialized())
            return (MovementUpdateMessage) new PathUpdateMovementMessage( this, null, player.getSyncID() );
         else
            return (MovementUpdateMessage) new PathUpdateMovementMessage( this, player.getPrimaryKey(), player.getSyncID() );
     }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** To update the current movement.
   * @param updateMessage MovementUpdateMessage
   */
     public synchronized void setUpdate( MovementUpdateMessage updateMessage ) {
           if( !(updateMessage instanceof PathUpdateMovementMessage) ) {
               Debug.signal( Debug.ERROR, this, "Received bad update message :"+updateMessage.getClass());
               return;
           }

           PathUpdateMovementMessage msg = (PathUpdateMovementMessage) updateMessage;
           useEndingOrientationValue=false;

/* METHOD 1 : SIMPLE UPDATE : WE FORCE THE NEW POSITION

           xPosition = (float)msg.srcPoint.x;
           yPosition = (float)msg.srcPoint.y;
           orientationAngle = msg.orientationAngle;

           walkingAlongPath = msg.isMoving;

           if( walkingAlongPath ) {
               Point pDst = new Point( msg.dstPoint.x, msg.dstPoint.y );

               if (AStarDouble.isInitialized()) {
                  // Astar initialized, re-creating path
                     recreateTrajectory( pDst, msg.movementDeltaTime );
               }
               else {
                  // Astar not initialized, just saving data
                     endPoint = new ScreenPoint( pDst );
                     movementTimeStamp = System.currentTimeMillis();
                     reconstructTrajectory = true;
                     movementDeltaTime = msg.movementDeltaTime;
               }
           }
           else {
             // No movement
               resetMovement();
           }
*/

/* METHOD 2 : ADVANCED UPDATE : WE TEST THE NEW POSITION */

           if (!AStarDouble.isInitialized()) {
             // We just save the data
                xPosition = (float)msg.srcPoint.x;
                yPosition = (float)msg.srcPoint.y;
                orientationAngle = msg.orientationAngle;

                walkingAlongPath = msg.isMoving;

                if( walkingAlongPath ) {
                    endPoint = new ScreenPoint( msg.dstPoint.x, msg.dstPoint.y );
                    movementTimeStamp = System.currentTimeMillis();
                    reconstructTrajectory = true;
                    movementDeltaTime = msg.movementDeltaTime;
                }
                else
                    resetMovement(); // No movement
           }
           else
           {
             // AStar initialized
             // Do we have to consider this update ?
                boolean takeUpdate = false;

                if( walkingAlongPath ) {
                    Point target = getTargetPosition();

                    if( msg.isMoving ) {
                        if( distance( msg.srcPoint, getPosition() )>MAX_DISTANCE_DELAY ||
                            findPath( getPosition(), msg.dstPoint, player.getLocation().isRoom() )==null )
                            takeUpdate = true;
                        else
                            recreateTrajectory( msg.dstPoint, 0 );
                    }
                    else {
                      // no movement, we received the master replica's ending trajectory position
                        if( target.x!=msg.srcPoint.x || target.y!=msg.srcPoint.y
                    	    || distance( target, getPosition() )>MAX_DISTANCE_DELAY ) {
                    	    takeUpdate = true;
                    	}
                        else {
                          // save the final orientation for later
                            useEndingOrientationValue=true;
                            endingOrientation = msg.orientationAngle;
                        }
                    }
                }
                else if( !msg.isMoving && Math.abs(xPosition-msg.srcPoint.x)<=1
                         && Math.abs(yPosition-msg.srcPoint.y)<=1 ) {
                    // we turn on ourself
                       turningAlongPath = true;
                       useEndingOrientationValue = true;
                       nextAngle = msg.orientationAngle;
                       angularDirection = 1;

                       while( nextAngle-orientationAngle > Math.PI )
                              nextAngle = (float)(nextAngle-2*Math.PI);

                       while( nextAngle-orientationAngle < -Math.PI )
                              nextAngle = (float)(nextAngle+2*Math.PI);

                       if( orientationAngle > nextAngle )
                           angularDirection = -1;

                       path=null;
                }
                else
                    takeUpdate = true;

                if(!takeUpdate)
                   return;

             // Our update...
                xPosition = (float)msg.srcPoint.x;
                yPosition = (float)msg.srcPoint.y;
                orientationAngle = msg.orientationAngle;

                walkingAlongPath = msg.isMoving;

                if( walkingAlongPath )
                    recreateTrajectory( msg.dstPoint, msg.movementDeltaTime );
                else
                    resetMovement(); // No movement
           }
     }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** To update speed & rotations
   */
    private void updateMovementAspect() {
         realisticRotations = false; // default
         speed = 1.0f;             // default : very slow speed

         if( player==null || player.getLocation()==null )
             return;

         if ( player.getLocation().isRoom() )
              realisticRotations = true;

         speed = player.getBasicChar().getSpeed( player.getLocation() );
    }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** Our Tick method. Call this method regularly to update the position along the path.
   */
    public void tick() {
       if (AStarDouble.isInitialized()) {
          if(reconstructTrajectory) {
              if(endPoint!=null) 
                 recreateTrajectory( endPoint.toPoint(), movementDeltaTime );
              reconstructTrajectory = false;
          }
          else
              updatePathMovement();
       }
    }

 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /** Updates our movement along path.
   *  Method to call each tick to update the entity's position.
   *  This method does nothing if there is no current move.
   */
    private synchronized void updatePathMovement() {
       if(!turningAlongPath && !walkingAlongPath)
          return;

    // 1 - Time Update - Delta T 
       long now = System.currentTimeMillis();
       double deltaT = ( now-lastUpdateTime )/1000.0f;
       lastUpdateTime = now;

       if(deltaT>=0.8f) return; // SECURITY if a slow is encountered
       if(deltaT<0) return; // Date has been advanced

    // 2 - Orientation update
       if (turningAlongPath) {

        // Orientation update
           orientationAngle += angularDirection*deltaT*angularSpeed;

        // End of turn ?
           double deltaA = (nextAngle-orientationAngle)*angularDirection;

           if( deltaA<=0 ) {
                if(useEndingOrientationValue &&
                   ( path==null || pathIndex >= path.size() ) ) {
                   resetMovement(); // recreated trajectory ending by a rotation...
                   return;
                }

                turningAlongPath = false;
                orientationAngle = angle( getPosition(), nextPoint );
           }
           else if(deltaA>Math.PI/8)
                return; // no footsteps, the angle is to great, we just turn...
       }

    // 3 - Position Update
       if( path==null )
           return; // no path to follow we just have to turn on ourself

       xPosition = (float)(xPosition + speed*deltaT*Math.cos( orientationAngle ) );
       yPosition = (float)(yPosition + speed*deltaT*Math.sin( orientationAngle ) );

    // 4 - Have we reached the next point in the path ?
       float deltaD = distance( getPosition(), prevPoint ) - distance( nextPoint, prevPoint );

        if( deltaD >= 0 ) {
            pathIndex++;

         // Path end point reached ?
            if( pathIndex >= path.size() ) {
                xPosition = (float) nextPoint.x;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -