Textadventure als Schulprojekt

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Joeee
User
Beiträge: 3
Registriert: Freitag 25. Oktober 2013, 21:31

Hey Leute und erstmal Hallo an das Forum.

Ich muss für den Info Unterricht bis Montag ein Textadventure schreiben und nunja, ich komme nicht so recht weiter :D

Hier mal Programm soweit ich es habe : (wir benutzen den PyScripter in der neusten Version

Code: Alles auswählen

#Verloren im Wald Version 6

#Schrift = Arial Uni Ms

# Version 6     03.09.2013
import tkinter
import tkinter.scrolledtext

# Klassendefinition
class TRaum(object):
    def __init__(self, pBeschreibung, pBild):

        #Button Weiter
        self.__Weiter = None # Weiter im Intro
        #Button Zurueck
        self.__Zurueck = None # Zurueck im Intro
        self.__Beschreibung = pBeschreibung
        self.__Norden = None # ↑
        self.__Osten = None  # ←
        self.__Sueden = None # ↓
        self.__Westen= None  # →
        # Neue Richtungen -----------------------------------------------
        self.__Nordwesten = None # ↑←
        self.__Nordosten = None  # ↑→
        self.__Suedwesten = None # ↓←
        self.__Suedosten = None # ↓→




        self.__Bild = pBild  # Erweiterung 1.2 Bilder
    def gibBeschreibung(self):
        return self.__Beschreibung
    def gibBild(self):
        return self.__Bild

  #Setze Befehle

    def setzeNorden(self, pNorden):
        self.__Norden = pNorden
    def setzeOsten(self, pOsten):
        self.__Osten = pOsten
    def setzeSueden(self, pSueden):
        self.__Sueden = pSueden
    def setzeWesten(self, pWesten):
        self.__Westen = pWesten

      #Neue Richtungen

    def setzeNordwesten(self, pNordwesten):
        self.__Nordwesten = pNordwesten
    def setzeNordosten(self, pNordosten):
        self.__Nordosten = pNordosten
    def setzeSuedwesten(self, pSuedwesten):
        self.__Suedwesten = pSuedwesten
    def setzeSuedosten(self, pSuedosten):
        self.__Suedosten = pSuedosten

      #Weiter Button
    def setzeWeiter(self, pWeiter):
        self.__Weiter = pWeiter
      #Zurueck Button
    def setzeZurueck(self, pZurueck):
        self.__Zurueck = pZurueck


#Gib Befehle

    def gibNorden(self):
        return self.__Norden
    def gibNorden(self):
        return self.__Norden
    def gibOsten(self):
        return self.__Osten
    def gibOsten(self):
        return self.__Osten
    def gibSueden(self):
        return self.__Sueden
    def gibSueden(self):
        return self.__Sueden
    def gibWesten(self):
        return self.__Westen
    def gibWesten(self):
        return self.__Westen
  #Neue Richtungen Gib Befehle
    def gibNordwesten(self):
        return self.__Nordwesten
    def gibNordwesten(self):
        return self.__Nordwesten
    def gibNordosten(self):
        return self.__Nordosten
    def gibNordosten(self):
        return self.__Nordosten
    def gibSuedwesten(self):
        return self.__Suedwesten
    def gibSuedwesten(self):
        return self.__Suedwesten
    def gibSuedosten(self):
        return self.__Suedosten
    def gibSuedosten(self):
        return self.__Suedosten
    #Button Weiter
    def gibWeiter(self):
        return self.__Weiter
    #Button Zurueck
    def gibZurueck(self):
        return self.__Zurueck




# ButtonClick - Prozedur
def ButtonClick(Befehl):
    TextBox.delete(1.0, 'end')
    global aktuellerRaum
    #Start Button
    if Befehl == "Start":
        aktuellerRaum = Intro1
    #Weiter Button
    elif Befehl == "Weiter" and aktuellerRaum.gibWeiter() != None :
        aktuellerRaum = aktuellerRaum.gibWeiter()
    #Zurueck Button
    elif Befehl == "Zurueck" and aktuellerRaum.gibZurueck() != None :
        aktuellerRaum = aktuellerRaum.gibZurueck()
    #"Normale Buttons"
    elif Befehl == "Norden" and aktuellerRaum.gibNorden() != None :
        aktuellerRaum = aktuellerRaum.gibNorden()
    elif Befehl == "Osten" and aktuellerRaum.gibOsten() != None:
        aktuellerRaum = aktuellerRaum.gibOsten()
    elif Befehl == "Sueden" and aktuellerRaum.gibSueden() != None:
        aktuellerRaum = aktuellerRaum.gibSueden()
    elif Befehl == "Westen" and aktuellerRaum.gibWesten() != None:
        aktuellerRaum = aktuellerRaum.gibWesten()
    #Neue Richtungen
    elif Befehl == "Nordwesten" and aktuellerRaum.gibNordwesten() != None :
        aktuellerRaum = aktuellerRaum.gibNordwesten()
    elif Befehl == "Nordosten" and aktuellerRaum.gibNordosten() != None :
        aktuellerRaum = aktuellerRaum.gibNordosten()
    elif Befehl == "Suedwesten" and aktuellerRaum.gibSuedwesten() != None :
        aktuellerRaum = aktuellerRaum.gibSuedwesten()
    elif Befehl == "Suedosten" and aktuellerRaum.gibSuedosten() != None :
        aktuellerRaum = aktuellerRaum.gibSuedosten()

    TextBox.insert("end",aktuellerRaum.gibBeschreibung())




#Bilder Erweiterung
    global im
    im = tkinter.PhotoImage(file=aktuellerRaum.gibBild())
    global canvas
    canvas.create_image(0,0,image=im, anchor = 'nw')

#Ende - Erweiterung Bilder
    TextBox.insert("end","\n---------- \n")
    TextBox.insert("end","Folgende Ausgänge können genommen werden: \n")
    #Button Weiter
    if (aktuellerRaum.gibWeiter() != None):
        TextBox.insert("end","-->   Weiter\n")
    #Button Zurueck
    if (aktuellerRaum.gibZurueck() != None):
        TextBox.insert("end","-->   Zurueck\n")
    #"Normale Buttons"
    if (aktuellerRaum.gibNorden() != None):
        TextBox.insert("end","-->   Norden\n")
    if (aktuellerRaum.gibOsten() != None):
        TextBox.insert("end","-->   Osten\n")
    if (aktuellerRaum.gibSueden() != None):
        TextBox.insert("end","-->   Sueden\n")
    if (aktuellerRaum.gibWesten() != None):
        TextBox.insert("end","-->   Westen\n")
    #Neue Richtungen
    if (aktuellerRaum.gibNordwesten() != None):
        TextBox.insert("end","-->   Nordwesten\n")
    if (aktuellerRaum.gibNordosten() != None):
        TextBox.insert("end","-->   Nordosten\n")
    if (aktuellerRaum.gibSuedwesten() != None):
        TextBox.insert("end","-->   Suedwesten\n")
    if (aktuellerRaum.gibSuedosten() != None):
        TextBox.insert("end","-->   Suedosten\n")

    TextBox.see("end") #TextBox ans Ende scrollen




# Erweiterung Richtungsbuttons

#Button Start
def ButtonClickStart():
     ButtonClick("Start")
#Button weiter
def ButtonClickWeiter():
     ButtonClick("Weiter")
#Button Zueruck
def ButtonClickZurueck():
     ButtonClick("Zurueck")
#"Normale Buttons
def ButtonClickNorden():
     ButtonClick("Norden")
def ButtonClickWesten():
     ButtonClick("Westen")
def ButtonClickSueden():
     ButtonClick("Sueden")
def ButtonClickOsten():
     ButtonClick("Osten")

#Neue Richtungen
def ButtonClickNordwesten():
     ButtonClick("Nordwesten")
def ButtonClickNordosten():
     ButtonClick("Nordosten")
def ButtonClickSuedwesten():
     ButtonClick("Suedewesten")
def ButtonClickSuedosten():
     ButtonClick("Suedosten")





# Erzeugung der Räume
#Flur = TRaum('Du stehst in einem leeren Flur', "Bilder/Flur.gif")

Intro1 =TRaum('Du wachst alleine in einen dunklem Wald auf.\n \
Dein Hinterkopf schmerzt und du hast keine Erinnerung wer du bist oder wo du bist.', "Bilder/Intro/Intro1.gif")
Intro2 = TRaum('Du siehst an dir herunter und erkennst eine Nachricht auf deinem Unterarm', "Bilder/Intro/Intro2.gif")
Intro3 = TRaum('Du hast keine andere Wahl als der Karte zu folgen', "Bilder/Intro/Intro3.gif")
#Intro1N = TRaum('Intro 1', "Bilder/Intro/Intro1N")
aktuellerRaum = Intro1

##Flur = TRaum('Du stehst in einem leeren Flur', "Bilder/Flur.gif")
##Lehrerzimmer = TRaum('Du betrittst das Lehrerzimmer. \n \
##Dieses ist unheimlich und groß.', "Bilder/Lehrerzimmer.gif")
##Computerraum = TRaum('Du gehst in den Computerraum. \n \
##Alle Rechner laufen, der Raum ist leer.', "Bilder/Computerraum.gif")
##Abstellkammer = TRaum('Du öffnest eine Abstellkammer. \n \
##Die Kammer ist leer und dunkel.', "Bilder/Abstellkammer.gif")
##aktuellerRaum = Flur





# Attribute als Objektreferenzen initialisieren

#Intro
Intro1.setzeWeiter(Intro2)
Intro2.setzeZurueck(Intro1)
Intro2.setzeWeiter(Intro3)
Intro3.setzeZurueck(Intro2)

#Flur.setzeNorden(Intro1N)

##Flur.setzeOsten(Abstellkammer)
##Flur.setzeSueden(Computerraum)
##Lehrerzimmer.setzeSueden(Flur)
##Abstellkammer.setzeWesten(Flur)
##Computerraum.setzeNorden(Flur)





#GUI - Hauptfenster
main = tkinter.Tk()
main.title("Veloren im Wald")
TextBox = tkinter.scrolledtext.ScrolledText(main, width=50, height = 10,
                                                  font=('Arial, 14'))
TextBox.grid(row=2 , column = 1, columnspan=60)
TextBox.insert("end", "Verloren im Wald .\n \
 \n \
 \n \
 Druecke auf Start um das Spiel zu beginnen  \n")

# Buttonsteuerung Erweiterung 1.1

#Start Button
ButtonStart = tkinter.Button(main, text = "Start/Neustart", command = ButtonClickStart)
ButtonStart.grid(row=4, column = 10)

#Weiter Button
ButtonWeiter = tkinter.Button(main, text = "Weiter", command = ButtonClickWeiter)
ButtonWeiter.grid(row=4, column = 90)

#Button Zueruck
ButtonZurueck = tkinter.Button(main, text = "Zurueck", command = ButtonClickStart)
ButtonZurueck.grid(row=4, column = 70)

#Bewegung
ButtonNorden = tkinter.Button(main, text = "↑", command = ButtonClickNorden)
ButtonNorden.grid(row=3, column = 90)
ButtonSueden = tkinter.Button(main, text = "↓", command = ButtonClickSueden)
ButtonSueden.grid(row=5, column = 90)

ButtonWesten = tkinter.Button(main, text = "←", anchor = "e", command = ButtonClickWesten)
ButtonWesten.grid(row=4, column = 80)
ButtonOsten = tkinter.Button(main, text = "→", command = ButtonClickOsten)
ButtonOsten.grid(row=4, column = 100)

#Neue Richtungen

ButtonNordwesten = tkinter.Button(main, text = "NW", command = ButtonClickNordwesten)
ButtonNordwesten.grid(row=3, column = 80)
ButtonNordosten = tkinter.Button(main, text = "NO", anchor = "e", command = ButtonClickNordosten)
ButtonNordosten.grid(row=3, column = 100)
ButtonSuedwesten = tkinter.Button(main, text = "SW", command = ButtonClickSuedwesten)
ButtonSuedwesten.grid(row=5, column = 80)
ButtonSuedosten = tkinter.Button(main, text = "SO", command = ButtonClickSuedosten)
ButtonSuedosten.grid(row=5, column = 100)


# Erweiterung Bilder in der GUI
# (Angezeigt werden können nur "gif"-Bilder)
canvas = tkinter.Canvas(main, bg='white')
im = tkinter.PhotoImage(file="Startbild.gif")
canvas.create_image(0,0,image=im, anchor="nw")
canvas.grid(row=1, column = 1)

# Ende der Erweiterung

main.mainloop()

#anchor = ausrichtung
Was ich ergänzen wollen würden, wär;
-Starten im Vollbildmodus und das die Schrift in einem Feld unter dem Bild ist (soweit ja kein Problem, aber ich weiß nicht wie ich eine Randlose Box erzeuge die bündig an das Bild anschließt.)

-Die Schrift Box, Ausgabe und die Buttons Farbig
-Ein Inventar in dem man Dinge die man findet einsammeln kann und später benutzen kann ( Schlüssel , Fakeln etc.) , habe mir da gedacht das man rechts wo gerade die Textbox ist vielleicht immer jeweils eine liste ausgeben könnte die dann den Namen des Gegenstandens trägt ,
also Z.bsp.
-Eine Karte Rechts oben auf der der eigene Standpunkt angezeigt wird ( Habe mir überlegt einfach eine Karte zeichen und dann für jeden Berreich den Punkt reinzumalen und dann für jeden Berreich zu aktualisieren)

Schlüssel 0
Fakeln 1
Brote 3
Wasser 0

Geplant ist weiterhin so eine Art "Schnitzeljagd" zu machen , wobei man sich von dem Akutellen Punkt(Raum) immer umschauen muss (in andere Räume) um einen Hinweis zu finden wie man weiter kommt.

Wie gesagt , ist erst der Rohbau da ich die Bilder noch schießen muss :)

