Usefull thing for strategy games. Floodfill the map and give all connected tiles a number. You can then get the landmass size. With ai programming you can then also do useful things with the information. With map generating you can create maps until certain landmass needs are met.
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 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 percland = Rnd(2.0,3.5) makemap makeislandmap End Method Method OnUpdate() ' how much land must it have numoflandtiles </mapsize/percland remakecnt+=1 If remakecnt > 10 remakecnt=0 percland = Rnd(2.0,3.5) makemap makeislandmap End If End Method Method OnRender() Cls 0,0,0 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 "Landmass floodfill to number the continents/islands",0,0 For Local y=1 To numislands DrawText "Landmass "+y+" is "+getlandmass(y)+" tiles.",0,y*15 Next End Method End Class 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 SetColor 255,255,255 For Local y=0 Until mapheight For Local x=0 Until mapwidth DrawText islandmap[x][y],x*tilewidth+tilewidth/2,y*tileheight+tileheight/2,0.5,0.5 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 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.