Seite 5 von 7
Verfasst: 21.08.2007 20:08
von PMV
Scarabol hat geschrieben:@PMV
Um einen Raum zu bauen muss man zuerst im Menü auf den gewünschten Button drücken und dann auf einen der grünen Säle die dann im Spiel angezeigt werden.
Thema verfehlt ... das weis ich schon längst ... und ich habs sogar
geschaft, nen kleinen Ameisenstaat auf zu bauen ... sieht lustig aus, wenn
man ganz viele kleine grüne Punkte hat. Am ende helfen die einem zu
sehen, wo Wege und Räume sind, aber es werden viel zu schnell viel zu
viele, das kann kein Computer schaffen ...
Und um noch mal auf meinen Bug zu sprechen zu kommen:
Es werden keine
gebauten Wege und Räume angezeigt. In der
Außenwelt kann ich den Eingang sehen, im inneren aber nicht. Genau so
fehlen Gänge und alle anderen Räume. System steht im Profil.
MFG PMV
Verfasst: 21.08.2007 21:18
von coder
Ich weiß das man Wachsäle dazwischen setzen kann, ich würde nur gerne lange Gänge ohne Wachsälen dazwischen! Also Gang an Gang...
Verfasst: 23.08.2007 15:24
von Scarabol
@PMV
Dann muss wohl der Include Teil deiner Exe beschädigt sein, bitte erneut herunterladen und schauen ob der Fehler verschwindet.
@coder
Ich versteh nicht ganz wieso? Geht dir die andere Methode zu langsam oder wie? Ansonsten sei gesagt ich werd es für die nächste Version berücksichtigen.
@Alle
Kennt jemand nen superschnellen Pathfind algo der auf einem Schachbrettmuster arbeitet? Es brauchen keine Felder bewertet werden oder so, nur einfach prüfen ob Feld passierbar ist oder nicht.
Bisher verwende ich diesen Code von Artus aus dem Codearchiv
Code: Alles auswählen
Procedure.s FindPath(StartX.l, StartY.l, TargetX.l, TargetY.l)
Protected PYa, PYb, PXa, PXb, PY, PX, G_Step, Lili
Protected NewList APath_List.APath_Field()
Protected NewList APath_ClosedList.APath_Field()
Protected NewList APath_Points.Point()
Protected Result$
StartX = Int((StartX-32)/64)
StartY = Int((StartY-32)/64)
TargetX = Int((TargetX-32)/64)
TargetY = Int((TargetY-32)/64)
MapWidth = #PathMapWidth
MapHeight = #PathMapHeight
MaxCycles = #PathFindMaxCycles
If Path_Map(TargetX,TargetY) = #True
ProcedureReturn "1"
ElseIf StartX = TargetX And StartY = TargetY
ProcedureReturn "2"
EndIf
ClearList(APath_Points())
Static ElementExist.b, Pointer.Point
AddElement(APath_ClosedList())
APath_ClosedList()\X = StartX
APath_ClosedList()\Y = StartY
APath_ClosedList()\ParentX = StartX
APath_ClosedList()\ParentY = StartY
Pointer\X = StartX
Pointer\Y = StartY
Repeat
If Pointer\Y = 0 : PYa = 0 : Else : PYa = 1 : EndIf
If Pointer\Y = MapHeight : PYb = 0 : Else : PYb = 1 : EndIf
If Pointer\X = 0 : PXa = 0 : Else : PXa = 1 : EndIf
If Pointer\X = MapWidth : PXb = 0 : Else : PXb = 1 : EndIf
For PY = Pointer\Y - PYa To Pointer\Y + PYb
For PX = Pointer\X - PXa To Pointer\X + PXb
If PX = Pointer\X Or PY = Pointer\Y ;// ist das Feld nicht der Pointer(Ursprungsfeld)
If Not Path_Map(PX,PY) = #True ;// Schaut ob Feld Blockiert ist
ElementExist = 0
ForEach APath_List()
If PX = APath_List()\X And PY = APath_List()\Y
ElementExist = 1
Break
EndIf
Next
If ElementExist = 0
ForEach APath_ClosedList()
If PX = APath_ClosedList()\X And PY = APath_ClosedList()\Y
ElementExist = 2
Break
EndIf
Next
EndIf
LastElement(APath_ClosedList())
If PX <> Pointer\X And PY <> Pointer\Y
G_Step=14
Else
G_Step=10
EndIf
If ElementExist = 0
AddElement(APath_List())
APath_List()\X = PX
APath_List()\Y = PY
APath_List()\ParentX = Pointer\X
APath_List()\ParentY = Pointer\Y
APath_List()\G = APath_ClosedList()\G + G_Step
APath_List()\H = (Abs(PX-TargetX) + Abs(PY-TargetY))*10
APath_List()\F = APath_List()\H + APath_List()\G
ElseIf ElementExist = 1
If APath_ClosedList()\G + G_Step < APath_List()\G
APath_List()\X = PX
APath_List()\Y = PY
APath_List()\ParentX = Pointer\X
APath_List()\ParentY = Pointer\Y
APath_List()\G = APath_ClosedList()\G + G_Step
APath_List()\H = (Abs(PX-TargetX) + Abs(PY-TargetY))*10
APath_List()\F = APath_List()\H + APath_List()\G
EndIf
EndIf
EndIf
EndIf
Next
Next
If CountList(APath_List()) = 0
ProcedureReturn ""
EndIf
SortStructuredList(APath_List(), 0, OffsetOf(APath_Field\F), #PB_Sort_Long)
FirstElement(APath_List())
AddElement(APath_ClosedList())
APath_ClosedList()\X = APath_List()\X
APath_ClosedList()\Y = APath_List()\Y
APath_ClosedList()\ParentX = APath_List()\ParentX
APath_ClosedList()\ParentY = APath_List()\ParentY
APath_ClosedList()\G = APath_List()\G
APath_ClosedList()\H = APath_List()\H
APath_ClosedList()\F = APath_List()\F
Pointer\X = APath_ClosedList()\X
Pointer\Y = APath_ClosedList()\Y
DeleteElement(APath_List())
Lili + 1
If Pointer\X = TargetX And Pointer\Y = TargetY
Lili = MaxCycles
EndIf
Until Lili = MaxCycles
LastElement(APath_ClosedList())
AddElement(APath_Points())
APath_Points()\X = APath_ClosedList()\X
APath_Points()\Y = APath_ClosedList()\Y
Pointer\X = APath_Points()\X
Pointer\Y = APath_Points()\Y
Repeat
ForEach APath_ClosedList()
If APath_ClosedList()\X = Pointer\X And APath_ClosedList()\Y = Pointer\Y
AddElement(APath_Points())
APath_Points()\X = APath_ClosedList()\ParentX
APath_Points()\Y = APath_ClosedList()\ParentY
Pointer\X = APath_Points()\X
Pointer\Y = APath_Points()\Y
EndIf
Next
Until Pointer\X = StartX And Pointer\Y = StartY
; Element entfernen auf dem der Spieler steht
DeleteElement(APath_Points())
LastElement(APath_Points())
; Liste in umgekehrter Reihenfolge als String zurückgeben
Repeat
Result$ + Str(APath_Points()\x)+"/"+Str(APath_Points()\y) + "%"
Until PreviousElement(APath_Points()) = 0
ProcedureReturn Left(Result$, Len(Result$)-1)
EndProcedure
Gruß
Scarabol
Verfasst: 23.08.2007 16:35
von NicTheQuick
Scarabol hat geschrieben:Kennt jemand nen superschnellen Pathfind algo der auf einem Schachbrettmuster arbeitet? Es brauchen keine Felder bewertet werden oder so, nur einfach prüfen ob Feld passierbar ist oder nicht.
Wie liegen die Daten denn vor?
Als 1D-Array, als 2D-Array, als LinkedList mit Koordinaten der passierbaren
Punkte, als Punkte auf einem Image/Sprite?
Soll der kürzeste Weg gefunden werden oder einfach irgend ein Weg?
Verfasst: 23.08.2007 16:45
von Scarabol
Hallo Nik,
muss jetzt ein bisschen weiter ausholen, aber so versteht ihrs am Besten denke ich.
Die Einheiten können sich nur da bewegen wo der Spieler einen Raum gebaut hat. Daher müsste der Pathfind also nur innerhalb dieser LinkedList von Räumen den kürzesten Weg von Raum A nach Raum B finden.
Gruß
Scarabol
Verfasst: 23.08.2007 23:08
von PMV
So, ich habs noch mal runter geladen, zum dritten mal, aber das hat auch
nix gebracht. Mir is aber ne andere Lösung eingefallen ... nennt sich
Treiber

... ich hab das gefühl, ich hatte nen Steinzeittreiber installiert
... die Versionsnummer is ja gigantisch

... egal.
Also seh nun auch alles
MFG PMV
Verfasst: 24.08.2007 14:39
von NicTheQuick
@Scarabol:
Du hast also eine LinkedList mit Räumen und deren Koordinaten und bei
jedem Raum ist abgespeichert, mit welchem anderen Raum er verbunden ist?
Hier ein Beispielcode, wie du es vielleicht meinst. Ich habe dabei
angenommen, dass jeder Raum mit maximal 4 anderen Räumen verbunden
sein kann.
Code: Alles auswählen
Structure Room
x.l
y.l
*LinkedRoom.Room[4]
EndStructure
Global NewList Room.Room()
Procedure NewRoom(x.l, y.l) ;Erstellt einen neuen Raum
If AddElement(Room())
Room()\x = x
Room()\y = y
ProcedureReturn @Room()
EndIf
ProcedureReturn #False
EndProcedure
Procedure DelRoom(*Room.Room) ;Löscht einen bereits bestehenden Raum
Protected a.l, b.l
;Alle Verbindungen zu anderen Räumen löschen
For a = 0 To 3
If *Room\LinkedRoom[a]
For b = 0 To 3
If *Room\LinkedRoom[a]\LinkedRoom[b] = *Room
*Room\LinkedRoom[a]\LinkedRoom[b] = 0
EndIf
Next
EndIf
Next
;Raum löschen
ChangeCurrentElement(Room(), *Room)
DeleteElement(Room())
ProcedureReturn #True
EndProcedure
Procedure LinkRooms(*Room1.Room, *Room2.Room) ;Verbindet zwei Räume
Protected a.l, empty1.l = -1, empty2.l = -1
For a = 0 To 3
Select *Room1\LinkedRoom[a]
Case *Room2
ProcedureReturn #True ;Räume sind schon verbunden
Case 0
If empty1 = -1 : empty1 = a : EndIf
EndSelect
If *Room2\LinkedRoom[a] = 0
If empty2 = -1 : empty2 = a : EndIf
EndIf
Next
If empty1 >= 0 And empty2 >= 0
*Room1\LinkedRoom[empty1] = *Room2
*Room2\LinkedRoom[empty2] = *Room1
ProcedureReturn #True ;Räume verbunden
EndIf
ProcedureReturn #False ;Keine weitere Verbindung möglich
EndProcedure
Procedure DeLinkRooms(*Room1.Room, *Room2.Room) ;Löst die Verbindung wieder auf
Protected a.l
For a = 0 To 3
If *Room1\LinkedRoom[a] = *Room2
*Room1\LinkedRoom[a] = 0
EndIf
If *Room2\LinkedRoom[a] = *Room1
*Room2\LinkedRoom[a] = 0
EndIf
Next
ProcedureReturn #True
EndProcedure
Structure FindPath
*Room.Room
LinkedRoom.l
EndStructure
Procedure FindPath(*Room1.Room, *Room2.Room, *fRooms.Room())
Protected NewList FP.FindPath(), *FP.FindPath, *LinkedRoom.Room, r.l, ok.l, max.l = -1
AddElement(FP())
FP()\Room = *Room1
FP()\LinkedRoom = 0
*FP = @FP()
r = 0
;CallDebugger
Repeat
;Debug *FP\Room\x
If *FP\LinkedRoom >= 0 And *FP\LinkedRoom <= 3
*LinkedRoom = *FP\Room\LinkedRoom[*FP\LinkedRoom]
If *LinkedRoom
;Debug *LinkedRoom\x
If *LinkedRoom = *Room2 ;ZielRaum wurde gefunden
If max = -1 Or CountList(FP()) < max
max = CountList(FP())
ClearList(*fRooms())
ForEach FP()
AddElement(*fRooms())
*fRooms() = FP()\Room
Next
AddElement(*fRooms())
*fRooms() = *Room2
*FP\LinkedRoom = 3
EndIf
Else
ok = #True
ForEach FP()
If FP()\Room = *LinkedRoom
ok = #False
Break
EndIf
Next
If ok
*FP\LinkedRoom + 1
AddElement(FP())
FP()\Room = *LinkedRoom
FP()\LinkedRoom = -1
*FP = @FP()
r + 1
EndIf
EndIf
EndIf
*FP\LinkedRoom + 1
Else
If r = 0
If max > 0
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
Else
ChangeCurrentElement(FP(), *FP)
DeleteElement(FP())
*FP = @FP()
r - 1
EndIf
EndIf
ForEver
EndProcedure
Dim *Raum.Room(5)
;Wir erstellen 6 Räume und benutzen die x-Koordinate als ID
*Raum(0) = NewRoom(0, 0)
*Raum(1) = NewRoom(1, 0)
*Raum(2) = NewRoom(2, 0)
*Raum(3) = NewRoom(3, 0)
*Raum(4) = NewRoom(4, 0)
*Raum(5) = NewRoom(5, 0)
;Wir verbinden Raum 0 mit 1, 1 mit 2, 2 mit 3, 3 mit 4 und 4 mit 5 sozusagen als Kette,
;außerdem verbinden wir Raum 1 mit 5
LinkRooms(*Raum(0), *Raum(1))
LinkRooms(*Raum(1), *Raum(2))
LinkRooms(*Raum(2), *Raum(3))
LinkRooms(*Raum(3), *Raum(4))
LinkRooms(*Raum(4), *Raum(5))
LinkRooms(*Raum(1), *Raum(5))
NewList *Path.Room()
;Finde den Weg von Raum 0 zu 3
FindPath(*Raum(0), *Raum(3), *Path())
ForEach *Path()
Debug *Path()\x
Next
;Finde den Weg von Raum 0 zu 4
FindPath(*Raum(0), *Raum(3), *Path())
ForEach *Path()
Debug *Path()\x
Next
Verfasst: 26.08.2007 10:01
von Scarabol
Hallo Nik
vielen Dank, dass du dir die Arbeit machst und hier den Code postest, werde sehen ob und wie ich ihn einbauen kann.
Suche noch Ideen für Einheiten, Räume, ect.
Gruß
Scarabol
Verfasst: 26.08.2007 10:41
von PMTheQuick
Hi,
irgendwie hab ich ein Problem. Ich bin jetzt an einer Stelle, wos nicht weitergeht. Alle Blattläuse und Ameisen stehen bei dem Eingangsloch, aber gehen nicht raus

Habe schon einen weiteren Eingang gebaut, aber auch kein Erfolg. Wohl ein Bug
Gruss
PMTheQuick
Link:
http://web56.login-1.loginserver.ch/Savegame6.sav
EDIT: 1. Was zeichnest du denn alles mit StartDrawing? 2. Zeichnest du sie Real-Time oder erzeugst du am Anfang Images auf die du malst?
Verfasst: 26.08.2007 13:20
von Scarabol
Zu Edit:
Sorry ich versteh den Zusammenhang nicht.
Zu "Bug"
Wird gegen Abend von mir geprüft, bin jetzt aber eingeladen.
Gruß
Scarabol