Bewegungsreichweite eines taktischen Kampfsystems
Übersicht

![]() |
SkabusBetreff: Bewegungsreichweite eines taktischen Kampfsystems |
![]() Antworten mit Zitat ![]() |
---|---|---|
Guten Abend,
Ich hab momentan etwas Zeit, deswegen brüte ich wieder über meinem Kampfsystem für Aves Certim. Ich bin dabei auf ein etwas tiefgreifenderes Problem gestoßen und würe mich freuen wenn ihr mir eure Ideen dazu vermitteln könntet ![]() Ich programmiere ein taktisches Kampfsystem und brauche dafür eine Routine die mir einen Array ausspuckt in dem die Bewegungsmöglichkeiten eines Charakters enthalten sind.Die Bewegung ist ganz einfach. ->Ich haben einen Wert(Aktionspunkte) die quasi als Wärung der Bewegung fungiert. ->Meine Karte ist in 16*16 Kacheln angelegt und jede Bewegung von Kachel zu Kachel kostet 1 AP Nun soll der aktuelle Charakter entsprechend der Aktionspunkte einen Radius angezeigt bekommen in dem er sich bewegen kann.Dabei kann er nur soviele Schritte gehen, wie er Aktionspunkte besitzt. Hat ein Charakter 2 AP kann er 2 Schritte gehen.Sein resultierender Aktionsradius sieht dann so aus: Das Kreuz ist die Position des Charakters, die grünen Felder sind begehbar die roten nicht, da da nen Stein oder ein anderes Hindernis liegt.Diese Kollisionsdaten liegen in einem Array. Nun ist mein Ansatz gewesen, den Ausschnitt aus dem Kollisionsarray in einen temporären Array zu übertragen und dann alle nicht erreichbaren Felder dann in den temporären Array ebenfalls als "nicht begehbar" zu kennzeichnen.Als letztes müsste ich diesen temporären Array dann nur noch durch meinen A-Star-Algorithmus jagen und ich erhalte eine genaue Bewegungsreihenfolge in welcher ich dann genau weiß wo der Charakter lang gehen muss. Dabei fallen mir mehrere Implementierungsprobleme auf, über die ich momentan nachgrüble und auf die ich keine Antwort finden. 1.)Wie kann ich genau festlegen, dass exakt der verfügbare Bewegungsradius ermittelt wird. Wenn mein Charakter z.B. ganz links oben auf der Karte steht dann kann er natürlich nur nach rechts und unten oder diagonal nach unten laufen. 2.)Wie kann ich berücksichtigen, dass bestimmte Hindernisse den komplette Bewegung in eine Richtung verhindern, sodass diese Richtung gar nicht weiter verfolgt wird?z.B. bei dem Beispiel oben, wenn ein Stein direkt links,rechts,oben oder unten vom Spieler liegt und er nur 2 Schritte machen kann dann kann er logischerweise auch nicht 2 mal nach links/rechts/unten/oben geht auch wenn nach dem ersten Feld noch ein weites erreichbar wäre. Ich würd mich über Ideen und Anregung zu diesem komplexen Thema freuen. Ich hab nämlich selbst schon eine Idee wie ich es umsetzen könnte, aber so wie ich es machen würde, würde es übermäßig kompliziert werden, mit mehreren Fakllunterscheidungen gigantischen If-Verzweigungen und und und.Und das möchte ich wenn möglich vermeiden. Ich hoffe auf eure Hilfe!Danke ![]() MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
TimBo |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi Skabus,
ich würde es mit einer Rekrusiven Funktion machen. Du kannst ja nur in 4 Richtungen gehen. dann gehst du für die 4 Punkte , die du erreichen kannst wieder in 4 Richtungen, und das ganze AP mal. Also sowas NeuerSchritt(ausgangspunktx,ausgangspunkty) in jede richtung dann NeuerSchritt() ausführen End Function Liebe Grüße TimBo |
||
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31 hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht. |
AvaGast |
![]() Antworten mit Zitat |
|
---|---|---|
Im Prinzip ist das ganze auch nur ein (vereinfachter) A*, dessen Funktionsweise Du leicht abwandelst. Du suchst die Karte halt nicht nach einem bestimmten Ziel ab, sondern nach allen erreichbaren Feldern, indem Du den A* vom Ursprung (der Spielfigur) aus einfach sollange aufrufst, bis kein nächstes Feld mehr innerhalb der Bewegungsreichweite liegt. Der Ansatz mit dem temporären Array ist dafür sehr gut geeignet, so hatte ich das bei The Darkthrone auch gelöst. | ||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
A* ist für sowas aber schon recht bruteforce ![]() Damit er effizient würde muss er soweit modifiziert werden das er effektiv nur noch eine breitensuche oder dijkstra suche ist. Die breitensuche geht dabei einfach stupide herum in abhängigkeit von der direkten feld distanz zu dir / bewegungstiefe. Dijkstra ist da sehr viel intelligenter und wird vor allem dann interessant wenn die felder unterschiedliche kosten hat, da er jeweils das bewegungsdistanzmässig naheste feld abarbeitet. Dadurch wir die bestimmung, wann man aufhören kann "selbst lösend". Implementationsmässig ist Dijkstra sehr einfach (kaum mehr aufwand als die breitensuche) und eine einfache "gib mir immer das kleinste Element" Datenstruktur (-> Heap, hat allermindestens 1 im Codearchive) ist alles was man dafür braucht abgesehen von ein wenig code fürs abarbeiten der Punkte sowie das hinzufügen der allfälligen nachbarpunkten, sofern sie noch nicht besucht wurden. ob ein feld schon besucht wurde oder nicht beim check speichert ihr am einfachsten direkt in den tiles der map und reseted die flag nach der berechnung wieder (einfach das Rechteck das durch die kleinste und grösste X / Y koordinate erzeugt wird komplett resetten) |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
Ich hab jetzt Wochen über Wochen mit meinem Anzeigealgorithmus gearbeitet, mehrere Quellen gewälzt und hab auch bereits mehrere im Ansatz funktionierende Algorithmen geschrieben. Leider funktionieren sie letzendlich immer an einer kleiner Stelle nicht, oder sie funktionieren nur für bestimmte Teile oder Situationen fehlerfrei... Ich bin mitlerweile ziemlich verzweifelt.Keine Ahnung wie ich jemals nen funktionierenden Algorithmus selber hinkriegen soll.Meine Bemühungen dahingehend waren bissher zumindest im Detail fruchtlos ![]() Daher wollte ich fragen, ob es im Codearchiv oder irgendwo ein Codebeispiel oder ähnliches gibt, was mir diese Arbeit abnimmt.Ich habs jetzt 2 Monate versucht selbst zu machen, es funktioniert aber einfach nicht. Würd mich freuen, wenn mir jemand nen Link oder nen Quellcode(egal welche Sprache) geben könnte, der sich mit einem ähnlichen Thema befasst. Wäre euch sehr dankbar ![]() MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
das hört sich doch mal spannend an....
Zeig mal den besten deiner algo's, damit ich sehen kann was du bisher erreicht hast. Hast du eine rekursive Lösung hinbekommen? Welche Deiner Fragen aus dem ersten Beitrag sind noch ungelöst? Geht es dir nur darum, dieses 2.Array zu erhalten, oder hattest du Probeme, dies dann in der A* einzubinden? Fragen über Fragen... |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] SuperStrict
Global map:Int[16 , 16] Global Targetmap:Int[16 , 16] map[3 , 3] = 1 map[4 , 3] = 1 map[5 , 5] = 1 Local startx:Int = 3 Local starty:Int = 4 Local range:Int = 4 fillmap(map,targetmap,startx,starty,range) drawmap(targetmap) Function isWalkable:Int(m:Int[,],x:Int,y:Int) If (x >=0) And (y>=0) And (x<16) And (y<16) Then If m[x , y] = 0 Then Return True EndIf End Function Function FillMap(source:Int[,],target:Int[,],x:Int , y:Int , range:Int) If isWalkable(source,x - 1 , y) Then target[x - 1 , y] = 1 If range > 1 Then fillmap(source,target,x-1 , y , range - 1) EndIf If isWalkable(source,x + 1 , y) Then target[x + 1 , y] = 1 If range > 1 Then fillmap(source,target,x+1 , y , range - 1) EndIf If isWalkable(source,x , y-1) Then target[x , y-1] = 1 If range > 1 Then fillmap(source,target,x , y-1 , range - 1) EndIf If isWalkable(source,x , y+1) Then target[x , y+1] = 1 If range > 1 Then fillmap(source,target,x , y+1 , range - 1) EndIf End Function Function drawmap(m:Int[,]) For Local y:Int = 0 Until 16 For Local x:Int= 0 Until 16 StandardIOStream.WriteString(String(m[x,y])) StandardIOStream.Flush() Next Next End Function Das wäre mein hingesauter Ansatz dafür. Funtioniert unter BMax einwandfrei, in Targetmap sind die begehbaren Felder. Ist natürlich sehr unsauber. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke für eure Antworten^^
Also ich hab es erstmal die Tage durchgetestet bei Gelegenheit.Ich dachte zunächst das Problem läge bei meiner Methode, da ich nicht die gesamte Karte(also den gesamten Array) sondern nur einen Auschnitt aus dem Kartenarray in einen separaten Array übertragen habe. Allerdings habe ich bis eben das Ganze mal mit dem kompletten Kartenarray getestet und es will weiterhin nicht funktionieren. Problem ist folgendes: Mein Algorythmus berechnet den Radius grob korrekt, tut dies aber seltsamerweise nur manchmal vollständig richtig.Meistens vergisst er dort wo ein Hindernis steht, quasi auch den Pfad, der hinter dem Hindernis steht miteinzubeziehen... Es sieht aus, als wäre der leere Bereich hinder dem Hindernis quasi der Schatten weil nur exakt hinter dem Hindernis die Felder fehlen die eigentlich begehbar sind. Hier mal der Code mit dem ich den Radius berechne(-1 bedeutet hier "noch nicht geprüft" wärend 0 begehbar und jeder Wert > 0 ein Hinderniss darstellt, die -1 benötige ich, damit ich später aus allen nicht geprüften Feldern temporär eine 1 machen kann, damit mein AStaralgorithmus danach die Felder die außerhalb des Bewegungsradius liegt als Hindernis interpretiert) Zur Erläuterung: range ist die Bewegungsreichweite die man maximal gehen kann,diese hängt von den AP des Charakters ab.Hat er z.B. 7 AP kann er 7 Felder gehen. posX und posY sind die aktuelle Position, hierbei muss beachtet werden, dass die Funktion nicht den vollständigen Bewegungsradius berechnet sondern nur für die aktuelle Richtung, was durch dir ausgedrückt wird. stepCount stellt den Akkumulator der Rekursion dar(wer nicht weiß was eine Rekursion mit Akkumulator ist, kann sich z.B. hier belesen: http://www.deinprogramm.de/dmda/akku.pdf) und ist dann gleich der range-Variable wenn alle Schritte verbraucht sind... battleMSizeX/Y ist die Größe der Karte. Warum ich dir und curDir genommen habe weiß ich selber nicht genau. Es liegt wohl aan oben benanntem Problem.Die Funktion berechnet nicht den ganzen Radius sondern nur die möglichen Pfade einer Richtung, daher brauche ich die Richtung des aktuellen rekursiven Aufrufs und einmal die ursprüngliche Richtung. Alles sehr doof gelöst, aber vllt.. versteht ihr jetzt warum ich verzweifelt bin^^" Bei weiteren Unklarheiten, einfach fragen^^ BlitzMax: [AUSKLAPPEN] 'diese Methode aktualisiert den temporären MoveArray und ermittelt anhand der Daten Midimaster: Wie du siehst habe ich mich für eine rekursive Variante entschieden.Grob stimmt das Ergebnis auch, aber eben nur grob.Im Detail funktioniert er bei dem Hauptcharakter 100%tig, bei den 3 weiteren Charakteren die einer anderen Position stehen funktioniert er nicht. ICh weiß einfach nur nicht warum er mir was falsches liefert... Es ist im übrigen sehr schwer lauffähigen Code hochzuladen da mein Programm mitlerweile an die 10000 Zeilen Code enthält...verzeiht mir also^^" MfG Ska BladeRunner: Ich hatte ganz vergessen zu sagen, das dein Ansatz mir sehr hilft.Danke dafür. Dein Ansatz ist also völlig ohne Richtungsangabe?Geht aber trotzdem vollständig alle Richtungen ab? Ne andere Sache: Du sagst an 3 Stellen sind Hindernisse also 1 sind deine Hindernisse, warum sind dann in targetmap noch mehr Hindernisse dazugekommen?Selbst wenn die 1 im targetmap die begehbaren Felder sind wie unterscheidest du sie da von den Hindernissen? Also das Ergebnis kann ich leider nicht deuten^^" Wäre nett wenn du es erklären könntest...Danke im vorraus! |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ist denn das Feld nicht auch begehbar, wenn tepmMoveArr=0 ist?
Zitat: 'dann wird geprüft ob die aktuelle Position begehbar ist
If(tempMoveArr[posX,posY] = -1) Then Stell dir vor du hast 4 AP. X ist der Startpunkt. Z ist ein Punkt hinter einem Hindernis, der eigentlich erreichbar sein müsste. Der Algo beginnt z.b. so zu suchen: von x aus 2x nach links und dann 1x hoch Code: [AUSKLAPPEN] ...z.
.0.11 .00x1 ...11 bleibt noch 1 AP und der geht zufällig nach rechts, so: Code: [AUSKLAPPEN] ...z.
.0011 .00x1 ...11 dann kommt eine spätere Rekursion nie wieder auf diesen Weg: Code: [AUSKLAPPEN] ..00..
..011 ..0x1 ...11 Meiner Meinung nach muss es heißen: Zitat: 'dann wird geprüft ob die aktuelle Position begehbar ist
If(tempMoveArr[posX,posY] < 1 ) Then oder noch besser, du notierst in die Felder den AP-Verbrauch, den es bis hier gekostet hat. Vorbereitung: Zunächst bekommen alle verbotenen Felder einen geringen Wert (hier:0) Alle möglichen Felder den Wert 99. (Das wären in den Beispielen alle mit ".") Das Startfeld x erhält auch 99 Eine Rekursion braucht dann viele Felder nicht mehr zu testen, weil man "billiger" hierhin kam: Code: [AUSKLAPPEN] ...z.
...00 ...x0 ...00 nach 4 Zügen: Code: [AUSKLAPPEN] ...z.
.3400 .21x0 ...00 Andererseit wird sie das teuere 4-er Feld später noch einmal betreten dürfen: Code: [AUSKLAPPEN] ..34.
.3200 .21x0 ...00 Der Algo: Code: [AUSKLAPPEN] Springe in die Rekursion mit dem Startfeld (hier X).
Wenn der Wert des Feldes dort größer als dein AP-Verbrauch ist, nimm es ein und setze es den Wert gleich dem aktuellen AP-Verbrauch Starte von hier in alle 4 Richtungen mit um 1 verringertem Test-AP... ...und erhöhtem AP-Verbrauch aber wenn der Wert des Feldes kleiner ist (weil verboten=0 oder weil schon billiger) vergiß diesen Platz. 1 Rekursion zurück, dort die 3 anderen testen. Ende Wenn Der Vorteil dieser Rekursion ist, dass du im Code keine Rücksicht auf die vorangegangene Richtung nehmen musst. Du scanntst immer alle 4 Richtungen. Die aus der du hergekommen bist, hat ja schon einen niedrigeren AP-Wert: Angenommen du bist bis auf Feld 2 gekommen und checkst nun die Umgebung: Code: [AUSKLAPPEN] ...z.
...00 .21x0 ...00 dann checkt der algo zwar auch die richtung hin zur 1, aber es kommt nur dies in Frage: Code: [AUSKLAPPEN] ...z.
.3.00 321x0 .3.00 Versuch erst gar nicht den Code zu optimieren. Lass es die Rekursion machen! Die richtig schönen Rekursionen sehen immer supersimpel aus! |
||
- Zuletzt bearbeitet von Midimaster am Fr, Jan 15, 2010 12:13, insgesamt 3-mal bearbeitet
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Vielen Dank Midimaster ![]() Ich werd mir sobald ich Zeit hab anhand dessen mal einen Algorithmus implementieren. Übrigens KANN das Feld begehbar sein wenn es 0 ist, allerdings habe ich alle Felder die 0 waren -1 gesetzt damit ich später für den AStar den Unterschied zwischen dem im Radius begehbaren Feldern und den zwar begehbaren aber nicht erreichbaren Feldern versteht. Die Felder die nicht erreicht wurden werden nach dem Ermitteln des Bewegungsradius auf 1 gesetzt un dem AStar-Algo gegeben, damit er denkt, dass die nicht erreichbaren Felder Hindernisse sind.So wollte ich den Bewegungsbereich auf den Algo anpassen. Muss ich schauen in wie weit ich das mit deiner Variante anpassen muss. MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
jetzt hast du mich missverstanden:
ich spreche nur von dem temporären Feld. Dort dürfen während der Rekursion nicht schon die bereits "begangenen" Felder von weiteren Rekursionen ausgeschlossen werden. Alle Tipps, die ich dir gegeben habe beziehen sich nur auf das temporäre Feld und wie du darin "hinter" die Hindernisse kommst. |
||
- Zuletzt bearbeitet von Midimaster am Fr, Jan 15, 2010 11:16, insgesamt einmal bearbeitet
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Aso, gut..
Dank dir. Ich meld mich nochmal falls es immernoch nicht funktionieren will XD Ich versteh eine Sache nicht ganz: Wenn ich auf meinem tempMoveArray die Startposition -1 setze und dann die Rekursion mit dem Startpunkt(x,y) beginne, ergibt die Abfrage für mich keinen Sinn. Denn der aktuelle Wert des Feldes ist -1 somit KLEINER als die restAp(immer, da die restAp maximal 0 werden kann) also würde ja die zweite Bedingung zu tragen kommen. Aus deinem Pseudocode hab ichh aber verstanden, dass dies nicht für den ersten Fall sondern für alle folgende Fälle für die das gilt passieren soll... Kannst du mir nochmal sagen, wie genau der Algorithmus anfängt?Wäre sehr nett^^ MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
du hast recht, du hast zwei Fehler in meiner Denke gefunden:
1. beginne mit einer 99 auf der startpos! das war blöd von mir.... 2. Verglichen wird natürlich nicht mit dem Rest-Ap, sondern ob auf dem Feld bereits ein Verbrauch eingetragen worden war. Und der wird natürlich mit dem aktuellen Verbrauch verglichen. Danke für deine Hinweise! Hier ein Code-Versuch Starte so: Code: [AUSKLAPPEN] CheckField MyX, MyY, AP, 0
hier die Funktion: BlitzMax: [AUSKLAPPEN] Function CheckField(X%, Y%, AP%, Verbraucht%) |
||
- Zuletzt bearbeitet von Midimaster am Fr, Jan 15, 2010 14:35, insgesamt einmal bearbeitet
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hey, jetzt scheint es nach einigen Testreihen makellos zu funktionieren!
Vielen Dank für deine Mühen, echt klasse! ![]() Ich meld mich nochmal falls irgendwas nicht stimmt^^ MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi Skabus,
ich glaube Du hast die Ausgabe meines Codes nur falsch interpretiert. Die Einsen in TargetMap sind nicht Blockaden sondern eben die Felder innerhalb der Reichweite. Um das Ganze mal ein wenig deutlicher zu machen, habe ich die Routine so angepasst, dass sie die Menge an AP in die Karte einträgt welche nach dem Laufen übrigbleiben. Code: [AUSKLAPPEN] SuperStrict
Global map:Int[16 , 16] Global Targetmap:Int[16 , 16] map[3 , 3] = 1 map[4 , 3] = 1 map[5 , 5] = 1 Local startx:Int = 3 Local starty:Int = 4 Local range:Int = 4 fillmap(map,targetmap,startx,starty,range) drawmap(targetmap) Function isWalkable:Int(m:Int[,],x:Int,y:Int) If (x >=0) And (y>=0) And (x<16) And (y<16) Then If m[x , y] = 0 Then Return True EndIf End Function Function FillMap(source:Int[,],target:Int[,],x:Int , y:Int , range:Int) If isWalkable(source,x - 1 , y) Then If target[x - 1 , y] < range Then target[x - 1 , y] = range If range > 1 Then fillmap(source,target,x-1 , y , range - 1) EndIf If isWalkable(source,x + 1 , y) Then If target[x + 1 , y] < range Then target[x + 1 , y] = range If range > 1 Then fillmap(source,target,x+1 , y , range - 1) EndIf If isWalkable(source,x , y-1) Then If target[x , y-1] < range Then target[x , y-1] = range If range > 1 Then fillmap(source,target,x , y-1 , range - 1) EndIf If isWalkable(source,x , y+1) Then If target[x , y+1] < range Then target[x , y+1] = range If range > 1 Then fillmap(source,target,x , y+1 , range - 1) EndIf End Function Function drawmap(m:Int[,]) For Local y:Int = 0 Until 16 For Local x:Int= 0 Until 16 StandardIOStream.WriteString(String(m[x,y])) StandardIOStream.Flush() Next Next End Function Ich hoffe das wird nun deutlicher für Dich. So kann dein Charakter auf dem potentiellen Zielfeld nachschauen und erhält automatisch Rückmeldung ob er hinkann (AP>0) und zu welchen Kosten. Auch ein Anzeigen der Zielfelder wird so möglich: einfach ein farbiges Feld mit geringem Alpha über alle Felder zeichnen lassen welche >0 sind in der Targetmap. Zwei Dinge musst Du noch beachten: 1. Das Startfeld wird bei der Prüfung nicht ausgenommen, weshab es in der Regel zu einem AP weniger als den Maximalen angezeigt werden wird. Hier würde ich eine Manuelle Abfrage einbauen 2. Damit die 100% Routine korrekt arbeitet müsstest du entweder: a) die zur Verfügung stehenden AP für die Abfrage um eins erhöhen ODER b) Targetmap mit -1 initialisieren und die Abfragen in der Funktion so ändern dass sie bei 0 statt bei 1 anschlagen, da bislang die Bewegungsweite eins zu gering ist. Aber der Ansatz war ja auch nur hingesaut. Das ganze funktioniert mit einem winzigen bissel mehr Arbeit auch mit beliebigen Arraygrössen, ohne dass Du dazu weitere Angaben bräuchtest. HF. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
@BladeRunner
wie schon gesagt: Die richtig schönen Rekursionen sehen immer supersimpel aus! BlitzMax: [AUSKLAPPEN] CheckField StartX, StartY, AP, 0 |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
... nur hingesaut, midimaster, nur hingesaut ![]() Ich glaube nicht dass ich irgendwo behauptet habe mein Code sei das nonplusultra oder schön. Sonst noch Probleme damit? |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
doch keine Probleme! ![]() Sollst dir ja nur mal anschauen, wo man in einer Rekursion das Feld checkt! Dann fallen die Fallunterscheidungen weg. Auch der Sondercode fürs "Einsteigen" ist nicht nötig. Schon schön, oder? |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ist er bei mir nach einer kleinen Anpassung auch nicht, wie ich erwähnte. | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group