Made a small demo using voronoi tessellation to form random 2D map. Press spacebar to randomize the map. Combine this with an auto-tiling feature and you have random tile maps.
Changing the "areas" constant creates more points of reference for each terrain type, increasing the chance of islands and rivers.
Small update. Use the up/down arrow keys to increase/decrease the number of areas.
SetErrorMode(2)
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate(0, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
global tilesize = 8
#constant WIDTH = 1024/tilesize
#constant HEIGHT = 768/tilesize
#constant areas = 50
Type VoronoiPoint
x as integer
y as integer
terrain as integer
EndType
voronoi as VoronoiPoint[areas]
randomizeVoronoiPoints(voronoi)
dim map[WIDTH, HEIGHT] as integer
dud = createSprite(0)
setSpriteSize(dud, tilesize, tilesize)
maxPoints = 3
for x = 0 to WIDTH-1
for y = 0 to HEIGHT-1
map[x,y] = cloneSprite(dud)
setSpritePosition(map[x,y], x*tilesize, y*tilesize)
i = getNearestVoronoi(voronoi, x, y, maxPoints)
if voronoi[i].terrain = 0 then setSpriteColor(map[x,y], 0,0,255,255)
if voronoi[i].terrain = 1 then setSpriteColor(map[x,y], 0,255,0,255)
next y
next x
colors as integer[2]
colors[0] = makeColor(0, 0, 200)
colors[1] = makeColor(0,200,0)
do
for i = 0 to maxPoints
drawBox(voronoi[i].x*tilesize, voronoi[i].y*tilesize, voronoi[i].x*tilesize+tilesize, voronoi[i].y*tilesize+tilesize, colors[voronoi[i].terrain],colors[voronoi[i].terrain],colors[voronoi[i].terrain],colors[voronoi[i].terrain], 1)
next i
if getRawKeyPressed(32) = 1
randomizeVoronoiPoints(voronoi)
for x = 0 to WIDTH-1
for y = 0 to HEIGHT-1
i = getNearestVoronoi(voronoi, x, y, maxPoints)
if voronoi[i].terrain = 0 then setSpriteColor(map[x,y], 0,0,255,255)
if voronoi[i].terrain = 1 then setSpriteColor(map[x,y], 0,255,0,255)
next y
next x
endif
if getRawKeyPressed(38) = 1
inc maxPoints
redrawMap(voronoi, maxPoints)
endif
if getRawKeyPressed(40) = 1
dec maxPoints
redrawMap(voronoi, maxPoints)
endif
if maxPoints < 2 then maxPoints = 2
if maxPoints > areas-1 then maxPoints = areas-1
print("Max Points: "+str(maxPoints+1))
print(screenfps())
sync()
loop
function redrawMap(v ref as VoronoiPoint[], maxPoints as integer)
for x = 0 to WIDTH-1
for y = 0 to HEIGHT-1
i = getNearestVoronoi(v, x, y, maxPoints)
if v[i].terrain = 0 then setSpriteColor(map[x,y], 0,0,255,255)
if v[i].terrain = 1 then setSpriteColor(map[x,y], 0,255,0,255)
next y
next x
endfunction
function randomizeVoronoiPoints(v ref as VoronoiPoint[])
for i = 0 to areas-1
v[i].x = random(0, WIDTH-1)
v[i].y = random(0, HEIGHT-1)
v[i].terrain = random(0, 1)
next i
endfunction
function getNearestVoronoi(v ref as VoronoiPoint[], x, y, max)
d = 9999999
nearest = -1
if max > areas-1 then max = areas-1
for i = 0 to max
g = (v[i].x-x)^2 + (v[i].y-y)^2
if g < d
d = g
nearest = i
endif
next i
endfunction nearest
More examples here:
http://zimnox.com/voronoi/