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

📄 astardouble.java

📁 Vyger offers a D & D and Rogue-like environment in a graphical online roleplay game.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    // Correct the position
    if (x+SPRITE_SIZE<mapWidth) {
      if (isNotBlock(x+SPRITE_SIZE,y)) {
        if (SHOW_DEBUG)
          System.out.print("change x+");
        pointGoal.x += SPRITE_SIZE;
        return true;
      }
    }
    if ((x+SPRITE_SIZE<mapWidth) && (y+SPRITE_SIZE<mapHeight)) {
      if (isNotBlock(x+SPRITE_SIZE,y+SPRITE_SIZE)) {
        if (SHOW_DEBUG)
          System.out.print("change x+ y+");
        pointGoal.x += SPRITE_SIZE;
        pointGoal.y += SPRITE_SIZE;
        return true;
      }
    }
    if (y+SPRITE_SIZE<mapHeight) {
      if (isNotBlock(x,y+SPRITE_SIZE)) {
        if (SHOW_DEBUG)
          System.out.print("change y+");
        pointGoal.y += SPRITE_SIZE;
        return true;
      }
    }
    if ((x>SPRITE_SIZE) && (y+SPRITE_SIZE<mapHeight)) {
      if (isNotBlock(x-SPRITE_SIZE,y+SPRITE_SIZE)) {
        if (SHOW_DEBUG)
          System.out.print("change x- y+");
        pointGoal.x -= SPRITE_SIZE;
        pointGoal.y += SPRITE_SIZE;
        return true;
      }
    }
    if (x>SPRITE_SIZE) {
      if (isNotBlock(x-SPRITE_SIZE,y)) {
        if (SHOW_DEBUG)
          System.out.print("change x-");
        pointGoal.x -= SPRITE_SIZE;
        return true;
      }
    }
    if ((x>SPRITE_SIZE) && (y>SPRITE_SIZE)) {
      if (isNotBlock(x-SPRITE_SIZE,y-SPRITE_SIZE)) {
        if (SHOW_DEBUG)
          System.out.print("change x- y-");
        pointGoal.x -= SPRITE_SIZE;
        pointGoal.y -= SPRITE_SIZE;
        return true;
      }
    }
    if (y>SPRITE_SIZE) {
      if (isNotBlock(x,y-SPRITE_SIZE)) {
        if (SHOW_DEBUG)
          System.out.print("change y-");
        pointGoal.y -= SPRITE_SIZE;
        return true;
      }
    }
    if ((x+SPRITE_SIZE<mapWidth) && (y>SPRITE_SIZE)) {
      if (isNotBlock(x+SPRITE_SIZE,y-SPRITE_SIZE)) {
        if (SHOW_DEBUG)
         System.out.print("change x+ y-");
        pointGoal.x += SPRITE_SIZE;
        pointGoal.y -= SPRITE_SIZE;
        return true;
      }
    }

    return false;
  }

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

  /**
   * test if a point (in CELL units) is a valid start,
   * and correct the position regarding the sprite size
   *
   * @param pointGoal the point (in CELL units)
   * @return true if point is valid (not blocked) in the {@link #mask mask}
   */
  static public boolean isValidStart(Point pointGoal) {
    return aStar.isValid(pointGoal);
  }

  /**
   * test if a point (in pixels coordinate) is a valid start.
   * If it's an invalid point, search a valid point near it,
   * and correct the position regarding the sprite size
   *
   * @param pointGoal the point
   * @return true if point is valid or has been corrected, false otherwise
   */
  private boolean isValid(Point pointGoal) {
    // We search up to 3 pixels around the original point
    int radius = 3;

    int x = pointGoal.x/tileSize;
    int y = pointGoal.y/tileSize;

    if (isNotBlock(x,y)) {
      //if (SHOW_DEBUG)
      //  System.out.println("valid point");
      return true;
    } else {
      //if (SHOW_DEBUG)
      //  System.out.println("not a valid point -> search a valid point");
      Debug.signal( Debug.NOTICE, null, "not a valid start point -> search a valid point");  
      //Debug.signal( Debug.NOTICE, null, "  x = " + x + " ,  y = " + y);
    }

    // test if player is near border
    if (x+SPRITE_SIZE>mapWidth) {
      if (SHOW_DEBUG)
        System.out.println("test x near border");
      if (map[x-SPRITE_SIZE-1][y]) {
        if (SHOW_DEBUG)
          System.out.print("player near border -> change x=mapWidth-SPRITE_SIZE-1");
        pointGoal.x = mapWidth-SPRITE_SIZE-1;
        return true;
      }
    }
    if (y+SPRITE_SIZE>mapHeight) {
      if (SHOW_DEBUG)
        System.out.println("test y near border");
      if (map[x][mapHeight-SPRITE_SIZE-1]) {
        if (SHOW_DEBUG)
          System.out.print("player near border -> change y=mapHeight-SPRITE_SIZE-1");
        pointGoal.y = mapHeight-SPRITE_SIZE-1;
        return true;
      }
    }

    // We search a valid point around the original point

    //pointGoal.y = y-1;
    if (isNotBlock(x,y-1)) {pointGoal.y-=tileSize;return true;}
    //pointGoal.y = y+1;
    if (isNotBlock(x,y+1)) {pointGoal.y+=tileSize;return true;}

    //pointGoal.x = x-1;
    //pointGoal.y = y-1;
    if (isNotBlock(x-1,y-1)) {pointGoal.x-=tileSize;pointGoal.y-=tileSize;return true;}
    //pointGoal.y = y+1;
    if (isNotBlock(x-1,y+1)) {pointGoal.x-=tileSize;pointGoal.y+=tileSize;return true;}

    //pointGoal.x = x+1;
    //pointGoal.y = y-1;
    if (isNotBlock(x+1,y-1)) {pointGoal.x+=tileSize;pointGoal.y-=tileSize;return true;}
    //pointGoal.y = y+1;
    if (isNotBlock(x+1,y+1)) {pointGoal.x+=tileSize;pointGoal.y+=tileSize;return true;}

    //pointGoal.x = x-2;
    //for (pointGoal.y=y-2;pointGoal.y<y+3;y++) {
    for (int step=-2;step<3;step++) {
      if (isNotBlock(x-2,y+step)) {
        pointGoal.x-=2*tileSize;
        pointGoal.y+=step*tileSize;
        return true;
      }
    }

    //for (pointGoal.x=x-1;pointGoal.x<x+2;x++) {
    for (int step=-1;step<2;step++) {
      //pointGoal.y=y-2;
      if (isNotBlock(x+step,y-2)) {
        pointGoal.x+=step*tileSize;
        pointGoal.y-=2*tileSize;
        return true;
      }
      //pointGoal.y=y+2;
      if (isNotBlock(x+step,y+2)) {
        pointGoal.x+=step*tileSize;
        pointGoal.y+=2*tileSize;
        return true;
      }
    }

    //pointGoal.x = x+2;
    //for (pointGoal.y=y-2;pointGoal.y<y+3;y++) {
    for (int step=-2;step<3;step++) {
      if (isNotBlock(x+2,y+step)) {
        pointGoal.x+=2*tileSize;
        pointGoal.y+=step*tileSize;
        return true;
      }
    }

    return false;
  }

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

  /**
   * Generates all the not blocked children of a Node
   *
   * @param p Node.point
   * returns a Vector of child Points of the point "p"
   */
  private List generateChildren(Point p) {
    List listChildren = new List(8);
    int x = p.x;
    int y = p.y;
    if (isNotBlock(x,y-1))   {listChildren.addElement(new Point(x,y-1));}
    if (isNotBlock(x+1,y))   {listChildren.addElement(new Point(x+1,y));}
    if (isNotBlock(x,y+1))   {listChildren.addElement(new Point(x,y+1));}
    if (isNotBlock(x-1,y))   {listChildren.addElement(new Point(x-1,y));}
    if (isNotBlock(x-1,y-1)) {listChildren.addElement(new Point(x-1,y-1));}
    if (isNotBlock(x-1,y+1)) {listChildren.addElement(new Point(x-1,y+1));}
    if (isNotBlock(x+1,y+1)) {listChildren.addElement(new Point(x+1,y+1));}
    if (isNotBlock(x+1,y-1)) {listChildren.addElement(new Point(x+1,y-1));}
    return listChildren;
  }

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

  /**
   * Finds the optimal path between 2 points.
   *
   * @param pointStart baginning of the path (in CELL units)
   * @param pointGoal end of the path (in CELL units)
   */
  static public List findPath(Point pointStart, Point pointGoal) {
    if (SHOW_DEBUG)
      System.out.println("AStarDouble::findPath");

    if (aStar==null)
      aStar=new AStarDouble();

    //if ( (!isNotBlock(pointStart.x, pointStart.y)) || (!isNotBlock(pointGoal.x, pointGoal.y)) )

    if (SHOW_DEBUG)
      System.out.print(pointGoal);
    if ( (!aStar.isValidGoal(pointGoal)) ) {
      if (SHOW_DEBUG)
        System.err.println("error : invalid point");
      return null;
    }
    if (SHOW_DEBUG)
      System.out.println(" -> " + pointGoal);

    NodeDouble solution = aStar.searchNode(pointStart, pointGoal);
    return aStar.getPath(solution);

  }

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

  /**
   * constructs the path from the start node to the node n
   */
  private List getPath(NodeDouble n) {
    List result;
    if (n == null) {
      result = new List();
    } else {
      result = getPath(n.parent);
      result.addElement(n.point);
    }
    return result;
  }

  /**
   * prints the AStar path
   */
  public String toString(List path) {
    Point pathPoint;
    String result = "";
    for (int i=0; i<path.size(); i++) {
      pathPoint = (Point) path.elementAt(i);
      result += "path["+i+"] = (" + pathPoint.x + "," + pathPoint.y + ")\n";
    }
    return result;
  }

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

  /**
   * initializes the array "map" with a BufferedImage
   */
  public void initMask(BufferedImage maskBuffImg, int myMapWidth, int myMapHeight)
  {
    mapWidth = myMapWidth;
    mapHeight = myMapHeight;
    map = null;
    map = new boolean[myMapWidth][myMapHeight];
    for (int i=0; i<myMapWidth; i++)
    {
      for (int j=0; j<myMapHeight; j++)
      {
        map[i][j] = (maskBuffImg.getRGB(i, j)==-1) ? false: true; // not blocked
      }
    }
  }

  /** To set the mask
   */
  static public void setMask( boolean mask[][] ) {
    if (aStar==null)
      aStar = new AStarDouble();
    map = mask;
    mapWidth = mask.length;
    mapHeight = mask[0].length;
  }

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

  static public List smoothPath(List path) {
    return aStar.smoothPath1(path);
  }

 /** SMOOTH PATH ALGO FROM GAMASUTRA **/

  /** To smooth a path.
   * @param path a previously created path via Astar
   * @return smoothed path...
   */
  public List smoothPath1( List path ) {
    if ( (path==null) || (path.size()<3) )
      return path;

    List smoothedPath = new List( path.size() );

    Point checkPoint = (Point) path.elementAt(0);
    int index = 1;

    smoothedPath.addElement( path.elementAt(0) ); // first point

    while ( index+1<path.size() )
      if ( walkable( checkPoint, (Point) path.elementAt(index+1) ) )
        index++; // no need for this point, we check the next one
      else {
        checkPoint = (Point) path.elementAt(index);
        smoothedPath.addElement( checkPoint  ); // point needed
        index++;
      }

    smoothedPath.addElement( path.elementAt(index) ); // end point
    return smoothedPath;
  }

  /** Returns true if we can walk directly from point A to point B.
   */
  private boolean walkable( Point a, Point b ) {
    float cosinus = 0;
    float sinus = 0;

    if ((a.x == b.x) && (a.y == b.y)) {
      return true;
    }

    // 1 - compute angle between the two points...
    if (b.x == a.x) {
      if (b.y>a.y) {
        cosinus = 0;
        sinus = 1;
        }
      else if (b.y<a.y) {
        cosinus = 0;
        sinus = -1;
        }
      //else angle = 0.0f;
    } else {
      double angle = Math.atan( (double) (b.y-a.y)/(b.x-a.x) );
      if (b.x<a.x) {
        cosinus = (float) -Math.cos(angle);
        sinus   = (float) -Math.sin(angle);
      } else {
        cosinus = (float) Math.cos(angle);
        sinus   = (float) Math.sin(angle);
      }
    }

    // 2 - check points along the path every 0.25 pixels...

    float rfin = (float) Math.sqrt( (b.y-a.y)*(b.y-a.y) + (b.x-a.x)*(b.x-a.x) );

    for ( float r=0.25f; r<rfin; r +=0.25f ) {
      if ( !isNotBlock( (int) (a.x+r*cosinus), (int) (a.y+r*sinus) ) ) {
        return false;
      }
    }

    return true; // success ! found valid path between these two points!
  }

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

  /** To dynamically modify the mask setting all pixels of a rectangle to a boolean value
   *
   * @param r the rectangle to fill (in screen pixels coordinate)
   * @param maskTileSize the CELL size (in pixel units)
   * @param value new value of the pixels
   */
  private synchronized void changeRectangle(Rectangle r, int maskTileSize, boolean value) {
    int cx = (int) (r.x/maskTileSize);
    int cy = (int) (r.y/maskTileSize);

    int cWidth = (int) (r.getWidth()/maskTileSize);
    if( cWidth==0 ) cWidth=1;

    int cHeight = (int) (r.getHeight()/maskTileSize);
    if( cHeight==0 ) cHeight=1;

    if (SHOW_DEBUG)
      System.out.println("cWidth = " + cWidth + " cHeight = " + cHeight);

    for (int i=0; i<cWidth; i++)
      for (int j=0; j<cHeight; j++)
        if(cx+i<map.length && cy+j<map[0].length)
           map[cx+i][cy+j] = value;
  }

  /** To dynamically modify the mask setting all pixels
   * of a rectangle to false
   *
   * @param r the rectangle to fill (in screen pixels coordinate)
   */
  static public void fillRectangle(Rectangle r) {
    aStar.changeRectangle(r, tileSize, false);
  }
  
  /** To dynamically modify the mask setting all pixels
   * of a rectangle to true
   *
   * @param r the rectangle to clean (in screen pixels coordinate)
   */
  static public void cleanRectangle(Rectangle r) {
    aStar.changeRectangle(r, tileSize, true);
  }

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

}

⌨️ 快捷键说明

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