Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Terrain generator
#1
I'm testing a terrain generation method in qbasic for a game I plan to program in C++ later.

The trick is to make the terrain's left edge fit with the right seamlessly height/slopewise
and I think I've figured out a method that seems to work, however it would take too much space
to explain in the same post but I will later if you ask me to...

The thing I need help with is "k" the variable defining the maximum slope/steepness
- A terrain segment can't be more than k pixels higher or lower than the ones beside it.

For now, it works perfectly unless k=1 then the above "law"
is often broken Sad

Code:
RANDOMIZE TIMER
SCREEN 12
CONST screenw = 640
CONST screenh = 480
DIM mountains(0 TO screenw - 1)          ' raw mountain array
DIM hills(0 TO screenw - 1)              ' smoothed mountain array

FOR x = 0 TO screenw - 1                 ' -1 shows that the particular part
  mountains(x) = -1                      ' of the raw mountain is unprocessed
NEXT
'k = INT(RND * 9) + 2                     ' maximum steepness
k = 1                                   '<<< CAUSING ERRORS
min = 20 + INT(RND * 50)                 ' minimal height
max = screenh - (20 + INT(RND * 50))     ' maximal height
sv = INT(RND * 25) * 2 + 1               ' smoothing value

PRINT "Creating raw landscape  ";

s = 512                                  ' step
DO
  FOR x = 0 TO screenw - 1 STEP s
    IF mountains(x) = -1 THEN            ' if this particular mountain part
                                         ' is unprocessed...
  
    
    
'-----------------------------------------------------------------------------

      l = x - s                                   '\
      IF x - s < 0 THEN l = l + screenw           '  \
      r = x + s                                   '   | checking the height
      IF x + s > screenw - 1 THEN r = r - screenw '   > to the left and
      margin = k * s                              '   | right
      left = mountains(l)                         '  /
      right = mountains(r)                        '/

'-----------------------------------------------------------------------------

      SELECT CASE left
    
        CASE -1
          IF right = -1 THEN                 ' If both are -1
            high = max
            low = min
          ELSE                               ' If only left is -1
            high = right + margin
            low = right - margin
          END IF

        CASE ELSE
          SELECT CASE right

            CASE -1                          ' If only right is -1
              high = left + margin
              low = left - margin

            CASE IS < left                   ' If left > right
              high = right + margin
              low = left - margin
    
            CASE ELSE                        ' If right >= left
              high = left + margin
              low = right - margin
        END SELECT
      END SELECT
'-----------------------------------------------------------------------------
      IF high > max THEN high = max               ' making certain that the
      IF low < min THEN low = min                 ' values isn't out of bounds
      mountains(x) = INT(RND * (high - low)) + low' and setting the mountains
                                                  ' altitude
'-----------------------------------------------------------------------------
    END IF
  NEXT
  s = s \ 2                                     ' halving the step NOTE:
LOOP UNTIL s = 0                                ' INTEGER DIVISION: 1 \ 2 = 0
PRINT "FINISHED" + STRING$(2, 13) + "Smoothing landscape "
FOR x = 0 TO screenw - 1                        'smoothing
LOCATE 4: PRINT INT(x / screenw * 100); "%"     'status meter
sum = 0
  FOR p = -sv TO sv
    p2 = p
    IF x + p > screenw - 1 THEN p2 = p - screenw
    IF x + p < 0 THEN p2 = p + screenw

    sum = sum + mountains(x + p2)
  NEXT
  hills(x) = sum \ (sv * 2 + 1)
  
  
NEXT


CLS
FOR x = 0 TO screenw - 1
  LINE (x, screenh - 1)-(x, screenh - mountains(x)), 8
NEXT

maxdiff = 0
FOR x = 1 TO screenw - 1
  IF ABS(mountains(x) - mountains(x - 1)) > maxdiff THEN maxdiff = ABS(mountains(x) - mountains(x - 1))
NEXT
PRINT "k: "; k; "     l/r diff: "; ABS(mountains(0) - mountains(screenw - 1)); "     sv: "; sv
IF maxdiff > k THEN COLOR 4
PRINT "maxdiff: "; maxdiff; " (must be <= k or something's wrong)"
COLOR 15

LINE (0, screenh - 1 - max)-(screenw - 1, screenh - 1 - max), 1
LINE (0, screenh - 1 - min)-(screenw - 1, screenh - 1 - min), 4
SLEEP
CLS
FOR x = 0 TO screenw - 1
  LINE (x, screenh - 1)-(x, screenh - hills(x)), 8
NEXT
LINE (0, screenh - 1 - max)-(screenw - 1, screenh - 1 - max), 1
LINE (0, screenh - 1 - min)-(screenw - 1, screenh - 1 - min), 4

maxdiff = 0
FOR x = 1 TO screenw - 1
  IF ABS(hills(x) - hills(x - 1)) > maxdiff THEN maxdiff = ABS(hills(x) - hills(x - 1))
NEXT
PRINT "k: "; k; "     l/r diff: "; ABS(hills(0) - hills(screenw - 1)); "     sv: "; sv
IF maxdiff > k THEN COLOR 4
PRINT "maxdiff: "; maxdiff; " (must be <= k or something's wrong)"
COLOR 15

SLEEP
/post]
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)