Hoffe ihr könnt ihr mir helfen und dass ich mich nicht zu umständlich ausgedrückt hab ,

liebe grüße, Joe
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Joeee,

ich weiß nicht, was Du in Python schon alles gelernt hast, oder haben solltest, aber da Du Klassen schon kennst, gehe ich mal davon aus, dass Schleifen, Listen und Wörterbücher Dir nicht unbekannt sind.
Über zwei drittel aller Deiner Zeilen sind Kopien von anderen Zeilen. In Deinem Programm behandelst Du jede Richtung einzeln, und da es sehr oft irgendetwas mit Richtungen zu tun gibt, vervielfacht sich Dein Code.
An Deiner stelle würde ich ein Wörterbuch nehmen, in dem nur die Richtungen gespeichert werden, die es auch tatsächlich gibt. Dass alle Deine Klassenattribute mit zwei Unterstrichen beginnen, macht zum ersten keinen Sinn und zum zweiten ist mehr Schreibarbeit und macht den Code unleserlicher. Die ganzen »gib«- und »setze«-Methoden sind genauso überflüssig, da man direkt Attribute lesen und schreiben kann. pWarum pfangen pbei pDir palle pParameter pmit p»p« pan? Das macht den Code auch weniger lesbar und hat keinen Nutzen. Innerhalb einer Funktion ist es schließlich egal, ob die Variable lokal definiert wurde oder als Parameter.
Ein »\« am Zeilenende ist zwar möglich, sollte aber nicht mehr verwendet werden. Für mehrzeilige Befehle bietet es sich an, diese in Klammern zu setzen, wenn sie nicht sowieso schon Klammern enthalten, und mehrzeilige Strings werden mit ''' oder """ gebildet.

Alles in Allem kommt dann ungefähr sowas raus:

Code: Alles auswählen

#Verloren im Wald Version 6
#Schrift = Arial Uni Ms
# Version 6     03.09.2013
import tkinter
import tkinter.scrolledtext
import functools
 
# Klassendefinition
class TRaum(object):
    def __init__(self, Beschreibung, Bild):
        self.benachbarte_raeume = {}
        self.Beschreibung = Beschreibung
        self.Bild = Bild  # Erweiterung 1.2 Bilder
 
# ButtonClick - Prozedur
def ButtonClick(Befehl):
    TextBox.delete(1.0, 'end')
    global aktuellerRaum
    #Start Button
    if Befehl == "Start":
        aktuellerRaum = Intro1
    else:
        if Befehl in aktuellerRaum.benachbarte_raeume:
            aktuellerRaum = aktuellerRaum.benachbarte_raeume[Befehl]
    TextBox.insert("end",aktuellerRaum.Beschreibung)
 
#Bilder Erweiterung
    im = tkinter.PhotoImage(file=aktuellerRaum.Bild)
    canvas.create_image(0,0,image=im, anchor = 'nw')
 
#Ende - Erweiterung Bilder
    TextBox.insert("end","\n---------- \n")
    TextBox.insert("end","Folgende Ausgänge können genommen werden: \n")
    for raum in aktuellerRaum.benachbarte_raeume:
        TextBox.insert("end","-->   %s\n"%raum)
    TextBox.see("end") #TextBox ans Ende scrollen
 
# Erzeugung der Räume
Intro1 =TRaum('''Du wachst alleine in einen dunklem Wald auf.
Dein Hinterkopf schmerzt und du hast keine Erinnerung wer du bist oder wo du bist.''', "Bilder/Intro/Intro1.gif")
Intro2 = TRaum('Du siehst an dir herunter und erkennst eine Nachricht auf deinem Unterarm', "Bilder/Intro/Intro2.gif")
Intro3 = TRaum('Du hast keine andere Wahl als der Karte zu folgen', "Bilder/Intro/Intro3.gif")
#Intro1N = TRaum('Intro 1', "Bilder/Intro/Intro1N")
aktuellerRaum = Intro1
 
# Attribute als Objektreferenzen initialisieren
 
#Intro
Intro1.benachbarte_raeume['Weiter']=Intro2
Intro2.benachbarte_raeume['Zurueck']=Intro1
Intro2.benachbarte_raeume['Weiter']=Intro3
Intro3.benachbarte_raeume['Zurueck']=Intro2
 
#GUI - Hauptfenster
main = tkinter.Tk()
main.title("Veloren im Wald")
TextBox = tkinter.scrolledtext.ScrolledText(main, width=50, height = 10,
                                                  font=('Arial, 14'))
TextBox.grid(row=2 , column = 1, columnspan=60)
TextBox.insert("end", """Verloren im Wald .


Druecke auf Start um das Spiel zu beginnen
""")
 
# Buttonsteuerung Erweiterung 1.1
BUTTONS = [
    (4,10, "Start/Neustart", "Start"),
    (4,90, "Weiter", "Weiter"),
    (4,70, "Zurueck", "Zurueck"),
    (3,90, "↑", "Norden"),
    (5,90, "↓", "Sueden"),
    (4,80, "←", "Westen"),
    (4,100, "→", "Osten"),
    (3,80, "NW", "Nordwesten"),
    (3,100, "NO", "Nordosten"),
    (5,80, "SW", "Suedwesten"),
    (5,100, "SO", "Suedosten"),
]

for row, column, label, command in BUTTONS:
    button = tkinter.Button(main, text=label, command=functools.partial(ButtonClick,command))
    button.grid(row=row, column=column)
 
# Erweiterung Bilder in der GUI
# (Angezeigt werden können nur "gif"-Bilder)
canvas = tkinter.Canvas(main, bg='white')
im = tkinter.PhotoImage(file="Startbild.gif")
canvas.create_image(0,0,image=im, anchor="nw")
canvas.grid(row=1, column = 1)
 
# Ende der Erweiterung
 
main.mainloop()
 
#anchor = ausrichtung
Jetzt solltest Du Dir noch überlegen, eine »Spiel«-Klasse zu erzeugen, die die ganze GUI mit Steuerung enthält und die eigentlichen Räume und Texte noch besser vom restlichen Programm trennen, am besten indem Du Dir ein Dateiformat überlegst und dieses dann lädst.

Grüße
Sirius
BlackJack

Ergänzend zu den unnsinnigen Präfixen bei den Namen die Sirius3 schon genannt hat: Auch das T vor Raum gehört da nicht hin. Wenn das alles von Deinem Lehrer vorgegeben wurde, dann bestell ihm mal einen schönen Gruss und er soll doch bitte aufhören Pascal in Python-Syntax zu schreiben und idiomatisches Python lernen. Das es sich um einen *T*yp handelt erkennt man in Python daran, dass der Name „MixedCase” geschrieben ist, also einfach `Raum` in diesem Fall. Klassen sind nämlich konventionell in Python (nahezu) die einzigen Namen die mit einem Grossbuchstaben anfangen. Näheres dazu im Style Guide for Python Code.
Joeee
User
Beiträge: 3
Registriert: Freitag 25. Oktober 2013, 21:31

Vielen Dank schonmal ihr 2 ;)
Ja richtig, wir lernen es so mit dem p und t davor .
Warum Klassenattribute mit zwei Unterstrichen beginnen weiß ich ehrlich gesagt nicht , aber wurde auch so vorgegeben :D
Also Schleifen und Listen etc. kenne ich natürlich , damit haben wir angefangen , aber ich weiß nicht was ein Wörterbuch ist.

Die "Neuen" vier Richtungen habe ich rein gebracht , damit man sich praktisch von seinem aktuellem Standpunkt aus in 8 Richtungen umschauen kann um z.bsp die Hinweise auf den richtigen Weg zu finden. Dachte mir das 4 Richtungen mit dementsprechend 4 Bildern kein Gefühl von Räumlichkeit vermitteln können.

@Sirius3
Du hast da ja jetzt ziemlich viel rausgelöscht oder komprimiert.
könntest du mir vielleicht noch erklären warum das überhaupt geht :D ? Müssen die Buttons nicht am Anfang auch in der Klassendefinition stehen ? Und das mit diesen setze und gib Befehlen hab ich eh nicht so verstanden was das bedeuten soll . Also kann man die einfach rauslassen ?

liebe Grüße
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@Joeee: was genau meinst Du mit »warum das überhaupt geht«? Neben der Programmlogik ist das finden der richtigen Datenstruktur eine Hauptaufgabe des Programmierens. Legst Du die Daten in einer ungünstigen Struktur ab, wird das Programm gleich viel komplizierter. Bei Deinen Richtungen ist es so, dass das Programm das selbe tut, egal ob Du nach Norden oder Osten gehst, es wechselt den Raum. Es besteht also eine eindeutige Zuordnung Richtung -> Raum. Diese Struktur nennt sich Wörterbuch, da es das gleiche ist wie Deutsch -> Englisch. Da Wörterbücher genauso wie Listen zu den absoluten Grundlagen zählen, wundert es mich, dass ihr das nicht durchgenommen habt.:

Code: Alles auswählen

# Wörterbuch erzeugen
richtungen = {}
# Schlüssel-Wert-Paare eintragen
richtungen['Norden']='Dänemark'
richtungen['Süden']='Österreich'

# Ausgabe:
print(richtungen)
# {'Norden': 'Dänemark', 'Süden': 'Österreich'}

# Testen ob Schlüssen im Wörterbuch
print('Süden' in richtungen)

# Wert zu Schlüssel ausgeben
print(richtungen['Norden'])
# Dänemark
Das ist schon das Wichtigste zu Wörterbüchern.
Zum »setze…«: Du siehst, dass es geht und übersichtlicher aussieht :-)
Joeee
User
Beiträge: 3
Registriert: Freitag 25. Oktober 2013, 21:31

Achso ,ja dass kenne ich :D , aber bei uns hieß es glaube ich anders.
Könntet ihr mir vielleich auch noch TIpps geben wie ich die dinge hinbekomme die ich ergänzen wollte ?
-Starten im Vollbildmodus und das die Schrift in einem Feld unter dem Bild ist (soweit ja kein Problem, aber ich weiß nicht wie ich eine Randlose Box erzeuge die bündig an das Bild anschließt.)

-Die Schrift Box, Ausgabe und die Buttons Farbig
-Ein Inventar in dem man Dinge die man findet einsammeln kann und später benutzen kann ( Schlüssel , Fakeln etc.) , habe mir da gedacht das man rechts wo gerade die Textbox ist vielleicht immer jeweils eine liste ausgeben könnte die dann den Namen des Gegenstandens trägt ,
also Z.bsp.
-Eine Karte Rechts oben auf der der eigene Standpunkt angezeigt wird ( Habe mir überlegt einfach eine Karte zeichen und dann für jeden Berreich den Punkt reinzumalen und dann für jeden Berreich zu aktualisieren)

Schlüssel 0
Fakeln 1
Brote 3
Wasser 0
liebe grüße,
Antworten