Roguelike-Diary (WIP ...)

Spiele, Demos, Grafikzeug und anderes unterhaltendes.
Benutzeravatar
diceman
Beiträge: 347
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Roguelike-Diary (WIP ...)

Beitrag von diceman »

Roguelike Diary 15: Lock&Key-System

Und wieder ein großer Fortschritt:
Mein Lock&Key-System steht!
Damit in einer prozedural erstellten Umgebung Schlüssel und verschlossene Türen funktionieren, muß man diese so platzieren, daß man am Ende tatsächlich jeden Teil des Dungeons "öffnen" kann.
Dafür habe ich mir folgende Routine ausgedacht:

A)
- Einen zufälligen Prozentsatz an Türen als "Lockable" flaggen.
- Für jede dieser Türen eine A*-Suche von der einen Seite der Tür zur anderen durchführen (Türfeld-Kollision auf #True setzen).
- Wenn ein Pfad existiert, ist die Tür nicht als "Lockable" geeignet, da man den Bereich dahinter auf einem alternativen Pfad durch eine unverschlossene Tür erreichen kann.
- Die verbliebenen Türfelder auf eine offene Liste setzen.
- Anschließend die Kollision aller Türfelder der offenen Liste auf #True setzen.

B)
- Mit A*-Pfadsuche vom Startpunkt aus alle Türfelder der offenen Liste versuchen anzusteuern.
- Alle Türfelder, die mit A* erreicht werden, auf eine sekundäre offene Liste setzen.
- Von der sekundären offenen Liste ein zufälliges Element herauspicken.
- Einen Schlüssel mit keyIndex 1, welcher die Koordinaten seines Zielfeldes kennt, im Dungeon verstecken (da alle übrigen Türfelder immer noch positive Kollision haben, kann man hier leicht mit A* überprüfen, daß der Schlüssel an einer erreichbaren Stelle platziert wurde).
- Die entsprechende Tür öffnen (Kollision entfernen) und von der offenen Liste löschen.
- keyIndex +1

C)
- Alle Punkte unter B solange wiederholen, bis keine Elemente auf der offenen Liste übrig sind.

D)
- Da "absolute" Schlüssel langweilig sind, bekommt jeder Schlüssel eine zufällige Farbe (1-4).
- Die dazugehörige Tür (der Schlüssel kennt die Koordinaten) erhält dieselbe Farbe.
- Jeder farbige Schlüssel kann jetzt jede Tür derselben Farbe öffnen.

Mit dieser Methode kann es ab und zu vorkommen, daß man sich selber den Weg zum Ausgang versperrt, da man die Schlüssel in falscher Reihenfolge verwendet; deswegen werde ich später alternative Möglichkeiten, Türen zu öffnen (Tür aufbrechen, Magie, etc.), sow und alternative Verwendungszwecke für nicht benutzte Schlüssel implementieren.
So "zwingt" man den Spieler zu interessanten Entscheidungen. :)




Weitere Features:
- Monster können unverschlossene Türen öffnen (bzw. versuchen es; wenn sie es nach mehreren Versuchen nicht schaffen, suchen sie einen Weg drumherum).
- Ein Teil des Dungeons kann "abgekapselt" werden (an Türfeldern ohne alternativen Rückweg)
- Der Übergang wird entfernt und beide Teile des Dungeons werden über einen Teleporter verknüpft.
- Wenn die Trennlinie durch eine verschlossene Tür geht, benutze ich die Koordinaten des zugehörigen Schlüssel als Referenz für den ersten Teleporter.
- In diesem Fall kommt der zuvor initialisierte keyIndex zum Tragen: alle Türen mit keyIndex < Index der Übergangstür werden geöffnet, dahinter bleibt alles verschlosen!
- Das Zielfeld ist niemals der Teleporter zurück, den muß man erst finden!
- Das Zielfeld für den ersten Teleporter ist gültig, wenn es per A*-Suche die Trennlinie erreichen kann, aber NICHT den ersten Teleporter (Kollision der Trennlinie auf #True setzen).
- Die Koordinaten des zweiten Teleporters sind gültig, wenn man per A* die Trennline UND das Zielfeld des ersten Teleporters erreichen kann.
- Das Zielfeld für den zweiten Teleporter ist gültig, wenn man per A* Trennline UND ersten Teleporter errechen kann.



Nächster Meilenstein:
Ein Message-System, mit dem man Texte und Informationen einblenden kann (z.B. Innschriften und Informationen über Items und Monster)
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Roguelike-Diary (WIP ...)

Beitrag von RSBasic »

Es wird ja immer besser. :allright:
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
diceman
Beiträge: 347
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Roguelike-Diary (WIP ...)

Beitrag von diceman »

Dankeschön. :)
Ja, es macht mir Spaß, PureBasic ist eine tolle Sprache, und ich mache große Fortschritte. Ich muß ehrlich sagen, daß ich bei den meisten Threads hier im Forum abschnalle, was ihr programmiertechnisch drauf habt ... wenn es zu "technisch" wird, verstehe ich das nicht mehr. Wo ich meine Stärken aber sehe, daß ist im Austüfteln von logischen Konstrukten (siehe oben die Schlüssel-Routine) und Optimieren von (bekannten) Algorithmen. Ich liebe außerdem das Jonglieren mit *pointern und die Interaktion von verschiedenen Listen-Elementen. Und ein Roguelike-Adventure mit zufällig erstelltem Content ist die Art von Herausforderung, welche mich zu Höchstleistungen aufstachelt.

Zum Beispiel habe ich gemerkt, daß der Bresenham-Algorithmus weitaus schönere Ergebnisse liefert, wenn man ihn an etwas längerer Leine laufen lässt ... der strenge Bresenham zieht jeweils eine Line vom Zentrum zu jedem Randfeld und berechnet die Ergebnisse dazwischen. Ich gönne dem Algorithmus etwas mehr Spielraum, indem ich das FieldOfView-Quadrat in einer For/Next-Schleife 3 mal verkleinere und die bresenMap() mit den neuen Ergebnissen "überschreibe".

Den Unterschied kann man unten sehen (westlich und südwestlich vom Spieler, sowie der Gang in Nordrichtung):

Strict Bresenham

Code: Alles auswählen

	Define x0 = limit(*player\x-lineOfSight,0,xMax)
	Define x1 = limit(*player\x+lineOfSight,0,xMax)
	Define y0 = limit(*player\y-lineOfSight,0,yMax)
	Define y1 = limit(*player\y+lineOfSight,0,yMax)

	y = y0
	For x = x0 To x1
		getBresenham(*player\x,*player\y,x,y,#True)
	Next
	x = x1
	For y = y0 To y1
		getBresenham(*player\x,*player\y,x,y,#True)
	Next
	y = y1
	For x = x1 To x0 Step -1
		getBresenham(*player\x,*player\y,x,y,#True)
	Next
	x = x0
	For y = y1 To y0 Step -1
		getBresenham(*player\x,*player\y,x,y,#True)
	Next
Bild


Loose Bresenham

Code: Alles auswählen

	For radius = 0 To 3
		y = y0+radius
		For x = x0 To x1
			getBresenham(*player\x,*player\y,x,y,#True)
		Next
		x = x1-radius
		For y = y0 To y1
			getBresenham(*player\x,*player\y,x,y,#True)
		Next
		y = y1-radius
		For x = x1 To x0 Step -1
			getBresenham(*player\x,*player\y,x,y,#True)
		Next
		x = x0+radius
		For y = y1 To y0 Step -1
			getBresenham(*player\x,*player\y,x,y,#True)
		Next
	Next
Bild
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Benutzeravatar
diceman
Beiträge: 347
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Roguelike-Diary (WIP ...)

Beitrag von diceman »

Roguelike Diary 16: Committing to a Color Palette

So langsam wird es Zeit, sich über ein Thema Gedanken zu machen ... wohin das alles mal führen soll.

Die Griechische Antike soll's sein, mit all ihren mythischen "Untiefen"!
In meinem Roguelike wacht man als Gefallener im Palast von Hades auf (3 Charakterklassen sollen später zur Wahl stehen: Hoplit, Amazone und Priesterin), wo einem der Gott der Unterwelt eine zweite Chance im Leben einräumt, wenn man sich in die Tiefen des Tartarus vorschlägt um dort Persephone zu finden, die auf einem ihrer nachmittaglichen Spaziergänge in den Abgrund gestürzt ist.

Und damit's auch atmosphärisch passt, gehört dazu eine stimmige Farbpalette; ich werde mich dabei sehr in der Auswahl an Farben beschränken, da dies einerseits meine Kreativität fördert, zum Zweiten ist Reduktion ein wichtiges Mittel um ein einheitliches Design zu gewährleisten. Den Rest erledigen die Alpha-Values vom Lichtradius um den Spieler (außerdem möchte ich bei statischen "Hintergrund"-Tiles (Boden/Mauern/Hindernisse) die Sättigung etwas herunterdrehen, so stehen die interaktiven Elemente besser heraus). Die entsprechenden Farbwerte habe ich bereits als Konstanten in meinen Code eingelesen, so daß sich auch die ingame verwendenten RGB-Befehle ausschließlich auf meine Palette beziehen:

Bild

Für die Sprites werde ich später "Aseprite" verwenden; das ist ein schönes Programm, mit dem man auch als Grafik-Noob (etwas Einarbeitungszeit und YT-Tutorials gucken vorausgesetzt) schnell mit klar kommt, und einen zudem nicht gleich mit 1001 Knöpfen und Optionen erschlägt. Bevor es soweit ist, werde ich aber noch etwas an meiner Core-Engine arbeiten.
Zuletzt geändert von diceman am 30.04.2018 02:42, insgesamt 3-mal geändert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Roguelike-Diary (WIP ...)

Beitrag von Mijikai »

Da kann ich RSBasic nur beipflichten :)
Bin gespannt auf die weiteren Schritte.
Jan125
Beiträge: 31
Registriert: 23.06.2013 06:26
Computerausstattung: Nicht lachen. Atom Z3775, 2GiB RAM, Win8.1.

Re: Roguelike-Diary (WIP ...)

Beitrag von Jan125 »

Wollt' mich eig schon früher wieder zuschalten, aber bisher nicht dazu gekommen...
Früh einsetzende Demenz oder so. D:
Wennst außerhalb von selbst kreiertem noch was brauchst, hab hier irgendwo noch ein paar Waffensprites rumliegen, falls an sowas Bedarf besteht. :>

Sonst noch: Sieht fein aus, weitermachen! :D
Wer braucht schon Unicode? PB5.24LTS
Benutzeravatar
diceman
Beiträge: 347
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Roguelike-Diary (WIP ...)

Beitrag von diceman »

Das ist ein sehr nette Angebot, aber das Designen von Pixelart-Sprites macht mir sogar Spaß (auch wenns nicht meine Stärke ist); Übung macht den Meister. :wink:
Ich suche mir ein reales Bild aus dem Internet und dann versuche ich es in klein zu reproduzieren (40x40 sind meine Tiles groß).

Hier sind ein paar Sprites, die ich designt habe, als das Projekt noch unter Blitzbasic lief. Ich habe sie an meine derzeitige Farbpalette angepasst.
Die Items kommen in 2 Ausfertigungen: einmal als inventoryObject (volle Größe), und einmal auf 75% skaliert (worldObject).

Food-Items:
Bild

Nahkampf-Items (von links nach rechts: Dolch, Axt, Kopis, Xiphos, Dory, Sarissa, Labris)
Bild
Zuletzt geändert von diceman am 26.04.2018 14:05, insgesamt 5-mal geändert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Roguelike-Diary (WIP ...)

Beitrag von ccode_new »

Sieht gut aus!
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
diceman
Beiträge: 347
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Roguelike-Diary (WIP ...)

Beitrag von diceman »

Roguelike Diary 17: Conveying Information
Kleiner Fail: Ja, ich weiß, es heißt "Pomegranate" und nicht "Pomgrenade". :coderselixir:

Meine createMessage()/displayMessage()-Routinen sind an Ort und Stelle. :-)
Ich habe das maximal modular auf die Beine gestellt - Größe des Canvas wird on the fly angepasst, abhängig von Schriftgröße, Zeilenlänge, Zeilenanzahl, verwendeten Fonts, etc.
Ganz egal was man dem Spieler mitteilen möchte und wie der Text formatiert wurde, es sieht immer schick aus!
Vielen Dank an PureBasic für die tollen TextWidth()/TextHeight()-Befehle! 8)
Der nächste Schritt sind interaktive InfoScreens, wo man eine Auswahl treffen kann ... das sollte nicht allzu schwer zu realisieren sein.
Bis zum Anfang nächster Woche möchte ich mit dem Text/Schrift-Routinen abgeschlossen haben.

Externe Grafiken werde ich erst effektiv einbinden, sobald ich meine MVP-Liste abgearbeitet habe; man braucht immer ein höheres Ziel auf das man hinarbeiten kann, das hält die Motivation oben!
Trotzdem hier noch, gerade frisch aus der Sprite-Factory eingetroffen, ein kleiner Hoplite-Krieger ... :)

Bild
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Benutzeravatar
diceman
Beiträge: 347
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Roguelike-Diary (WIP ...)

Beitrag von diceman »

Nix was man sehen kann, aber EffectActors funktionieren jetzt! 8)
Ein EffektActor kann alles mögliche sein; er ist ein Override zur natürlichen Verhaltensweise eines Actors, bzw. kann dessen Attribute verändern, und hat üblicherweise einen Timer, welcher Turns heraufzählt bis zu einem killLimit; wenn dieses erreicht ist, wird er gelöscht. EffectActors werden immer am Ende einer Runde, wenn jeder Actor seine "move" gemacht hat, getriggert. Ein Beispiel für einen EffectActor ist zum Beispiel ein "Bleeding-Effect"; ein anderes aktuelles Beispiel wäre der #ePathBlocker:

Wenn ein Monster dreimal erfolglos versucht hat, eine Tür zu öffnen, wird deren Kollision von der overrideCollison()-Prozedur von #removableCollision auf #pathCollision gesetzt, das heißt das Feld wird von der Liste möglicher begehbarer Tiles gelöscht, und auch der Dijkstra-Algorithmus wird entsprechend geupdated. In anderen Worten, die Monster müssen entweder aufgeben oder einen Weg drumherum suchen. Im selben Zuge wird an derselben Stelle ein #ePathBlocker erstellt mit einem killLimit von Random(50,10).
EffectActors sind alleine auf sich gestellt nutzlos, daher haben sie immer einen ParentActor, dem sie zugeteilt werden; im oben angeführten Beispiel wäre das die Tür. Und weil ich es so eingerichtet habe, daß im Falle eines "Ablebens" eines Actors alle assoziierten ChildActors mit gelöscht, respektive, wenn es sich um itemActors handelt, gedroppt werden, entfällt hier jeglicher Verwaltungsaufwand, das erledigen die Actors zuverlässig unter sich. Wenn also der Timer des EffectActors sein killLimit erreicht, wird er gelöscht und der Pfad wird wieder freigegeben, das heißt Monster können erneut versuchen, die Tür zu öffnen; ebenso, wenn der Spieler zwischendurch die Tür selbst öffnet, wird sie effektiv "getötet" und durch eine neue Tür mit Status offen ersetzt, das heißt der assoziierte EffektActor verschwindet ebenfalls.
:bounce:

Und hier noch was zum Gucken:
Loot-Boxen in den Wertigkeiten Holz, Silber und Gold; jeweils in geschlossenem, offenen und beschädigtem Zustand( wenn der Spieler sie mit Gewalt öffnen wollte und versagt hat). ;-)

Bild
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Antworten