I tried to make my map generation code make balanced maps. Here are 3 types of maps. 2 continents and 3 continents and islands. In strategy games you have not many fun options for creating the maps other then making them yourself using a editor. It takes a while sometimes to create the islands maps.
Code below :
Import mojo Const mapwidth:Int=640/16 Const mapheight:Int=480/16 Const tilewidth:Int=16 Const tileheight:Int=16 Global map:Int[mapwidth][] Global islandmap:Int[mapwidth][] Global numland:Int = 0 Global percland:Float = 1.7 Global remakecnt:Int=0 Global maptype:Int=2 Class Openlist Field x:Int, y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class MyGame Extends App Method OnCreate() SetUpdateRate(5) Seed = Millisecs() 'Set up the map array to be multi dimensional For Local i=0 Until mapwidth map[i] = New Int[mapheight] islandmap[i] = New Int[mapheight] Next ' make the map the first time makegamemap End Method Method OnUpdate() ' how much land must it have numoflandtiles </mapsize/percland remakecnt+=1 If remakecnt > 20 makegamemap() End If End Method Method OnRender() Cls 0,0,0 If remakecnt < 9 drawmap Local numislands=getnumberislands() SetColor 10,10,10 SetAlpha 0.6 DrawRect 0,0,200,numislands*15+15 SetAlpha 1 SetColor 255,255,255 DrawText "Different types of maps / 2 cont, 3 cont, islands.",0,0 For Local y=1 To numislands DrawText "Landmass "+y+" is "+getlandmass(y)+" tiles.",0,y*15 Next Else drawmap SetColor 255,255,255 If maptype < 4 Then DrawText "Please wait.... Generating "+maptype+" continents.",0,0 If maptype = 4 Then DrawText "Please wait.... Generating islands..",0,0 End If End Method End Class Function makegamemap:Void() Local exitloop:Bool=False While exitloop = False remakecnt=0 percland = Rnd(2.0,3.5) makemap makeislandmap If maptype = 4 And createislandsmap() = True Then exitloop = True If maptype = 3 And create3landmasses() = True Then exitloop = True If maptype = 2 And create2landmasses() = True Then exitloop = True Wend maptype+=1 If maptype > 4 Then maptype=2 End Function Function makeislandmap:Void() 'first clear the array For Local y=0 Until mapheight For Local x=0 Until mapwidth islandmap[x][y] = 0 Next Next ' create an open list Local openlist:List<Openlist> = New List<Openlist> Local currentisland:Int=0 ' loop through the array For Local y1=0 Until mapheight For Local x1=0 Until mapwidth ' if land tile and not indexed as island If map[x1][y1]>=5 And islandmap[x1][y1] = 0 currentisland+=1 openlist.Clear() 'move this position onto the openlist openlist.AddLast(New Openlist(x1,y1)) Local tx:Int=0, ty:Int=0 While openlist.IsEmpty() = False ' get a x,y value from the open list For Local i:=Eachin openlist tx = i.x ty = i.y openlist.Remove i Exit Next ' get 8 new positions For Local y2=-1 To 1 For Local x2=-1 To 1 Local x3:Int=tx+x2 Local y3:Int=ty+y2 If x3>=0 And y3>=0 And x3<mapwidth And y3<mapheight ' if land tile and not assisgned before a island If map[x3][y3]>=5 If islandmap[x3][y3] = 0 ' add to open list openlist.AddLast(New Openlist(x3,y3)) ' set current connected landmass islandmap[x3][y3] = currentisland End If End If End If Next Next Wend End If Next Next End Function Function drawmap:Void() For Local y=0 Until mapheight For Local x=0 Until mapwidth Local val:Int=map[x][y] ' tile 1,2,3,4 is sea If val<5 Then SetColor 0,0,val*10+100 ' tile 5 6 7 8 is grasslands/trees If val>=5 And val <9 Then SetColor 0,val*15,0 'tiles 9 10 11 12 13 is mountains If val>=9 Then SetColor val*15,val*4,0 ' draw the tile DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight Next Next End Function Function makemap:Void() numland=0 ' exit loop if conditions on land percentage is good While numland<(mapwidth*mapheight/percland) ' erase the old data For Local y=0 Until mapheight For Local x=0 Until mapwidth map[x][y] = 0 Next Next 'lowest hold the highest tile value Local lowest = 0 ' while land height is below 13 While lowest < 13 Local x1 = Rnd(mapwidth) Local y1 = Rnd(mapheight) ' create a radius for draw oval Local radius = Rnd(3,6) ' loop and create oval For Local y2=-radius To radius For Local x2=-radius To radius If ((x2*x2)+(y2*y2)) <= radius*radius+radius*0.8 Local x3 = x1+x2 Local y3 = y1+y2 If x3>=0 And y3>=0 And x3<mapwidth And y3<mapheight ' add current position with added older tile value map[x3][y3]=map[x3][y3]+1 ' if current value is higher then lowest loop value ' then store it in the loop exit variable If map[x3][y3] > lowest Then lowest = map[x3][y3] End If End If Next Next Wend 'Count the number of land tiles numland=0 For Local y=0 Until mapheight For Local x=0 Until mapwidth ' if the value is above 4 then add landtile counter If map[x][y] >= 5 Then numland+=1 Next Next Wend End Function Function createislandsmap:Bool() Local nislands:Int=getnumberislands() Local c:Int=0 If nislands<7 Then Return False For Local i=1 To nislands Local v:Int=getlandmass(i) If v>25 Then c+=1 Next If c>5 Then Return True Return False End Function Function create3landmasses:Bool() Local nislands:Int=getnumberislands() Local c:Int=0 If nislands<>3 Then Return False For Local i=1 To nislands Local v:Int=getlandmass(i) If v>100 Then c+=1 Next If c>2 Then Return True Return False End Function Function create2landmasses:Bool() Local nislands:Int=getnumberislands() Local c:Int=0 If nislands<>2 Then Return False For Local i=1 To nislands Local v:Int=getlandmass(i) If v>200 Then c+=1 Next If c>1 Then Return True Return False End Function Function getlandmass:Int(islandnumber:Int=1) Local totaltiles:Int=0 For Local y=0 Until mapheight For Local x=0 Until mapwidth If islandmap[x][y] = islandnumber Then totaltiles+=1 Next Next Return totaltiles End Function Function getnumberislands:Int() Local highestnumber:Int=0 For Local y=0 Until mapheight For Local x=0 Until mapwidth If islandmap[x][y] > highestnumber Then highestnumber = islandmap[x][y] Next Next Return highestnumber End Function Function Main() New MyGame() End Function
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.