Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Map Generator

Hello everyone I am in need of a map generator

How it will work is you will specify different perameters such as
Trees =20
Bushes =30
Cliffs =75
Water=250
after these are specified, it will randomly place those in spots around the map. Ofcourse, we dont want water to be placed around the map in several different spots which is why water will be given a sticky perameter it will look like this

water= 250 Sticky = 15

in this example sticky is 15. That means that a minimum of 15 water tiles will be bunched together at once creating small pools of water instead of random one tiles of water.

So basically this will "seed" the map. Then you can build on the map from there. I hope this isnt too complicated and i know i am not very good at explaining but if anyone can grasp my concept then please help. Oh and just so everyone knows right away i do not know anything about ruby script, however i would like to learn ruby script and C#.  :(

ARE YOU THERE???  I am currently--Awaiting a reply
 
well i assume no one is up for the task? But on the offchance that somone does want to help me, i should probably make it aware that i may not be on rmxp.org very often as i am currently very busy creating my own forum and a game. So if you do wish to help me out then please let me know at this forum ( im on it like everyday so i will see your post )

http://zeitreise.forumotion.com/index.htm

Thank you for your support. ( if i am breaking a rule by posting a url to another forum and you are a moderator feel free to edit my post and delete the url )
 

poccil

Sponsor

Here is my attempt at a random map generator that I wrote some time ago.

