📄 screenobjectpathfollower.java
字号:
turningAlongPath = true; return; } useEndingOrientationValue=false; stopMovement(); return; } // Next Point reached... prevPoint = getPosition(); nextPoint = (Point) path.elementAt( pathIndex ); updateAngularNode(); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ // MOVEMENT CONTROL /** To set a player's movement : movement from current position to the given point. */ public void moveTo( Point endPosition, WorldManager wManager ) { // why all rem? 'cause mob can get to a new map : we will reinit data when getting // out of tilemap if will enable this./* // Test if xPosition,yPosition is a valid point Point startPt = new Point( (int)xPosition, (int)yPosition ); if ( !AStarDouble.isValidStart(startPt) ) { Debug.signal(Debug.WARNING,this,"PathFollower : invalid start point"); // We reset the position WotlasLocation location = screenObject.getLocation(); // We search for a valid insertion point ScreenPoint pReset = null; if ( location.isRoom() ){ pReset = screenObject.getMyRoom().getInsertionPoint(); else { if ( location.isTown() ) { TownMap myTown = wManager.getTownMap( location ); if (myTown!=null) pReset = myTown.getInsertionPoint(); } else if ( location.isWorld() ) { WorldMap myWorld = wManager.getWorldMap( location ); if (myWorld!=null) pReset = myWorld.getInsertionPoint(); } } if (pReset==null) { pReset = new ScreenPoint(0, 0); Debug.signal(Debug.CRITICAL,this,"Could not find a valid start point !"); } else Debug.signal(Debug.NOTICE,this,"Found a new valid start point..."); screenObject.setX(pReset.x); screenObject.setY(pReset.y); startPt.x = pReset.x; startPt.y = pReset.y; } // path = findPath( startPt, new Point( endPosition.x, endPosition.y ),player.getLocation().isRoom() ); path = findPath( startPt, new Point( endPosition.x, endPosition.y ), screenObject.getLocation().isTileMap() ); if( path==null ) { if( walkingAlongPath ) stopMovement(); // a message is sent : we were moving... else resetMovement(); // no message sent : we were already still... return; // no movement } updateMovementAspect(); initMovement( path ); if( screenObject.isTheServerSide() ) if( screenObject instanceof NpcOnTheScreen) ((NpcOnTheScreen)screenObject).getRouter().sendMessage( new ScreenObjectPathUpdateMovementMessage( this, screenObject.getPrimaryKey() , screenObject.getSyncID()),null, MessageRouter.EXTENDED_GROUP ); */ System.out.println(" diego_mov!"); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /** To rotate the player on itself. * @param finalOrientation final orientation to reach */ public void rotateTo( double finalOrientation ) { orientationAngle = finalOrientation; if( screenObject.isTheServerSide() ) if( screenObject instanceof NpcOnTheScreen) ((NpcOnTheScreen)screenObject).getRouter().sendMessage( new ScreenObjectPathUpdateMovementMessage( this, screenObject.getPrimaryKey() , screenObject.getSyncID()),null, MessageRouter.EXTENDED_GROUP ); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /** To recreate a trajectory from a dest. point & a DeltaTime. */ public void recreateTrajectory( Point pDst, int movementDeltaTime ) { path = findPath( new Point( (int)xPosition, (int)yPosition ), new Point( pDst.x, pDst.y ), screenObject.getLocation().isTileMap() ); if( path==null ) { Debug.signal( Debug.ERROR, this, "Failed to re-create path !" ); if( screenObject.isTheServerSide() ) stopMovement(); else resetMovement(); return; } updateMovementAspect(); if(movementDeltaTime>500) initMovement( path, movementDeltaTime ); else initMovement( path ); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /** Initialize a path movement from the start. This is the most method you should * use the most. This method modifies the entire state of the PathFollower. * To test if the movement is finished, call the isMoving method after each tick. * * @param path a valid path returned by the Astar algorithm. */ synchronized public void initMovement( List path ) { // 1 - Control if( path==null || path.size()<1 ) { Debug.signal(Debug.ERROR, this, "Invalid Path !!!! "+path); return; } // 2 - Path Inits this.path = path; pathIndex = 1; lastUpdateTime = System.currentTimeMillis(); movementTimeStamp = lastUpdateTime; prevPoint = getPosition(); nextPoint = (Point) path.elementAt(pathIndex); updateAngularNode(); // 3 - We validate the movement... walkingAlongPath = true; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /** Given a path followed by a player (1) and an elapsed time since the movement begun (2) * we initialize our path movement at the computed "current" position. * * The "current" position is totaly dependent from the speed at which we move. So be * sure to correctly initialize the PathFollower's speed BEFORE calling this method. * * @param path current path followed by a player. * @param deltaTime deltaTime in ms since the player begun to follow the path (starting * at the first point given in the path parameter) */ synchronized public void initMovement( List path, int deltaTime ) { // 1 - Control if(path==null || path.size()<1 ) { resetMovement(); Debug.signal(Debug.ERROR, this, "Invalid Path !!!! "+path); return; } if(path.size()==1) { resetMovement(); return; // no movement } this.path = path; // 2 - Position evaluation float totalDistance = (deltaTime/1000.0f)*speed; double d = 0.0f; Point a0 = null; Point a1 = (Point)path.elementAt(0); for( int i=0; i<path.size()-1; i++ ) { a0 = a1; a1 = (Point)path.elementAt(i+1); d += distance( a0, a1 ); // have we found the last point crossed by our entity ? if( d >= totalDistance ) { // Path approved ! this.path = path; pathIndex = i; orientationAngle = angle( a0, a1 ); xPosition = (float)(a1.x - (d-totalDistance)*Math.cos(orientationAngle) ); yPosition = (float)(a1.y - (d-totalDistance)*Math.sin(orientationAngle) ); prevPoint = a0; nextPoint = a1; //(Point) path.elementAt(pathIndex); lastUpdateTime = System.currentTimeMillis(); movementTimeStamp = lastUpdateTime; updateAngularNode(); // We validate the movement walkingAlongPath = true; return; } } // 3 - If we arrive here it means that the movement is over ! // We set the PathFollower state to the end of the path a0 = (Point)path.elementAt(path.size()-2); a1 = (Point)path.elementAt(path.size()-1); orientationAngle = angle( a0, a1 ); xPosition = (float)a1.x; yPosition = (float)a1.y; if( screenObject.isTheServerSide() ) stopMovement(); else resetMovement(); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /** To update the angular movement at a Path node. */ private void updateAngularNode() { nextAngle = angle( prevPoint, nextPoint ); 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; if (realisticRotations) turningAlongPath = true; // we will turn progressively, using the angularSpeed else { turningAlongPath = false; orientationAngle = nextAngle; // We update the angle right now } } /*------------------------------------------------------------------------------------*/ /** Helper. Returns the distance between two points * @param a first point * @param b second point * @return distance between the two points. */ public static float distance( Point a, Point b ) { if(a==null || b==null) return 0f; return (float) Math.sqrt( (b.y-a.y)*(b.y-a.y)+(b.x-a.x)*(b.x-a.x) ); } /*------------------------------------------------------------------------------------*/ /** Helper. Returns the angle between the given line and the horizontal. * @param first point of the line * @param second point of the line * @return angle in radian in the [-pi,pi] range. */ public static float angle( Point a, Point b ) { if(b.x==a.x) { if(b.y>a.y) return (float) Math.PI/2; else if (b.y<a.y) return (float) -Math.PI/2; return 0.0f; } float angle = (float) Math.atan( (double)(b.y-a.y)/(b.x-a.x) ); if(b.x<a.x) { if(angle>=0) return (float) ( angle-Math.PI ); if(angle<0) return (float) ( angle+Math.PI ); } return angle; } /*------------------------------------------------------------------------------------*/ /** write object data with serialize. */ public void writeExternal(java.io.ObjectOutput objectOutput) throws java.io.IOException { objectOutput.writeInt( ExternalizeGetVersion() ); objectOutput.writeFloat( xPosition ); objectOutput.writeFloat( yPosition ); objectOutput.writeLong( movementTimeStamp ); objectOutput.writeBoolean( walkingAlongPath ); objectOutput.writeDouble( orientationAngle ); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /** read object data with serialize. */ public void readExternal(java.io.ObjectInput objectInput) throws java.io.IOException, java.lang.ClassNotFoundException { int IdTmp = objectInput.readInt(); if( IdTmp == ExternalizeGetVersion() ){ xPosition = objectInput.readFloat(); yPosition = objectInput.readFloat(); movementTimeStamp = objectInput.readLong(); walkingAlongPath = objectInput.readBoolean(); orientationAngle = objectInput.readDouble(); } else { // to do.... when new version } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /** id version of data, used in serialized persistance. */ public int ExternalizeGetVersion(){ return 1; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -