That's a nice scrolling terrain you have there
Rather coincidentally, I did one of these too.
Press
W to toggle edge wrapping
Press
Enter to change the seed
Hold
Up or
down and then press:
S to change the scale of the terrain.
P to change the amount of points to calculate along it.
R to change the roughness.
And since this thread was brought up because of a lunar lander project:
Press
F to create a flat spot on the terrain to land on.
I was going to handle the collision next but I've got side-tracked (or rather, stopped being side-tracked) and got on with my main project.
However, all of the ponints that make up the terrain are stored in an array so it will be a very easy job to create a polygon collision mesh from them.
This is the terrain code. I've kept it separate so that it can be dropped into any project:
type tTerrain2D
width as float
points as float[]
seed as float
scale as float
roughness as float
wrap as integer
endtype
global terrain2D as tTerrain2D[]
function CreateTerrain2D( points, width#, roughness#, wrap, seed# )
if seed# <0 then seed# = timer()
SetRandomSeed(seed#)
displace# = 50.0
terrain2D.length = terrain2D.length + 1
t = terrain2D.length
terrain2D[t].width = width#
terrain2D[t].seed = seed#
terrain2D[t].roughness = roughness#
terrain2D[t].wrap = wrap
terrain2D[t].points.length = points
terrain2D[t].points[0] = random(-displace#, displace#)
if wrap
terrain2D[t].points[points] = terrain2D[t].points[0]
else
terrain2D[t].points[points] = random(displace#, displace#)
endif
newstep = points
repeat
for k = 0 to points-midpoint step newstep
midpoint = newstep>>1
displace( t, k+midpoint, midpoint, displace# )
next k
newstep = midpoint
displace# = displace# * roughness#
until newStep = 1
endfunction t
function displace( t, p, m, d# )
terrain2D[t].points[p] = (terrain2D[t].points[p-m] + terrain2D[t].points[p+m]) *0.5
inc terrain2D[t].points[p], random(0,d#*2)-d#
endfunction
function DrawTerrain( t, h#, s# )
s = makecolor( 192, 192, 192 )
b = MakeColor( 64, 64, 64 )
xStep# = terrain2D[t].width/terrain2D[t].points.length
for k = 1 to terrain2D[t].points.length
drawline( (k-1)*xStep#, h#-(terrain2D[t].points[k-1]*s#), k*xStep#, h#-(terrain2D[t].points[k]*s#), s, s)
drawline( (k)*xStep#, h#, k*xStep#, h#-(terrain2D[t].points[k]*s#), b, b)
next k
endfunction
function DeleteTerrain(t)
terrain2D.remove(t)
endfunction
function CreateTerrainFlatSpot( t, pos, width, height# )
if height#<0
totalHeight# = 0
for k = pos to pos+width
inc totalHeight#, terrain2D[t].points[k]
next k
avgHeight# = totalHeight#/(width+1)
else
avgHeight# = height#
endif
for k = pos to pos+width
terrain2D[t].points[k] = avgHeight#
next k
endfunction
function GetTerrainNearestPoint( t, p )
n = p/(display.dw/terrain2D[t].points.length)
endfunction n
function GetTerrainX( t, p )
x# = (terrain2D[t].width/terrain2D[t].points.length) * p
endfunction x#
And this the 'main' file used to call the terrain functions and provide user input:
// Project: TerrainGenerator2D
// Created: 2015-08-31
#include "../_libs/display.agc"
#include "terrain2D.agc"
initDisplay( VIRTUAL, 1024, 480 )
SetPrintSize(14)
global seed#
global points
global roughness#
global wrap
global scale#
seed# = 0
points = 128
roughness# = 0.5
wrap = 1
scale# = 4.0
t = CreateTerrain2D( points, display.dw, roughness#, wrap, seed# )
do
if GetUserInput(t)
DeleteTerrain(t)
realSeed# = seed#
if seed# = -1 then realSeed# = timer()
t = CreateTerrain2D( points, display.dw, roughness#, wrap, realSeed# )
endif
DrawTerrain( t, display.b, scale# )
print("Seed = " + str(realSeed#))
print("Points = " + str(points))
print("Roughness = " + str(roughness#))
print("Wrap = " + str(wrap))
print("Scale = " + str(scale#))
print("Points = " + str(terrain2D[t].points.length))
print("")
Sync()
loop
function GetUserInput(t)
if GetRawKeyState(38)
if GetRawKeyPressed(80)
points=points<<1
exitfunction 1
endif
if GetRawKeyState(82)
inc roughness#, 0.001
exitfunction 1
endif
if GetRawKeyState(83)
inc scale#, 0.01
exitfunction 1
endif
endif
if GetRawKeyState(40)
if GetRawKeyPressed(80)
if points > 2
points=points>>1
exitfunction 1
endif
endif
if GetRawKeyState(82)
dec roughness#, 0.001
exitfunction 1
endif
if GetRawKeyState(83)
dec scale#, 0.01
exitfunction 1
endif
endif
if GetRawKeyPressed(70)
CreateTerrainFlatSpot(t, random(0, terrain2D[t].points.length-10), random(3,10), -1)
DrawTerrain( t, display.b, scale# )
exitfunction 0
endif
if GetRawKeyPressed(87)
wrap = not wrap
exitfunction 1
endif
if GetRawKeyPressed(13)
seed# = random(0, 1000) * 0.1
exitfunction 1
endif
endfunction 0
Oops!
I forgot about this. You will need to drop my display set up in there too:
#constant VIRTUAL 0
#constant PERCENTAGE 1
type tDisplay
dw as integer
dh as integer
l as integer
t as integer
r as integer
b as integer
w as integer
h as integer
cx as integer
cy as integer
aspect as float
style as integer
endtype
global display as tDisplay
function initDisplay( style, x#, y# )
display.dw = x#
display.dh = y#
display.aspect = (display.dw*1.0)/(display.dh*1.0)
display.style = style
SetWindowSize( x#, y#, 0 )
if style = VIRTUAL
SetVirtualResolution( display.dw, display.dh )
else
SetDisplayAspect( display.aspect )
endif
display.l = GetScreenBoundsLeft()
display.r = GetScreenBoundsRight()
display.t = GetScreenBoundsTop()
display.b = GetScreenBoundsBottom()
display.w = display.r - display.l
display.h = display.b - display.t
display.cx = display.w * 0.5
display.cy = display.h * 0.5
SetScissor( display.l, display.t, display.r, display.b )
endfunction
If you are going to use this in a game then I would recommend using a different method to draw it.
AGK V2 user - Tier 1 (mostly)