Code:
class TileDrawingHelper
  Autotiles = [
    [ [27, 28, 33, 34], [ 5, 28, 33, 34], [27,  6, 33, 34], [ 5,  6, 33, 34],
      [27, 28, 33, 12], [ 5, 28, 33, 12], [27,  6, 33, 12], [ 5,  6, 33, 12] ],
    [ [27, 28, 11, 34], [ 5, 28, 11, 34], [27,  6, 11, 34], [ 5,  6, 11, 34],
      [27, 28, 11, 12], [ 5, 28, 11, 12], [27,  6, 11, 12], [ 5,  6, 11, 12] ],
    [ [25, 26, 31, 32], [25,  6, 31, 32], [25, 26, 31, 12], [25,  6, 31, 12],
      [15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12] ],
    [ [29, 30, 35, 36], [29, 30, 11, 36], [ 5, 30, 35, 36], [ 5, 30, 11, 36],
      [39, 40, 45, 46], [ 5, 40, 45, 46], [39,  6, 45, 46], [ 5,  6, 45, 46] ],
    [ [25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12],
      [17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [ 5, 42, 47, 48] ],
    [ [37, 38, 43, 44], [37,  6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44],
      [37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [ 1,  2,  7,  8] ]
  ]
  
  # converts neighbors returned from tableNeighbors to tile indexes
  NeighborsToTiles=[
    46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 
    42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16,
    46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40,
    42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 
    45, 39, 45, 39, 33, 31, 33, 29, 45, 39, 45, 39, 33, 31, 33, 29,
    37, 27, 37, 27, 23, 15, 23, 13, 37, 27, 37, 27, 22, 11, 22, 9, 
    45, 39, 45, 39, 33, 31, 33, 29, 45, 39, 45, 39, 33, 31, 33, 29,
    36, 26, 36, 26, 21, 7, 21, 5, 36, 26, 36, 26, 20, 3, 20, 1, 46, 
    44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 
    32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 46, 
    44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42,
    32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 45,
    38, 45, 38, 33, 30, 33, 28, 45, 38, 45, 38, 33, 30, 33, 28, 37,
    25, 37, 25, 23, 14, 23, 12, 37, 25, 37, 25, 22, 10, 22, 8, 45, 
    38, 45, 38, 33, 30, 33, 28, 45, 38, 45, 38, 33, 30, 33, 28, 36, 
    24, 36, 24, 21, 6, 21, 4, 36, 24, 36, 24, 20, 2, 20, 0
  ]
  def self.tableNeighbors(data,x,y)
      return 0 if x>=data.xsize || x<0
      return 0 if y>=data.ysize || y<0
      t=data[x,y]
      xp1=[x+1,data.xsize-1].min
      yp1=[y+1,data.ysize-1].min
      xm1=[x-1,0].max
      ym1=[y-1,0].max
      i=0
      i|=0x01 if data[x  ,ym1]==t # N
      i|=0x02 if data[xp1,ym1]==t # NE
      i|=0x04 if data[xp1,y  ]==t # E
      i|=0x08 if data[xp1,yp1]==t # SE
      i|=0x10 if data[x  ,yp1]==t # S
      i|=0x20 if data[xm1,yp1]==t # SW
      i|=0x40 if data[xm1,y  ]==t # W
      i|=0x80 if data[xm1,ym1]==t # NW
      return i
  end
  
  
attr_accessor :tileset
attr_accessor :autotiles

def initialize(tileset,autotiles)
 @tileset=tileset
 @autotiles=autotiles
end

def self.fromTileset(tileset)
 bmtileset=RPG::Cache.tileset(tileset.tileset_name)
 bmautotiles=[]
 for i in 0...7
  bmautotiles.push(RPG::Cache.autotile(tileset.autotile_names[i]))
 end
 return self.new(bmtileset,bmautotiles)
end

def bltSmallAutotile(bitmap,x,y,cxTile,cyTile,id,frame)
  return if frame<0 || !@autotiles || id>=384
  autotile=@autotiles[id/48-1]
  return if !autotile || autotile.disposed?
  cxTile=[cxTile/2,1].max
  cyTile=[cyTile/2,1].max
  if autotile.height==32
    anim=frame*32
    src_rect=Rect.new(anim,0,32,32)
    bitmap.stretch_blt(Rect.new(x,y,cxTile*2,cyTile*2),autotile,src_rect)
  else
    anim=frame*96
    id%=48
    tiles = TileDrawingHelper::Autotiles[id>>3][id&7]
    src=Rect.new(0,0,0,0)
    for i in 0...4
      tile_position = tiles[i] - 1
      src.set(tile_position % 6 * 16 + anim,
       tile_position / 6 * 16, 16, 16)
      bitmap.stretch_blt(Rect.new(i%2*cxTile+x,i/2*cyTile+y,cxTile,cyTile), 
        autotile, src)
    end
  end
end


def bltSmallRegularTile(bitmap,x,y,cxTile,cyTile,id)
   return if !@tileset || id<384 || @tileset.disposed?
   rect=Rect.new((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
   bitmap.stretch_blt(Rect.new(x,y,cxTile,cyTile),@tileset,rect)
end

def bltSmallTile(bitmap,x,y,cxTile,cyTile,id,frame=0)
 if id>=384
  bltSmallRegularTile(bitmap,x,y,cxTile,cyTile,id)
 elsif id>0
  bltSmallAutotile(bitmap,x,y,cxTile,cyTile,id,frame)
 end  
end

def bltAutotile(bitmap,x,y,id,frame)
  bltSmallAutotile(bitmap,x,y,32,32,id,frame)
end

def bltRegularTile(bitmap,x,y,id)
  bltSmallRegularTile(bitmap,x,y,32,32,id)
end

def bltTile(bitmap,x,y,id,frame=0)
 if id>=384
  bltRegularTile(bitmap,x,y,id)
 elsif id>0
  bltAutotile(bitmap,x,y,id,frame)
 end  
end

end

def floodFillInternal(table,x,y,target,fillbits,points)
 w=table.xsize
 xLeft=x
 xRight=x
 yFromOrg=y
 xFromOrg=x
 curpos=yFromOrg*w+xFromOrg
 begin
  if !fillbits[curpos]
   points.push([xLeft,y])
  end
  fillbits[curpos]=true
  curpos-=1
  xLeft-=1
 end while (xLeft>=0&&
       table[xLeft,y]==target&&
       !fillbits[curpos])
 xLeft+=1
 curpos=yFromOrg*w+xFromOrg
 begin
  if !fillbits[curpos]
   points.push([xRight,y])
  end
  fillbits[curpos]=true
  curpos+=1
  xRight+=1
 end while(xRight<table.xsize&&
       table[xRight,y]==target&&
       !fillbits[curpos])
 xRight-=1
 curpos=yFromOrg-w+(xLeft)
 for i in xLeft..xRight
  above=(yFromOrg-1)*w+(i)
  below=(yFromOrg+1)*w+(i)
  if(y> 0      &&table[i,y-1]==target&&!fillbits[above])
   ret=floodFillInternal(table,i,y-1,target,fillbits,points)
  end
  if(y<(table.ysize-1)&&table[i,y+1]==target&&!fillbits[below])
   ret=floodFillInternal(table,i,y+1,target,fillbits,points)
  end
 end
end

N=0x01
NE=0x02
E=0x04
SE=0x08
S=0x10
SW=0x20
W=0x40
NW=0x80
BADNEIGHBORS=[
0,
SE,
NW,
NE,
SW,
S|SW,
S|SE,
N|NW,
N|NE,
W|SW,
W|NW,
E|NE,
E|SE,
S|SW|SE,
N|NW|NE,
W|NW|SW,
E|NE|SE
]

def isBadNeighbor?(neighbor)
  return true if BADNEIGHBORS.any?{|i| i==neighbor }
  return true if (neighbor&(S|W))==(0) && (neighbor&(SW))!=0
  return true if (neighbor&(N|W))==(0) && (neighbor&(NW))!=0
  return true if (neighbor&(S|E))==(0) && (neighbor&(SE))!=0
  return true if (neighbor&(N|E))==(0) && (neighbor&(NE))!=0
  return true if (neighbor&(NW|NE))==(0) && (neighbor&(N))!=0
  return true if (neighbor&(SW|SE))==(0) && (neighbor&(S))!=0
  return true if (neighbor&(NW|SW))==(0) && (neighbor&(W))!=0
  return true if (neighbor&(NE|SE))==(0) && (neighbor&(E))!=0
end

def pbTableMoveToNeighbor(table,pointtable,value)
  1000.times do
   x=rand(table.xsize)
   y=rand(table.ysize)
   next if table[x,y]!=0
   table[x,y]=value
   nb=TileDrawingHelper.tableNeighbors(table,x,y)
   if isBadNeighbor?(nb)
     table[x,y]=0
     next
   end
   if nb==0 && rand(100)<50
     table[x,y]=0
     next
   end
   pointtable[x,y]=2
   break
  end
end

def pbTablePlaceValue(table,value,minNumber,minbunch)
 return if minNumber<=0
 # Phase 1: Place _minNumber_ points on the map
 1000.times do
  1000.times do
   x=rand(table.xsize-1)
   y=rand(table.ysize-1)
   placepos=[]
   if table[x,y]==0
    table[x,y]=value
    placepos.push([x,y])
   end
   if table[x+1,y]==0
    table[x+1,y]=value
    placepos.push([x+1,y])
   end
   if table[x,y+1]==0
    table[x,y+1]=value
    placepos.push([x,y+1])
   end
   if table[x+1,y+1]==0
    table[x+1,y+1]=value
    placepos.push([x+1,y+1])
   end
   placed=placepos.length
   for pp in placepos
    nb=TileDrawingHelper.tableNeighbors(table,pp[0],pp[1])
    if isBadNeighbor?(nb)
      table[pp[0],pp[1]]=0
      placed-=1
    end
   end
   minNumber-=placed
   break
  end
  break if minNumber<=0
 end
 # Phase 2: Move all bad points
 badpoints=0
 begin
  badpoints=0
  pointtable=Table.new(table.xsize,table.ysize)
  fillbits=[]
  # Find all bad points with flood filling
  if minbunch>0
   table.xsize.times{|x|
    table.ysize.times{|y|
     next if table[x,y]!=value
     index=y*table.xsize+x
     if !fillbits[index]
      points=[]
      floodFillInternal(table,x,y,value,fillbits,points)
      isbad=(points.length<minbunch)
      havebadpoints=true if isbad
      badpoints+=points.length if isbad
      for p in points
       pointtable[p[0],p[1]]=isbad ? 1 : 2
      end
     end
    }
   }
  end
  # Find all inappropriately placed points
  pointtable.xsize.times{|x|
   pointtable.ysize.times{|y|
    next if pointtable[x,y]==1
    next if table[x,y]!=value
    nb=TileDrawingHelper.tableNeighbors(table,x,y)
    if isBadNeighbor?(nb)
     pointtable[x,y]=1
     badpoints+=1
    end
    if nb==(0xEF) # everything but South
     table[x,y+1]=value
    end
    if nb==(0xBF) # everything but West
     table[x-1,y]=value
    end
    if nb==(0xFB) # everything but East
     table[x+1,y]=value
    end
    if nb==(0xFE) # everything but North
     table[x,y-1]=value
    end
   }
  }
  if badpoints>0
   # Move all bad points to new locations
   pointtable.xsize.times{|x|
    pointtable.ysize.times{|y|
     next if pointtable[x,y]!=1 # skip if not a bad point
     pointtable[x,y]=0
     table[x,y]=0
     pbTableMoveToNeighbor(table,pointtable,value)
    }
   }
  end
 end while badpoints>0
end

def pbGenerateMap(id,width,height,generateMapParams)
 # Fill table with zeros
 table=Table.new(width,height)
 table.xsize.times{|x|
  table.ysize.times{|y|
   table[x,y]=0
  }
 }
 # Place autotiles on the table
 for i in 0...7
  count=generateMapParams[i*2]
  sticky=generateMapParams[i*2+1]
  pbTablePlaceValue(table,i+1,count,sticky)
 end
 # Create map and fill it with grass
 map=RPG::Map.new(width,height)
 map.data.xsize.times{|x|
  map.data.ysize.times{|y|
   map.data[x,y,0]=384
  }
 }
 # Fill map with autotiles
 neighbors=TileDrawingHelper::NeighborsToTiles
 for i in 0...map.width
    for j in 0...map.height
      if table[i,j]!=0
        nb=TileDrawingHelper.tableNeighbors(table,i,j)
        tile=neighbors[nb]
        map.data[i,j,1]=tile+48*table[i,j]
      end
    end
 end
 # Save map 
 save_data(map,sprintf("Data/Map%03d.rxdata",id))
end
 #Usage:
 
 pbGenerateMap(
   24, # Map ID
   30, # Map Width
   30, # Map Height
   [  # Map Parameters
   # count, sticky
   20,8,    # Autotile 1
   30,8,    # Autotile 2
   75,8,    # Autotile 3
   250,15,  # Autotile 4
   0,0,     # Autotile 5
   0,0,     # Autotile 6
   0,0      # Autotile 7
  ]
 )
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top