Qbasicnews.com
March 21, 2019, 06:39:58 PM
 Welcome, Guest. Please login or register. 1 Hour 1 Day 1 Week 1 Month Forever Login with username, password and session length
 Home Help Search Login Register
 Pages: [1]
 Author Topic: Terrain generator  (Read 1943 times)
red_Marvin
Na_th_an

Posts: 1509

 « on: July 31, 2004, 01:52:32 PM »

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

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
 Logged

/post]
 Pages: [1]