Verbesserungen für ein reines Textadventure
Übersicht

MasterCoderGanonBetreff: Verbesserungen für ein reines Textadventure |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo liebe Programmierer Gemeinde.
ich bin schon sehr lange Fan von PenAndPaper-Spielen, wem das etwas sagt, und weil ich als Leidenschaftlicher Spielleiter meine Kreationen sehr gerne ins digitale Umwandeln würde und außerdem keine großen Erfahrungen mit dem Programmieren von Spielen habe bin ich zu Blitz Basic gekommen. Nach kurzer Einarbeitungszeit sah ich mich in der Lage loszulegen und ich bin soweit schon ganz zufrieden, dafür dass ich keine Erfahrung habe. Ich habe zwar bis jetzt noch nicht viel vom Gesamtwerk geschafft, jedoch könnte ich so schon bis zum ende weiter machen. Damit komme ich auch zum Grund dieses Foren-Beitrages. Denn bevor ich jetzt so weiter mache würde ich gerne einige Punkte klären und Anregungen einbringen um die Spielerfahrung zu optimieren. 1.Grafiken werde ich noch Einfügen, da ich die jedoch selber machen will, werde ich dies zum Schluss machen.(Muss ich da irgendwas wichtiges beachten. 2. Wäre es Sinvoll die einzelnen Passagen mit Funktionen ineinander zu verschachteln?(Funktion 1 führt zu Funktion 2 oder 3) 3. Ist die Schleife mit dem Counter für mögliche falscheingaben sinnvoll?(nicht im Sinne von Zweckmäßig sondern eher in Hinsicht auf PLatz, Übersichtlichkeit und Arbeitsspeicher) Ich wäre sehr dankbar für eure Hilfe ![]() Code: [AUSKLAPPEN] Graphics 800,600,0,1
SeedRnd MilliSecs () ;AlphaFenster/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Print "Liebe Alpha-Testerinnen und Tester." Print "Bei dieser Version handelt es sich um eine Alpha. Das heißt, dass das Spiel noch große Lücken hat." Print "Da gerade, dass programmieren von Spielen mit vielen Möglichkeiten sehr komplex ist bitte ich Lücken" Print "in der Handlung zu Entschuldigen und zu melden." Print "Nun aber viel Spaß." WaitKey Cls ;AlphaFenster/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Locate 0, 0 Print "Hey Kumpel. Du hast wohl gehört, dass wir einen neuen Zombie-Schlächter suchen, was?" Print "Sag mal... Wie heißt du? Name$ = Input() Print "Aha " + Name + " ist ein netter Name. Der Name eines Zombie-Töters." Print "Aber ich muss dich noch etwas fragen bevor wir oder besser gesagt du loslegen kannst." ;Der Spieler wird gefragt ob er die Vorgeschichte kennt./////////////////////////////////////////////////////////////////////////////////////// Print "Hast du schon jemals zuvor Tears gespielt " + Name + "?" Default_Counter = 0 Repeat Vorgeschichtenabfrage$ = Input("Ja oder Nein: ") Print "" If Vorgeschichtenabfrage = "Ja" Or Vorgeschichtenabfrage = "JA" Or Vorgeschichtenabfrage = "ja" Default_Counter = Default_Counter +1 Print "Dann lass uns Anfangen" ElseIf Vorgeschichtenabfrage = "Nein" Or Vorgeschichtenabfrage = "nein" Or Vorgeschichtenabfrage = "NEIN" Default_Counter = Default_Counter +1 Print "Dann hör mal gut zu." Print "Vorgeschichte:" Else Print "Ungültige Eingabe." EndIf Until Default_Counter = 1 WaitKey Cls ;Der Spieler wird gefragt ob er die Vorgeschichte kennt./////////////////////////////////////////////////////////////////////////////////////// ;Die Charakterbestimmung erfolgt./////////////////////////////////////////////////////////////////////////////////////////////////////////////// Locate 0, 0 Charakterfrage_1_Counter = 0 Print "Aber " + Name + " bevor du entgültig loslegen kannst brauchst du noch eine neue Persönlichkeit. Print "Möchtest du einen vordefinierten Charakter? Default_Counter = 0 Repeat Charakterfrage_1$ = Input("Ja oder Nein: ") If Charakterfrage_1 = "Ja" Or Charakterfrage_1 = "JA" Or Charakterfrage_1 = "ja" Default_Counter = Default_Counter + 1 Print "Du hast die Wahl zwischen den folgenden Charakteren: Print "Da wäre Lisa, die hübsche ehemalige Psychologie- und Mathematik Professorin. Print "Oder Armin, der einschüchternde Ex-Navi Seal und Überlebenskünstler. Charakterfrage_1_Counter = Charakterfrage_1_Counter + 1 ElseIf Charakterfrage_1 = "Nein" Default_Counter = Default_Counter + 1 Charakterfrage_1_Counter = Charakterfrage_1_Counter + 2 Else Print "Ungültige Eingabe." EndIf Until Default_Counter = 1 ;Funktion vordefinierter Charakter************************************************************************************************************** Repeat If Charakterfrage_1_Counter = 1 Default_Counter = 0 Charakterfrage_2$ = Input("Drücke L für Lisa oder A für Armin: ") EndIf If Charakterfrage_2 = "L" Or Charakterfrage_2 = "l" Default_Counter = Default_Counter + 1 Print "Ok. Lisa wird nun zu " + Name + "." Print "Jetzt kann alles losgehen." ElseIf Charakterfrage_2 = "A" Or Charakterfrage_2 = "a" Default_Counter = Default_Counter + 1 Print "Ok. Armin wird nun zu " + Name + "." Print "Jetzt kann alles losgehen." Else Print "Ungültige Eingabe." EndIf Until Default_Counter = 1 ;Funktion vordefinierter Charakter************************************************************************************************************** ;Funktion eigener Charakter********************************************************************************************************************* Fehlt noch ;Funktion eigener Charakter********************************************************************************************************************* WaitKey ;Die Charakterbestimmung erfolgt./////////////////////////////////////////////////////////////////////////////////////////////////////////////// ;Die Szene im Keller von Gebäude A.///////////////////////////////////////////////////////////////////////////////////////////////////////////// Cls Locate 0, 0 Print "Du wachst langsam und mit schmerzenden Knochen auf. Print "Du befindest dich nicht in deinem Bett im Hotel von Neu-Anfang sondern in einem kalten Keller." Print "Nur durch zugezimmerte Fenster fällt etwas Licht." Print "Neben dir befinden sich noch drei weitere Personen in diesem Keller, die aber noch schlafen." Default_Counter = 0 Repeat Handlungsfrage_1$ = Input("Möchtest du dich UMSEHEN, WARTEN oder die anderen WECKEN?: ") Knall_Counter_Frage = 0 Print "" If Handlungsfrage_1 = "Umsehen" Default_Counter = Default_Counter + 1 Print "Als du dich umsiehst siehst du, dass es außer euch Vieren nur eine Tür in diesem Raum gibt." Print "Nachdem du dich umgesehen hast ertönt in der Ferne ein lauter Knall, der die Anderen weckt." Print "Möchtest du Versuchen den Knall zu identifizieren?" Knall_Counter_Frage = Knall_Frage + 1 ElseIf Handlungsfrage_1 = "Warten" Default_Counter = Default_Counter + 1 Print "Nachdem du eine Zeit lang gewartet hast hörst du einen sehr lauten Knall in weiter Ferne." Print "Möchtest du Versuchen ihn zu identifizieren? Knall_Counter_Frage = Knall_Counter_Frage + 1 ElseIf Handlungsfrage_1 = "Wecken" Default_Counter = Default_Counter + 1 Print "Du weckst die Anderen und Ihr stellt euch gegenseitig vor." Print "Die drei Personen heißen Dieter, Anna-Maria und Steffen." Print "Während ihr euch noch gegenseitig vorstellt hört ihr einen lauten Knall in der Ferne." Print "Dieter kann es eindeutig als Explosion eines Treibstofftanks identifizieren" Print "und Anna-Maria erinnert sich, dass das Osttor von Neu-Anfang heute einen neuen Treibstofftank" Print "bekommen sollte." Print "" Print "Während ihr noch darüber rätselt, was am Osttor passiert ist, hört ihr vor der Tür zwei Männer." Else Print "Ungültige Eingabe." EndIf Until Default_Counter = 1 Knallfrage = 0 If Knall_Counter_Frage = 1 Knall_Frage = Input("Ja oder Nein?: ") Else Knall_Frage = 524 EndIf If Knallfrage = "Ja" Or Knallfrage = "JA" Or Knallfrage = "ja" ElseIf Knallfrage = "Nein" Or Knallfrage = "nein" Or Knallfrage = "NEIN" Print "Du entscheidest dich gegen die Identifizierung." EndIf WaitKey End |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mehrerlei:
Vermeide Print und Input, nimm stattdessen Text ![]() Print und Input nutzen immer den Frontbuffer, das wird spätestens wenn Du noch teilanimierte Grafiken zeigen willst zum Problem. Deine Abfragen sind sehr rudimentär. Statt auf "Ja" "ja" "JA" zu prüfen kannst Du die Eingabe zB. mittles lower ![]() Grundsätzlich kannst Du schon so weitermachen, aber es wird schnell ein Riesenwust von Verkettungen. Daher wäre es sinnig sich gedanken zu machen immer wieder kehrende Teile in Funktionen auszulagern. Bei einem klassischen Adventure wären das: Eingabe, Parsen und Auswertung. Eingabe und Parsen sind immer gleich, lediglich die Auswertung muss angepasst an Ort und Inventar des Spielers erfolgen. So lässt sich massenhaft redundanter Code vermeiden. Ein simpler Parser zerlegt die Eingabe in einzelne Worte (suchen mittels instr ![]() ![]() komplexere Befehlseingaben lassen sich eigentlich immer auf die Maximalform Verb, Objekt1, Objekt2 zurückführen: Lege das Schwert in die Truhe wird zu: Lege - Verb das, in, die sind Füllwörter, die ignoriert werden. Schwert und Truhe sind dann die beiden Objekte. Nun kann für jedes Verb und jedes Objekt eine Konstante vergeben werden. Nehmen wir an, lege hätte den Wert 3 bei Verben, Schwert den Wert 1 bei Objekten und Truhe die 3 bei Objekten, dann würde deine Raumbezogene Abfrage so aussehen: If Verb = 3 and obj1 = 1 and obj2 = 3 then print"okay, das Schwert ist nun in der Truhe" Dieses simpelbeispiel prüft natürlich noch nicht ob Schwert im Besitz des Spielers ist, und auch nicht ob Truhe sich im aktuellen Raum befindet. Ausserdem müsste dann das Schwert noch aus dem Inventory entfernt werden und in der Truhe plaziert. Du siehst, das kann recht schnell komplex werden. Allerdings lässt sich mit etwas Vorplanung alles so umsetzen. Viel Erfolg! |
||
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 |
CO2ehemals "SirMO" |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Willkommen im Forum!
Also, zu deinen Punkten: 1.) Beim laden des Bildes wäre es wichtig, den relativen, nicht den absoluten Pfad zu nehmen, da sonst der Spielordner auf jedem Rechner im gleichen Verzeichnis liegen muss, um ein Absturz zu verhindern (Statt "C:\Test\TestBild.bmp" lieber "TestBild.bmp", wenn wir davon ausgehen, dass dein Spiel-Ordner "\Test\" ist.) Des Weiteren ist es evtl. wichtig, sich mit Befehlen wie MaskImage, SetBuffer, Flip, etc. auseinander zu setzen. 2.) Auf jeden Fall! Vielleicht wäre es auch sinnvoll, den gesamten Text in eine Datei auszulagern, welche du dann mit deinem Programm liest (So bist du flexibler, wenn du den Text in eine andere Sprache übersetzen willst, etc.) 3.) Ein Tipp: Mit den Befehlen Upper() und Lower() kannst du die Eingabe im Gesamten groß, bzw. klein schreiben. (Aus "Ja" wird mit Lower() "ja", etc.) Dies vereinfacht die Abfrage des Eingegebenen. Schau dir einmal Types an. Damit kannst du die Daten, die zum Spieler gehören einfacher speichern. |
||
mfG, CO²
Sprachen: BlitzMax, C, C++, C#, Java Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Einen hab ich noch: Kennst Du die alten SCUMM-Klassiker wie zb Maniac Mansion oder Tales of Monkey Island?
Diese Spiele haben einen sehr reduzierten Befehlssatz, der aber äüßerst intelligent ist: Mit einem knappen Dutzend Befehlsworte kann man alles erreichen. Egal wieviele Verben also dein Parser kennt, er wird sich eigentlich immer auf diese Standartaktionen reduzieren lassen. "Iss" und "Trink" sind identisch zu "benutze", erhalten also den selben Wert. Dann kann der Spieler zwar eingeben trink den Schlüssel unter der Tür, und das Spiel wird dennoch "Benutze den Schlüssel mit der Tür" verstehen, aber mal im Ernst: die wenigsten Spieler werden das bemerken, weil die Eingabe ihnen zu abstrus erscheint um sie zu testen. |
||
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 |
![]() |
Tennisball |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
Also erstmal ein paar Tipps, dann versuche ich deine Fragen zu beantworten. - Einrückung. Die ist bei dir nicht ganz konsequent. Hier mal ein Beispiel, wie es sein sollte: BlitzBasic: [AUSKLAPPEN] If a = 1 Then - Nutze Text ![]() ![]() - Zeilen wie: BlitzBasic: [AUSKLAPPEN] If Vorgeschichtenabfrage = "Ja" Or Vorgeschichtenabfrage = "JA" Or Vorgeschichtenabfrage = "ja"kannst du zusammenfassen: BlitzBasic: [AUSKLAPPEN] If Lower(Vorgeschichtenabfrage) = "ja" ThenDies konvertiert erst die Eingabe in Kleinbuchstaben und vergleicht dann das mit "ja". Wo wir gerade bei der Zeile sind ... Then ![]() - Benutze Funktionen! -> Function ![]() - Die ganzen Strings solltest du in Dateien auslagern und zu Beginn z.B. in ein Array einlesen. Siehe ReadFile ![]() ![]() - Gib dem Spieler die Möglichkeit, das Spiel zu beenden. ![]() - Du könntest deine Räume als Objekte eines selbst definierten Type ![]() ... Und da die anderen schneller waren beantworte ich jetzt doch nur noch Frage 3. Das würde ich so lösen. Dort brauchst du keine extra Abbruchbedingung + Variable, sondern springst gegebenenfalls einfach mit Exit ![]() BlitzBasic: [AUSKLAPPEN] RepeatOh, und vergiss hier nicht, auch eine Option für's Abbrechen zur Verfügung zu stellen! Du wirst noch viel lernen müssen, aber gib nicht auf, dann wirst du das alles irgendwann meistern. ![]() Gruß, Tennisball |
||
MasterCoderGanon |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
![]() ![]() Vielen Dank für eure schnellen Tipps und Befehle die ihr mir gegeben habt. Auf die Art und Weise konnte ich den Code um einiges verkürzen und den Defaultcounter endlich rausnehmen, sowie die vielen Antwortmöglichkeiten wegnehmen. ![]() ![]() ![]() Ich werde den gesamten Text jetzt erstmal in ne gesonderte Datei schreiben. Das mit den entsprechenden Befehlen scheint mir recht einfach und umsetzbar. Das mit der Monkey Island Idee finde ich Interessant und ich werde mal überlegen ob bzw. wie ich das umsetze. Ich hätte nur noch einmal zwei Fragen bezüglich des Text statt Input Befehls. 1. Warum läuft das denn über den Frontbuffer? Für mich macht das irgendwie keinen Sinn. 2. Kann mir jemand noch mal einen Foenbeitrag oder irgendeine andere seite verlinken wo das anschaulich erklärt ist, auch wie das abläuft? Ich finde hier nämlich nur recht komplexe Beispiel die ich nicht recht verstehen will, aber langfristig komm ich wohl nicht rum. ![]() Nochmal vielen Dank für eure liebe Hilfe. ![]() ![]() ![]() |
||
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
Was gut funktionieren täte mit dem Auslagern von Text in eine Datei ist, dass du dir Sitationen schreibst.
Eine Situation besitzt einen Text, der angezeigt wird, sowie eine Liste an Möglichkeiten, die dann jeweils zu weiteren Situationen führen. Ein Beispiel: Code: [AUSKLAPPEN] Situation 1:
Text=Du stehst vor einer Tür. Was machst du? Auswahl1Cond=öffnen Auswahl1Ziel=2 Auswahl2Cond=eintreten Auswahl2Ziel=3 Situation 2: Text=Du hast die Tür geöffnet .... Situation 3: Text=Du hast die Tür eingetreten .... Dabei kannst du das Ganze auch auf mehrere Teile für die Konditionen erweitern, um z.B. ein Verb und zwei Objekte unterzubringen, wie es BladeRunner vorgeschlagen hat. Auf diese Weise brauchst du nur eine Engine programmieren, die mit dem Ganzen umgeht, und brauchst für den Rest nur externe Skriptdateien schreiben. Damit bleibt deine Engine frei von Story-Inhalten und dadurch klein und übersichtlich. Gleichzeitig bleiben auch die externen Scripts übersichtlich, da jede einzelne Situation für sich bearbeitet werden kann. Alles was du dafür brauchst sind Types. Die sind nicht so schwer, wie sie von Anfang an ausschauen. |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
![]() |
Tennisball |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: Ich hätte nur noch einmal zwei Fragen bezüglich des Text statt Input Befehls.
1. Warum läuft das denn über den Frontbuffer? Für mich macht das irgendwie keinen Sinn. Vermutlich meinst du Text statt Print. Print gibt immer in den Frontbuffer aus. Text gibt in den Buffer aus, den man mit SetBuffer ![]() ![]() ![]() BlitzBasic: [AUSKLAPPEN] Graphics(640, 480) Nimmst du die Zeilen mit Flip bzw. SetBuffer raus, wird es nicht flüssig aussehen/flackern. Ich habe außerdem noch einen Timer hinzugefügt, damit die CPU nicht zu 100% ausgelastet wird. ![]() Gruß, Tennisball |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group