2013-07-11 10 views
6

Entschuldigung, wenn dieser Titel nicht sehr beschreibend ist. Jedenfalls arbeite ich an etwas, das sich mit zufällig erzeugten Landschaften beschäftigt. Ich habe Seen gemacht, aber aufgrund der Art, wie sie gemacht werden, verursachen sie oft gerade Kanten/Rücksprünge, was nicht wünschenswert ist. Ich versuche, es zu glätten (direkt nach der Herstellung des Sees, wenn möglich), indem ich einen maximalen Variationsbetrag definiere (so dass Landhöhen nicht mehr variieren können), und lasse das Land reparieren, wenn es zu stark variiert, und beende es fein.Glättendes Land um Seen

Das Problem:

Large dropoff

Mein versucht fix:

Attempted fix

Wie Sie sehen können ... es hat nicht funktioniert. Es kommt mir auch in den Sinn, ich denke, es wäre kaputt, wenn es nach unten gehen müsste, obwohl dieser Fall eigentlich nicht vorkommen sollte, weil Seen nur die Landschaft versenken. Wie auch immer, hier ist die Quelle meines Versuchs:

//smoothing land nearby 

      int maxVariation = 2; //similar to the max height variation when the land is generated 

      //going right 



      for (int xPos = rightBound + 1, previousHeight = 0; ; ++xPos) 
      { 
       if (previousHeight == 0) 
        for (; previousHeight < size.y; ++previousHeight) 
         if (grid[0][rightBound][previousHeight] != BlockColor::DIRT && grid[0][rightBound][previousHeight] != BlockColor::GRASS) 
         { 
          --previousHeight; 

          break; 
         } 


       for (int y = 0; y < size.y; ++y) 
        if (grid[0][xPos][y] == BlockColor::WATER) 
         goto done_smoothing_right; 

       int height; 

       for (height = 0; height < size.y; ++height) 
        if (grid[0][xPos][height] != BlockColor::DIRT && grid[0][xPos][height] != BlockColor::GRASS) 
        { 
         --height; 

         break; 
        } 

        int difference = std::abs(height - previousHeight); 

        previousHeight = height; 

        if (difference > maxVariation) 
        { 
         for (int j = 0; j < size.y; ++j) 
         { 
          int toMove = difference; 

          while (j + toMove >= size.y) 
           --toMove; 

          grid[0][xPos][j] = grid[0][xPos][j + toMove]; 
         } 
        } 
        else 
         goto done_smoothing_right; 


      } 

done_smoothing_right: 

      int tomakegotowork; 

Beachten Sie, dass nur die rechte Seite ist, sollte aber in etwa gleich bleiben. Wie kann ich das richtig machen?

Danke, wenn Sie helfen können.

EDIT:

Ich habe dieses Problem nie gelöst. Stattdessen machte ich eine rekursive Funktion, um Luft zu messen (ab einer bestimmten Höhe), und wenn eine Lufttasche (die vom Land gebildet wurde) genug hatte, um sich mit Wasser zu füllen. Dies hat den Vorteil, dass das Land glatt aussieht, da es nicht verändert wird.

+0

rightBound der rightBound der ist See? Gibt es Seen nur in der Höhe 0? –

+0

@MikeSaull Ja, rightBound ist das x des am weitesten rechts liegenden Wassers. Seen treten nicht nur bei 0 auf, sondern mit der aktuellen Landhöhe und Seetiefe sieht es auch so aus. –

Antwort

1

Dies ist in Java geschrieben, so dass Sie es in C++ konvertieren müssen, aber es sollte Ihnen die Grundidee geben. Es wird nur funktionieren, um nach oben zu glätten und ich habe nur die rechte Seite des Sees gemacht, aber es ist sehr einfach, sie für die linke Seite des Sees zu modifizieren. Ich habe versucht, die Funktionalität meines Codes zu finden.

Hoffe, es hilft ...

void smoothLakeRight(Lake lake){ 

    int x = lake.rightBound+1; 

    if(getGrassHeight(x)-lake.height>WorldConstants.MAX_LAKESIDE_VARIATION){ 
     //if the right bank is too high start smoothing 
     int y =lake.height+WorldConstants.MAX_LAKESIDE_VARIATION; 

     while(grid[0][x][y] == BlockColor.DIRT){ 
      fixGrass(x++, y++); 
     } 
    } 
} 

private int getGrassHeight(int xPos){ 

    int y = WorldConstants.LOWEST_GRASS; 

    while(grid[0][xPos][y++] != BlockColor.GRASS); 

    return y-1; 
} 

private void fixGrass(int xPos, int yPos){ 

    grid[0][xPos][yPos] = BlockColor.GRASS; 

    aboveAir(xPos,yPos); 
    belowDirt(xPos, yPos); 

} 

private void aboveAir(int xPos, int yPos) { 

    while(grid[0][xPos][++yPos]!=BlockColor.AIR){ 
     if(grid[0][xPos][yPos]==BlockColor.TREE){ 
      upRootTree(xPos, yPos); 
     }else{ 
      grid[0][xPos][yPos]=BlockColor.AIR; 
     } 
    } 
} 

private void upRootTree(int xPos, int yPos) { 

    while(grid[0][xPos][yPos]==BlockColor.TREE){//remove stump 
     grid[0][xPos][yPos++]=BlockColor.AIR; 
    } 

    //remove leaves 
    grid[0][xPos][yPos] = BlockColor.AIR; 
    grid[0][xPos+1][yPos] = BlockColor.AIR; 
    grid[0][xPos-1][yPos] = BlockColor.AIR; 
    grid[0][xPos+1][yPos-1] = BlockColor.AIR; 
    grid[0][xPos-1][yPos-1] = BlockColor.AIR; 
} 

private void belowDirt(int xPos, int yPos) { 

    while(grid[0][xPos][--yPos]!=BlockColor.DIRT){ 
     grid[0][xPos][yPos] = BlockColor.DIRT; 
    } 
}