[cadeau] un generateur de carte de donjon
Publié : lun. 10/juil./2017 22:45
un generateur de carte de style donjon des couloirs, des portes des salles :p
ca peux interesser quelqu'un
la salle de départ du générateur est affichée en blanc sur la carte
le principe c'est que je crée une sale puis des portes ensuite je reli des couloirs a chaque porte puis au bout de chaque couloir une pièce puis je répété l’opération pour chaque piece
bien sur je teste pour voir si la pièce n'est pas a la mème position qu'autre chose. de meme pour les couloirs et si c'est le cas je suprime l'objet jusqu'a la porte correspondante.
ça peut sans doute être optimisé . mais bon
ca peux interesser quelqu'un
la salle de départ du générateur est affichée en blanc sur la carte
le principe c'est que je crée une sale puis des portes ensuite je reli des couloirs a chaque porte puis au bout de chaque couloir une pièce puis je répété l’opération pour chaque piece
bien sur je teste pour voir si la pièce n'est pas a la mème position qu'autre chose. de meme pour les couloirs et si c'est le cas je suprime l'objet jusqu'a la porte correspondante.
ça peut sans doute être optimisé . mais bon

Code : Tout sélectionner
;+------------------------------+
;! map generator !
;! licence : CC-BY !
;! 2017 case @ purebasic forums !
;+------------------------------+
;
InitSprite()
Structure door
x.i
y.i
lock.i ; 0 door is not real.1 open,2locked
orientation.s ; nesw
linked.i
unlock.i ; code to unlock
EndStructure
Structure room
type.i ; 0=room ; 1 = hall from south, 2 hall from east, 3 hall from north,4 hall from w
x.i
y.i
l.i
h.i
nodoor.s ; "nesw" la chaine est updatée en fonction des portes generees
color.i
List doors.door()
ddd.i
count.i
parentd.i
parentr.i
EndStructure
Global zoom
Global main=OpenWindow(#PB_Any,0,0,1024,768,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
Global scr=OpenWindowedScreen(WindowID(main),0,0,768,768)
Global nbr
Global maxdoors
Global NewList rooms.room()
Global x_maxroomsize
Global y_maxroomsize
Global x_minroomsize
Global y_minroomsize
Global zoom
Procedure overlap(x,y,l,h)
curent=ListIndex(rooms())
ForEach rooms()
hoverlap = Bool(Bool((x<rooms()\x+rooms()\l)) & Bool((rooms()\x<x+l)))
voverlap = Bool(Bool((y<rooms()\y+rooms()\h)) & Bool((rooms()\y<y+h)))
inside = Bool(hoverlap & voverlap)
If inside=1
SelectElement(rooms(),curent)
ProcedureReturn 0
EndIf
Next
SelectElement(rooms(),curent)
ProcedureReturn 1
EndProcedure
Procedure createroom(t=0,x=-1,y=-1,l=-1,h=-1,color=$ffffff)
;Repeat
If l=-1
l=Random(x_maxroomsize,x_minroomsize) ; largeur
EndIf
If h=-1
h=Random(y_maxroomsize,y_maxroomsize) ; hauteur
EndIf
If x=-1
x=Random(30)+5 ; ul
EndIf
If y=-1
y=Random(30)+5
EndIf
AddElement(rooms())
rooms()\type=t
rooms()\x=x
rooms()\y=y
rooms()\l=l
rooms()\h=h
rooms()\nodoor="nswe"
rooms()\color=color
rooms()\ddd=0
If t=0
nbr -1
EndIf
EndProcedure
Procedure createdoors(maxdoors)
; ADDING DOORS TO ACTUAL ROOM
If maxdoors>=4
dr=Random(4,1)
If Len(rooms()\nodoor)<4
dr=Len(rooms()\nodoor)
EndIf
; maxdoors-dr
ElseIf maxdoors>0
dr=Random(maxdoors % 4,1)
; maxdoors-dr
Else
dr=0
EndIf
; adding doors to actual room
For adoor=1 To dr
If Len(rooms()\nodoor)>0
For retru=1 To 10
di.s=Mid(rooms()\nodoor,Random(Len(rooms()\nodoor),1),1)
Next
rooms()\nodoor=RemoveString(rooms()\nodoor,di)
AddElement(rooms()\doors())
rooms()\doors()\orientation=di
Select di
Case "n"; add a door on the top of the room 'north'
rooms()\doors()\x=rooms()\x+Random(rooms()\l-2,2)
rooms()\doors()\y=rooms()\y
Case "s"
rooms()\doors()\x=rooms()\x+Random(rooms()\l-2,2)
rooms()\doors()\y=rooms()\y+rooms()\h-1
Case "e"
rooms()\doors()\x=rooms()\x+rooms()\l-1
rooms()\doors()\y=rooms()\y+Random(rooms()\h-2,2)
Case "w"
rooms()\doors()\x=rooms()\x
rooms()\doors()\y=rooms()\y+Random(rooms()\h-2,2)
EndSelect
EndIf
Next
ProcedureReturn maxdoors
EndProcedure
Procedure createhall()
curentroom=ListIndex(rooms())
ForEach rooms()\doors()
If maxdoors>0
curentdoor=ListIndex(rooms()\doors())
rl=Random(x_maxroomsize,x_minroomsize)
rh=Random(y_maxroomsize,y_minroomsize)
x=rooms()\doors()\x
y=rooms()\doors()\y
o.s=rooms()\doors()\orientation.s
l=Random(5,3) ; longueur du couloir
Select o
Case"w"
If overlap(x-l,y-1,l,3)
rooms()\doors()\linked=1
LastElement(rooms())
createroom(2,x-l,y-1,l,3,$888888)
AddElement(rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\y=y
rooms()\doors()\x=x-1
b=ListIndex(rooms())
LastElement(rooms())
xr=x-l-rl
wallsize=rh-3 ;
doorx=-(Random(wallsize)-wallsize/2)
yr=(y-1)-((wallsize/2))+doorx
If overlap(xr,yr,rl,rh)
AddElement(rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\y=y
rooms()\doors()\x=x-l
createroom(0,xr,yr,rl,rh,$888888)
rooms()\nodoor=RemoveString(rooms()\nodoor,"e")
AddElement (rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\x=x-l-1
rooms()\doors()\y=y
rooms()\count=maxdoors
maxdoors -1
Else
DeleteElement(rooms())
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
DeleteElement(rooms()\doors())
EndIf
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
Else
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
EndIf
SelectElement(rooms(),b)
Case"n"
If overlap(x-1,y-l,3,l)
rooms()\doors()\linked=1
LastElement(rooms())
createroom(1,x-1,y-l,3,l,$888888)
AddElement(rooms()\doors())
rooms()\parentd=curentdoor
rooms()\parentr=curentroom
rooms()\doors()\linked=1
rooms()\doors()\x=x
rooms()\doors()\y=y-1
b=ListIndex(rooms())
wallsize=rl-3 ;
doorx=-(Random(wallsize)-wallsize/2)
xr=(x-1)-((wallsize/2))+doorx
yr=y-l-rh
If overlap(xr,yr,rl,rh)
SelectElement(rooms(),b)
AddElement(rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\x=x
rooms()\doors()\y=y-l
LastElement(rooms())
createroom(0,xr,yr,rl,rh,$888888)
rooms()\nodoor=RemoveString(rooms()\nodoor,"s")
AddElement (rooms()\doors())
rooms()\doors()\lock=Random(2)
rooms()\doors()\linked=1
rooms()\doors()\x=x
rooms()\doors()\y=y-l-1
rooms()\count=maxdoors
maxdoors -1
Else
DeleteElement(rooms())
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
DeleteElement(rooms()\doors())
EndIf
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
Else
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
EndIf
SelectElement(rooms(),b)
Case"s"
If overlap(x-1,y+1,3,l)
rooms()\doors()\linked=1
LastElement(rooms())
createroom(3,x-1,y+1,3,l,$888888)
AddElement(rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\x=x
rooms()\doors()\y=y+1
b=ListIndex(rooms())
LastElement(rooms())
wallsize=rl-3 ;
doorx=-(Random(wallsize)-wallsize/2)
xr=(x-1)-((wallsize/2))+doorx
yr=y+l +1
If overlap(xr,yr,rl,rh)
AddElement(rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\x=x
rooms()\doors()\y=y+l
createroom(0,xr,yr,rl,rh,$888888)
AddElement (rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\x=x
rooms()\doors()\y=y+l+1
rooms()\nodoor=RemoveString(rooms()\nodoor,"n")
rooms()\count=maxdoors
maxdoors -1
Else
DeleteElement(rooms())
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
DeleteElement(rooms()\doors())
EndIf
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
Else
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
EndIf
SelectElement(rooms(),b)
Case"e"
If overlap(x+1,y-1,l,3)
rooms()\doors()\linked=1
LastElement(rooms())
createroom(4,x+1,y-1,l,3,$888888)
AddElement(rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\y=y
rooms()\doors()\x=x+1
b=ListIndex(rooms())
LastElement(rooms())
xr=x+l+1
wallsize=rh-3 ;
doorx=-(Random(wallsize)-wallsize/2)
yr=(y-1)-((wallsize/2))+doorx
If overlap(xr,yr,rl,rh)
AddElement(rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\y=y
rooms()\doors()\x=x+l
createroom(0,xr,yr,rl,rh,$888888)
rooms()\nodoor=RemoveString(rooms()\nodoor,"w")
AddElement (rooms()\doors())
rooms()\doors()\linked=1
rooms()\doors()\x=x+l+1
rooms()\doors()\y=y
rooms()\count=maxdoors
maxdoors -1
Else
DeleteElement(rooms())
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
DeleteElement(rooms()\doors())
EndIf
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
Else
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
EndIf
SelectElement(rooms(),b)
EndSelect
SelectElement(rooms(),curentroom)
SelectElement(rooms()\doors(),curentdoor)
Else
If rooms()\doors()\linked=0
DeleteElement(rooms()\doors())
EndIf
Break
EndIf
Next
EndProcedure
Procedure generatedungeon(nbr=1)
centerx=(768/2)/zoom
centery=(768/2)/zoom
maxdoors=nbr
createroom(0,centerx-8,centery-8,16,16,$ffffff) ; create the first room
If nbr>1 ; more rooms to come
maxdoors=nbr-1 ; nombre de portes max = nombre de pieces
Repeat
ForEach rooms()
curentroom=ListIndex(rooms())
If rooms()\type=0 And rooms()\ddd=0
maxdoors=createdoors(maxdoors)
createhall()
EndIf
SelectElement(rooms(),curentroom)
Next
Until maxdoors=0
EndIf
EndProcedure
;seed$="PureBasicRulez"
If seed$<>""
For a=1 To Len(seed$)
seed.q +Asc(Mid(seed$,a,1))
Next
RandomSeed(seed)
EndIf
;;
x_maxroomsize=32
y_maxroomsize=32
x_minroomsize=8
y_minroomsize=8
zoom=1
generatedungeon(200) ; restons coherents :)
miny=$ffff
maxy=-0
minx=$ffff
maxx=-0
ForEach rooms()
If rooms()\x< minx
minx=rooms()\x
EndIf
If rooms()\x+rooms()\l>maxx
maxx=rooms()\x+rooms()\l
EndIf
If rooms()\y< miny
miny=rooms()\y
EndIf
If rooms()\y+rooms()\h> maxy
maxy=rooms()\y+rooms()\h
EndIf
Next
MapSizex =(Abs(maxx)-Abs(minx))
MapSizey =(Abs(maxy)-Abs(miny))
centerx=Int(768/2)
centery=Int(768/2)
offsetx= minx
offsety= miny
mappic=CreateImage(#PB_Any,MapSizex,MapSizey)
StartDrawing(ImageOutput(mappic))
DrawingMode(#PB_2DDrawing_Default)
ForEach rooms()
Box((rooms()\x-offsetx)*zoom,(rooms()\y-offsety)*zoom,rooms()\l*zoom,rooms()\h*zoom,rooms()\color)
Box((rooms()\x-offsetx)*zoom+zoom,(rooms()\y-offsety)*zoom+zoom,rooms()\l*zoom-zoom*2,rooms()\h*zoom-zoom*2,$333333)
ForEach rooms()\doors()
If rooms()\type=0
If rooms()\doors()\linked=1
Select rooms()\doors()\lock
Case 0
Box((rooms()\doors()\x-offsetx)*zoom,(rooms()\doors()\y-offsety)*zoom,zoom,zoom,$333333)
Case 1
Box((rooms()\doors()\x-offsetx)*zoom,(rooms()\doors()\y-offsety)*zoom,zoom,zoom,$00ff00)
Case 2
Box((rooms()\doors()\x-offsetx)*zoom,(rooms()\doors()\y-offsety)*zoom,zoom,zoom,$0000ff)
EndSelect
Else
DeleteElement(rooms()\doors())
EndIf
Else
Box((rooms()\doors()\x-offsetx)*zoom,(rooms()\doors()\y-offsety)*zoom,zoom,zoom,$333333)
Box((rooms()\doors()\x-offsetx)*zoom,(rooms()\doors()\y-offsety)*zoom,zoom,zoom,$333333)
EndIf
Next
Next
StopDrawing()
;- mainloop
playerx=0
playery=0
StartDrawing(ScreenOutput())
DrawImage(ImageID(mappic),centerx-ImageWidth(mappic)/2,centery-ImageHeight(mappic)/2)
StopDrawing()
FlipBuffers()
Repeat
ev=WaitWindowEvent(1)
Until ev=#PB_Event_CloseWindow