Roguelike-Diary (WIP ...)
Re: Roguelike-Diary (WIP ...)
Wer Lust hat, darf's nochmal testen, ich glaube es steuert sich jetzt besser ...
- Der Camera-Center ist jetzt absolut, und wenn man sich bewegt, bewegt sich die Kamera in Relation zum Spieler mit.
- Mit den Taste W,A,S,D kann man die Kamera in die entsprechende Richtung "schwenken". Und zwar nicht mehr sprunghaft, sondern fließend.
- Leertaste zentriert den Viewport wieder zurück auf den Spieler.
- Irgendwann, wenn mal ein Menü existiert, könnte man den Spieler noch ein Häkchen setzen lassen zum optionalen Invertieren der Kamera-Steuerung.
Außerdem:
- Wenn man der Mauszeiger das Fenster verlässt, wird automatisch die Windows-Maus aktiviert.
- Ein Klick (rechte oder linke Maustaste) irgendwo aufs Fenster re-aktiviert die Spieloberfläche.
DOWNLOAD
Vielen Dank!
- Der Camera-Center ist jetzt absolut, und wenn man sich bewegt, bewegt sich die Kamera in Relation zum Spieler mit.
- Mit den Taste W,A,S,D kann man die Kamera in die entsprechende Richtung "schwenken". Und zwar nicht mehr sprunghaft, sondern fließend.
- Leertaste zentriert den Viewport wieder zurück auf den Spieler.
- Irgendwann, wenn mal ein Menü existiert, könnte man den Spieler noch ein Häkchen setzen lassen zum optionalen Invertieren der Kamera-Steuerung.
Außerdem:
- Wenn man der Mauszeiger das Fenster verlässt, wird automatisch die Windows-Maus aktiviert.
- Ein Klick (rechte oder linke Maustaste) irgendwo aufs Fenster re-aktiviert die Spieloberfläche.
DOWNLOAD
Vielen Dank!
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.
Re: Roguelike-Diary (WIP ...)
So gefällt es mir auf jeden Fall Besser
Re: Roguelike-Diary (WIP ...)
Mir ist übrigens grad aufgefallen, daß die Kamerabewegung nach rechts und links Blödsinn ist.
Die maximal mögliche Sichtweite ist ohnehin anhand der x-Achse gebalanced; eigentlich muß man nur nach oben und unten sehen können.
Das Mausrad würde sich hier anbieten ... das sind jetzt aber tatsächlich kleine QoL-Tweaks, an denen ich mich nicht lange aufhalten möchte.
Bin euch jedenfalls zu Dank verpflichtet - so ganz ohne Feedback kann man schnell Tunnelblick bekommen und sich mit dem kleinsten Übel zufrieden geben.
Eine gute, intuitive Steuerung ist mir nicht ganz unwichtig.
Die maximal mögliche Sichtweite ist ohnehin anhand der x-Achse gebalanced; eigentlich muß man nur nach oben und unten sehen können.
Das Mausrad würde sich hier anbieten ... das sind jetzt aber tatsächlich kleine QoL-Tweaks, an denen ich mich nicht lange aufhalten möchte.
Bin euch jedenfalls zu Dank verpflichtet - so ganz ohne Feedback kann man schnell Tunnelblick bekommen und sich mit dem kleinsten Übel zufrieden geben.
Eine gute, intuitive Steuerung ist mir nicht ganz unwichtig.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.
Re: Roguelike-Diary (WIP ...)
So ist es definitiv schon mal besser.
Weiter verbessern kann man im laufe des Projektes immer noch.
Weiter verbessern kann man im laufe des Projektes immer noch.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: Roguelike-Diary (WIP ...)
***** VIDEO *****
Roguelike Diary 05: Basic Monster Intelligence
Ein paar graue Haare später ...
Monster haben jetzt Verhaltensmuster und einen ersten (simplen) KI-Baum:
Die Pfadsuche habe ich mit einer Dijkstra-Map umgesetzt. Dijkstra-Maps sind toll, weil man die nur einmal pro Zug updaten muß und trotzdem für alle Monster gültig sind. Und wenn man alle Werte einer fertig berechnete Dijkstra-Map mit -1.2 multipliziert, und das Ergebnis erneut scannt, erhält man eine gewichtete Safety-Map: effektiv wird die Pfadsuche geflippt und weiter entlegene Felder bekommen einen "Safety-Bonus", was die Monster zum Rückzug bewegt.
Das funktioniert in 70% aller Fälle recht ordentlich; manchmal aber waren die Monster in einer "kognitiven" Dissonanz gefangen, so daß sie immer abwechselnd einen Fluchtschritt und wieder einen Schritt zum Spieler hin machten.
Der entscheidene Durchbruch kam dann mit der Idee, daß sich jeder Actor seine 4 zuletzt beschrittenen Felder merkt, und für solche Felder einen "Penalty-Bonus" zu der Dijkstra-Flucht-Map addiert! Das jeweils zuletzt betretene Feld bekommt dabei den größten "Strafwert", und nach jedem Schritt findet ein sogennanter "Penalty-Decay" statt, d.h. die Strafwerte nehmen ab, je länger ein Feld nicht betreten wurde:
Das Ergebnis seht ihr oben.
Und wer mehr über Dijkstra-Maps und deren Anwendung erfahren möchte, dem empfehle ich diese beiden Artikel auf roguebasin.com:
• The Incredible Power of Dijkstra Maps
• Dijkstra Maps Visualized
Roguelike Diary 05: Basic Monster Intelligence
Ein paar graue Haare später ...
Monster haben jetzt Verhaltensmuster und einen ersten (simplen) KI-Baum:
Code: Alles auswählen
If canSee(actor()\x,actor()\y,*player\x,*player\y)
actor()\tactic = 1 ;Engage
If actor()\hp = 1
actor()\tactic = 0 ;Flee
EndIf
Else
actor()\tactic = 2 ;Idle (move randomly)
EndIf
Das funktioniert in 70% aller Fälle recht ordentlich; manchmal aber waren die Monster in einer "kognitiven" Dissonanz gefangen, so daß sie immer abwechselnd einen Fluchtschritt und wieder einen Schritt zum Spieler hin machten.
Der entscheidene Durchbruch kam dann mit der Idee, daß sich jeder Actor seine 4 zuletzt beschrittenen Felder merkt, und für solche Felder einen "Penalty-Bonus" zu der Dijkstra-Flucht-Map addiert! Das jeweils zuletzt betretene Feld bekommt dabei den größten "Strafwert", und nach jedem Schritt findet ein sogennanter "Penalty-Decay" statt, d.h. die Strafwerte nehmen ab, je länger ein Feld nicht betreten wurde:
Code: Alles auswählen
For r = 0 To #recentMovesMax
If actor()\x+xMod(dir) = actor()\xRecent[r] And actor()\y+yMod(dir) = actor()\yRecent[r]
chooseDirection()\value[1] + (((#recentMovesMax+1)-r)*2)
EndIf
Next
Und wer mehr über Dijkstra-Maps und deren Anwendung erfahren möchte, dem empfehle ich diese beiden Artikel auf roguebasin.com:
• The Incredible Power of Dijkstra Maps
• Dijkstra Maps Visualized
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.
Re: Roguelike-Diary (WIP ...)
Von sowas habe ich in Blitzbasic immer geträumt ... On the fly Alpha mapping!
Roguelike Diary 06: More Alpha Map Testing
Den Sichtradius für den Bresenham-Algorithmus halte ich jetzt immer maximal, und regele die effektive Sichtweite (abhängig von Leuchtquellen, die der Spieler bei sich trägt) ausschließlich über Alpha Mapping (für jedes Tile überprüfe ich mit dem Satz des Pythagoras, in welchem Abstand es sich zum Spieler befindet, und regele so die Leuchtstärke). Spielerisch habe ich einige Ideen, z.B. kann man so Schüsse ins "Blaue" abgeben, oder externe Leuchtquellen im Dungeon können ihren eigenen Leuchtradius haben (muß man nur einmal beim Betreten des Dungeons mit dem Bresenham-Algorithmus initialisieren, ergo keine Geschwindigkeitseinbußen), und man kann deren Alpha Mapping-values zum Leuchtradius des Spielers aufaddieren.
Aber damit will ich mich jetzt (noch) nicht aufhalten - der nächste Milestone sind aggressive Monster (bis jetzt liefen die Kämpfe recht einseitig ab).
Roguelike Diary 06: More Alpha Map Testing
Den Sichtradius für den Bresenham-Algorithmus halte ich jetzt immer maximal, und regele die effektive Sichtweite (abhängig von Leuchtquellen, die der Spieler bei sich trägt) ausschließlich über Alpha Mapping (für jedes Tile überprüfe ich mit dem Satz des Pythagoras, in welchem Abstand es sich zum Spieler befindet, und regele so die Leuchtstärke). Spielerisch habe ich einige Ideen, z.B. kann man so Schüsse ins "Blaue" abgeben, oder externe Leuchtquellen im Dungeon können ihren eigenen Leuchtradius haben (muß man nur einmal beim Betreten des Dungeons mit dem Bresenham-Algorithmus initialisieren, ergo keine Geschwindigkeitseinbußen), und man kann deren Alpha Mapping-values zum Leuchtradius des Spielers aufaddieren.
Aber damit will ich mich jetzt (noch) nicht aufhalten - der nächste Milestone sind aggressive Monster (bis jetzt liefen die Kämpfe recht einseitig ab).
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.
Re: Roguelike-Diary (WIP ...)
Eine Monster-KI muß gut geplant werden, damit es hinterher keine bösen Überraschungen gibt. Die Abfragen und Konsequenzen sind fertig programmiert, jetzt muß alles auf logische Art und Weise verknüpft werden ... und ich wollte nur einen einzigen KI-Baum, der für alle Monster gleich gültig ist, nur die variablen Parameter werden "hinzugeladen".
Habe daher einen "trockenen" Konzept-Code aufgestellt, mit dem ich verschiedene Bedingungen und deren Konsequenzen überprüfen kann:
Habe daher einen "trockenen" Konzept-Code aufgestellt, mit dem ich verschiedene Bedingungen und deren Konsequenzen überprüfen kann:
Code: Alles auswählen
;Neue, noch zu erstellende Actor-Attribute:
Define moraleLowerLimit ;wenn Lebensenergie moraleLowerLimit (prozentualer Wert) unterschreitet, FLEE-Modus einleiten
Define moraleUpperLimit ;wenn Lebensenerge > moraleUpperLimit (prozentualer Wert), FLEE-Modus beenden
Define fleeCounter ;Fluchtschritte im FLEE-Modus werden gezählt
Define fleeLimit ;Wenn Fluchtschritte = fleeLimit, FLEE-Modus beenden
Define minSafeDistance ;Mindest-Abstand zum Gegner (für Fernkampf-Gegner). Wenn unterschritten, temporär in Fluchtmodus wechseln
Define hasMeleeAbility ;kann Nahkampfangriffe ausführen
Define hasRangedAbility ;kann Fernkampfangriffe ausführen
Define meleeKiteChance ;Chance auf Flucht Spieler im Nahkampf anzugreifen
Define rangedKiteChance ;Chance auf Flucht Spieler aus der Distanz anzugreifen
Define repositionChance ;Chance, statt Angriff auszuführen, neue Position zu finden
Define approachChance ;Chance, beim Annähern zufälligen Move zu machen
Define standStillChance ;Chance im IDLE-Modus stehenzubleiben
Define searchChance ;Chance, wenn Spieler aus den Augen verloren, in den SEARCH-Modus zu wechseln
Define randomFleeChance ;Chance, wenn canSeePlayer = #False, im FLEE-Mode zufälligen Move zu machen
Define FLEE ;Monster ist im permanenten Flucht-Modus
Define TARGET_AQUIRED ;speichert den zuletzt bekannten Spieler-Standort
Define SEARCH ;Monster im SEARCH-Mode versuchen (mittels aStar) den zuletzt bekannten Spieler-Standort zu lokalisieren
;kann extern getriggert werden, wenn Monster z.B. ein verdächtiges Geräusch gehört (braucht TARGET_AQUIRED)
Define IDLE ;Monster im IDLE-Mode machen entweder eine zufällige Bewegung oder bleiben stehen
selectMove = 0
selectAttack = 0
If FLEE
If hp > moraleUpperLimit Or fleeCounter = fleeLimit
FLEE = #False
IDLE = #True
TARGET_AQUIRED = 0
SEARCH = #False
EndIf
Else
If hp < moraleLowerLimit
FLEE = #True
fleeCounter = 0
TARGET_AQUIRED = 0
SEARCH = #False
IDLE = #False
EndIf
EndIf
If canSeePlayer
IDLE = #False
SEARCH = #False
TARGET_AQUIRED = playerLocation
If hasRangedAbility
If distance < minimumSafeDistance Or FLEE
If inMeleeRange
If hasMeleeAbility And Random(100) <= meleeKiteChance
selectAttack = 1
Else
fleeCounter +1
selectMove = 2
EndIf
Else
If isNotBlocked And Random(100) <= rangedKiteChance
selectAttack = 2
Else
fleeCounter +1
selectMove = 2
EndIf
EndIf
Else
If targetInRange
If isNotBlocked
If Random(100)<= repositionChance
selectMove = 3
Else
selectAttack = 2
EndIf
Else
selectMove = 3
EndIf
Else
If Random(100) <= approachChance
selectMove = -1
Else
selectMove = 1
EndIf
EndIf
EndIf
Else
If Not FLEE
If hasMeleeAbility
If Not inMeleeRange
If Random(100) <= approachChance
selectMove = -1
Else
selectMove = 1
EndIf
Else
If Random(100) <= repositionChance
selectMove = 1
Else
selectAttack = 1
EndIf
EndIf
Else
selectMove = -1
EndIf
Else
If inMeleeRange and hasMeleeAbility And Random(100) <= meleeKiteChance
selectAttack = 1
Else
fleeCounter +1
selectMove = 2
EndIf
EndIf
EndIf
Else
If Not FLEE
If SEARCH = #False
If TARGET_AQUIRED
If Random(100) <= searchChance
SEARCH = #True
Else
IDLE = #True
EndIf
Else
IDLE = #True
EndIf
EndIf
If SEARCH = #True
If standingOnLastKnownLocation
IDLE = #True
Else
selectMove = 4
EndIf
EndIf
Else
fleeCounter +1
If Random(100) < randomFleeChance
selectMove = -1
Else
selectMove = 2
EndIf
EndIf
EndIf
If IDLE = #True
TARGET_AQUIRED = 0
SEARCH = #False
FLEE = #False
If Random(100) > standStillChance
selectMove = -1
EndIf
EndIf
If selectMove
Select selectMove
Case -1 : Debug "Random Move"
Case 1 : Debug "Approach"
Case 2 : Debug "Move Away"
Case 3 : Debug "Reposition"
Case 4 : Debug "aStar to LastKnownLocation"
EndSelect
Else
If selectAttack
Select selectAttack
Case 1 : Debug "Perform Melee"
Case 2 : Debug "Perform Ranged"
EndSelect
EndIf
EndIf
Zuletzt geändert von diceman am 19.03.2018 23:07, insgesamt 1-mal geändert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.
Re: Roguelike-Diary (WIP ...)
Hi,
es macht vielleicht sinn mal mit Konstanten anzufangen. Dann ist das Programm besser lesbar als nur mit Zahlen.
es macht vielleicht sinn mal mit Konstanten anzufangen. Dann ist das Programm besser lesbar als nur mit Zahlen.
Code: Alles auswählen
; Meine Konstante
Enumeration -1
#Move_Random
#Move_Null
#Move_Approach
#Move_Away
#Move_Reposition
#Move_LastKnownLocation
EndEnumeration
Enumeration
#Attack_Null
#Attack_PerformMelee
#Attack_PerformRanged
EndEnumeration
Debug "Move Const"
Debug #Move_Random
Debug #Move_Null
Debug #Move_Approach
Debug #Move_Away
Debug #Move_Reposition
Debug #Move_LastKnownLocation
Debug "Attack Const"
Debug #Attack_Null
Debug #Attack_PerformMelee
Debug #Attack_PerformRanged
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Roguelike-Diary (WIP ...)
Ja, das ergibt Sinn.
Muß dazu sagen, daß ich das im Hauptprogramm schon stellenweise nutze; aber noch nicht konsequent genug, da geht noch mehr.
Das mit der automatischen Enumeration kannte ich aber noch nicht, bzw. habe ich mich bislang nicht beschäftigt.
Sieht nützlich aus, ich gucks mir gleich mal an!
//EDIT:
Ist super!
Vielen Dank für den Tip!
Das da oben ist allerdings eher Pseudo-Code, den habe ich zur Planung verwendet.
War trotzdem eine gute Idee, das vorher "trocken" hinzuschreiben, dafür fluppt es mit der praktischen Implementierung jetzt umso besser.
Gehe es aber vorsichtig an, und teste nach jedem neuen Schritt, ob auch wirklich alles ordnungsgemäß funktioniert.
Muß dazu sagen, daß ich das im Hauptprogramm schon stellenweise nutze; aber noch nicht konsequent genug, da geht noch mehr.
Das mit der automatischen Enumeration kannte ich aber noch nicht, bzw. habe ich mich bislang nicht beschäftigt.
Sieht nützlich aus, ich gucks mir gleich mal an!
//EDIT:
Ist super!
Vielen Dank für den Tip!
Das da oben ist allerdings eher Pseudo-Code, den habe ich zur Planung verwendet.
War trotzdem eine gute Idee, das vorher "trocken" hinzuschreiben, dafür fluppt es mit der praktischen Implementierung jetzt umso besser.
Gehe es aber vorsichtig an, und teste nach jedem neuen Schritt, ob auch wirklich alles ordnungsgemäß funktioniert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.
Re: Roguelike-Diary (WIP ...)
Die KI steht!
Was noch fehlt, ist der "Search-Modus", welcher Monster die zuletzt bekannte Position des Spielers aufsuchen lässt, sobald sie diesen aus den Augen verlieren.
Und wer mag, darf auch nochmal testen:
DOWNLOAD
• Ihr habt 1Mio. Lebenspunkte, das sollte reichen um zu überleben.
• Es gibt 3 Monster: 1x recht langsames (bewegt sich primär orthogonal) Nahkampf-Monster, das aber viel einstecken kann, 1x wendiges (mag gerne diagonale Richtungen) Flugmonster, und 1x Fernkampf-Monster.
• Monster werden erst aktiv, sobald sie Sicht zum Spieler haben.
• Fernkampf-Monster suchen sich aktiv Positionen, von denen aus sie den Spieler beharken können, und versuchen gleichzeitig Abstand zu halten.
• Wenn ein Monster zuviel Schaden einstecken mußte, versucht es zu fliehen; Monster haben eine 50% Chance pro Schritt 1 Lebenspunkt zu regenerieren.
• Wenn sich ein Monster erholt hat (oder nach einer gewissen Anzahl von Fluchtschritten) wechselt es wieder in den "Idle"-Modus
• Es gibt noch keine Waffen oder "richtiges" Gameplay: rechter Mausklick initiiert entweder einen Nahkampf- oder einen Fernkampf-Angriff, je nachdem wie ihr steht.
• Linksklick auf den Spieler selbst lässt euch eine Runde aussetzen (man kann auch gedrückt halten).
• Wenn ihr "eingesperrt" startet, dann einfach schließen (mit ESC) und neu starten. Dann gibts einen neuen Dungeon.
• Mit den W,S,A,D-Tasten könnt ihr die Kamera etwas schwenken für weitere Sicht (Fenstergröße ist 1024*768 - könnte ich on the fly anpassen; für manche Laptops ist das evtl. zu groß und der untere Rand vom Fenster verschwindet in der Taskleiste)
• Leertaste zentriert die Sicht
• Mit + und - könnt ihr den Sichtradius verringern, bzw. vergrößern.
• Wenn ihr den Mauszeiger vom Fenster runterbewegt, wird die Maus automatisch freigegeben. Um weiter zu spielen, einfach auf dem Fenster irgendeinen Klick ausführen.
Next milestone: Items!
Was noch fehlt, ist der "Search-Modus", welcher Monster die zuletzt bekannte Position des Spielers aufsuchen lässt, sobald sie diesen aus den Augen verlieren.
Und wer mag, darf auch nochmal testen:
DOWNLOAD
• Ihr habt 1Mio. Lebenspunkte, das sollte reichen um zu überleben.
• Es gibt 3 Monster: 1x recht langsames (bewegt sich primär orthogonal) Nahkampf-Monster, das aber viel einstecken kann, 1x wendiges (mag gerne diagonale Richtungen) Flugmonster, und 1x Fernkampf-Monster.
• Monster werden erst aktiv, sobald sie Sicht zum Spieler haben.
• Fernkampf-Monster suchen sich aktiv Positionen, von denen aus sie den Spieler beharken können, und versuchen gleichzeitig Abstand zu halten.
• Wenn ein Monster zuviel Schaden einstecken mußte, versucht es zu fliehen; Monster haben eine 50% Chance pro Schritt 1 Lebenspunkt zu regenerieren.
• Wenn sich ein Monster erholt hat (oder nach einer gewissen Anzahl von Fluchtschritten) wechselt es wieder in den "Idle"-Modus
• Es gibt noch keine Waffen oder "richtiges" Gameplay: rechter Mausklick initiiert entweder einen Nahkampf- oder einen Fernkampf-Angriff, je nachdem wie ihr steht.
• Linksklick auf den Spieler selbst lässt euch eine Runde aussetzen (man kann auch gedrückt halten).
• Wenn ihr "eingesperrt" startet, dann einfach schließen (mit ESC) und neu starten. Dann gibts einen neuen Dungeon.
• Mit den W,S,A,D-Tasten könnt ihr die Kamera etwas schwenken für weitere Sicht (Fenstergröße ist 1024*768 - könnte ich on the fly anpassen; für manche Laptops ist das evtl. zu groß und der untere Rand vom Fenster verschwindet in der Taskleiste)
• Leertaste zentriert die Sicht
• Mit + und - könnt ihr den Sichtradius verringern, bzw. vergrößern.
• Wenn ihr den Mauszeiger vom Fenster runterbewegt, wird die Maus automatisch freigegeben. Um weiter zu spielen, einfach auf dem Fenster irgendeinen Klick ausführen.
Next milestone: Items!
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.