Kleines Text rpg und schon erste schwierigkeiten



  • Hallo Programmierer und die, die es werden wollen^^

    ich habe mir gedacht, mache ich mal ein kleines text rpg um mir meine jetzigen c++ kenntnisse richtig einzuprägen.
    Aber ich habe gemerkt, dass c++ immer wieder andere Probleme hat. Mal ist es richtig, dann wieder nicht. Dann hat es hier ein aua, dann da. Langsam werde ich echt ungeduldig.

    Wenn ihr euch meinen Code nicht angucken wollt, habe ich dafür verständnis. Aber ich habe echt alles versucht und mein Gehirn platz gleich 😃

    Zuerst habe ich versucht, dass ganze mit Klassen zu machen.
    z.B.
    class Held
    class Wolf
    class Schaf
    und dann lebenspunkte, stärke und alles jeweils in der Klasse zu definieren. Beim Held sollen sich die attribute je nach Level usw. verändern.
    Das habe ich aufgegeben, nachdem ich da 6 Stunden dran gesessen habe.

    Nun habe ich dass so, dass klappt ja auch alles. Aber wenn ich für Hilfe die 3 drücke, dann kommt nicht die hilfe, sondern die Frage:
    Wie alt seid Ihr?

    Wieso zum kuckuck kommt das? Das steht doch in garkeinem zusammenhang. Das darf aus logischer Sicht doch garnicht passieren. Und ich dachte, beim PC ist immer alles ganz logisch^^

    Ich habs jetzt echt Satt. Ich brauche hilfe...

    //Einbinden der headder-datein.
    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    int main(int argc, char *argv[])
    //Der eigentliche code
    {
        string Klasse;
        string Name;
        int Alter;
        int Menue;
        int Menuee;
        int Menuu;
    //Menue
        cout << "Der Koenig von Elda" << endl;
        cout << endl;
        cout << endl;
        cout << "Start     <1>" << endl;
        cout << "Laden     <2>" << endl;
        cout << "Hilfe     <3>" << endl;
        cout << "Beenden   <4>" << endl;
        cout << endl;
        cin >> Menue;
        cout << endl;
    //Begruessung und Charackter erstellung  
        switch (Menue)
        {
               case 1: cout << "Willkommen in Der Koenig von Elda." << endl;
               break;
               case 2: cout << "In dieser Version nicht verfuegbar." << endl;
               break;
               case 4: cout << "Beenden..." << endl;
               break;
               case 3: cout << "Was moechten sie wissen?" << endl;
               cout << endl;
               cout << "Ueber das Spiel                  <1>" << endl;
               cout << "Ueber meinen Charackter          <2>" << endl;
               cout << "Ueber die Attribute              <3>" << endl;
               cout << "Credits                          <4>" << endl;
               break;
               cin >> Menuee;
               cout << endl;
               }
    
              switch (Menuee)
              {
                     case 1: cout << endl;
                     cout << "SPOILER" << endl;
                     cout << endl;
                     cout << "Noch in Entwicklung..." << endl;
                     cout << endl;
                     break;
                     case 2: cout << endl;
                     cout << "SPOILER" << endl;
                     cout << endl;
                     cout << "Noch in Entwicklung..." << endl;
                     cout << endl;
                     break;
                     case 3: cout << endl;
                     cout << "Staerke: " << endl;
                     cout << "Die Staerke macht Ihren Charakter staerker und robuster." << endl;
                     cout << "Staerke ist vorallem fuer die Krieger geeignet" << endl;
                     cout << endl;
                     cout << endl;
                     cout << "Geschicklichkeit" << endl;
                     cout << "Geschicklichkeit macht Ihren Charackter geschickter im Umgang mit Fernwaffen" << endl;
                     cout << "Geschicklichkeit ist vorallem fuer Fernkaempfer geeignet" << endl;
                     cout << endl;
                     cout << endl;
                     cout << "Mana" << endl;
                     cout << "Mana ist fuer Zaubersprueche notwendig. Ohne Mana koennen Sie diese nicht wirken." << endl;
                     cout << "Mana ist vorallem fuer Magier von hohem Wert." << endl;
                     cout << endl;
                     cout << endl;
                     break;
                     case 4: 
                     cout << "Idee: xxx xxx" << endl;
                     cout << "Programmierung: xxx xxx" << endl;
                     cout << "Spezieller dank an: " << endl;
                     cout << endl;
                     break;
                     }
    
               cout << "Wie lautet Euer Name, Herr?" << endl;
               cout << endl;
               cout << "Name:        " << endl; 
               cin >> Name;
               cout << endl;
               cout << "Ihr alter:   " << endl;
               cin >> Alter;
               cout << endl;
               cout << "Welche Klasse moechtet Ihr spielen?" << endl;
               cout << endl;
               cout << "Krieger         <1>" << endl;
               cout << "Spaeher         <2>" << endl;
               cout << "Magier          <3>" << endl;
               cin >> Menuu;
    
               switch (Menuu)
               {
                             case 1: 
                                  Klasse = "Krieger";
                                  break;
                             case 2: 
                                  Klasse = "Spaeher";
                                  break;
                             case 3:
                                  Klasse = "Magier";
                                  break;
                                  }
    
               cout << "In was moechtet Ihr Eure Lernpunkte investieren?" << endl;
               cout << endl;
               cout << "Staerke            <1>" << endl;
               cout << "Geschicklichkeit   <2>" << endl;
               cout << "Mana               <3>" << endl;
    
    return 0;
    }
    


  • 1. es fehlt : using namespace System
    2. String schreibt man groß
    3. hinter String fehlt ^(braucht man bei allen .net Klassen)



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    Der Code mag ja C++-Mittel benutzen, aber stilistisch gesehen ist das C. Und ich meine nicht, dass hier irgendwelche tollen Sprachfeatures nicht genutzt werden, sondern das Daten und Code, der mit diesen Daten arbeitet, an verschiedenen Stellen stehen, womit der Zusammenhang verloren geht. Zudem erklärt sich so das Fehlerverhalten:
    zunächst einmal steht das break für case 3 im ersten switsch-Statement ( ... ) an der falschen Stelle. Die sinnfreie Wiederverwendung der gleichen Variable (mit schlecht gewähltem Namen: Menue) führt dann dazu, dass direkt case 3 des nächsten switch-Statements aufgerufen wird.

    Edit: nicht das break steht an der falschen Stelle sondern die folgenden Statements im falschen Block...

    Edit: auch nicht... ich sehe nicht durch und das ist der Grund, warum man (kurze!) Funktionen schreibt und keine Seitenlangen switch-Kaskaden...



  • Aus logischer Sicht kann das nur so passieren (abgesehen davon, dass die Frage "Wie alt seid Ihr" im Quelltext so gar nicht vorkommt).
    Du brauchst den Quellcode eigentlich nur Zeile für Zeile durchgehen, dann hättest du den Fehler vermutlich auch selbst gefunden.

    cout << "Credits                          <4>" << endl;
               break;
               cin >> Menuee;
               cout << endl;
               }
    
              switch (Menuee)
              {
                     case 1: cout << endl;
    

    Wie soll die Ausführung denn je in Zeile 3 gelangen, wenn du vorher mit break rausspringst? Und switch (Menuee) gehört in den anderen switch-Block, sonst wird das ganze immer ausgeführt, egal ob du die Hilfe gewählt hast oder nicht.



  • aaauf jeden fall- wenn man mich fragt- ist das ganze ein wenig zu umständlich geschrieben.
    Du solltest dir überlegen, deine textuellen informationen einfach in textdateien zu laden. Das verkürzt und vereinfacht deinen Code ungemein.



  • Zuerst habe ich versucht, dass ganze mit Klassen zu machen.
    z.B.
    class Held
    class Wolf
    class Schaf
    und dann lebenspunkte, stärke und alles jeweils in der Klasse zu definieren. Beim Held sollen sich die attribute je nach Level usw. verändern.
    Das habe ich aufgegeben, nachdem ich da 6 Stunden dran gesessen habe.

    woran genau bist du denn gescheitert?
    vll postest du ja einfach mal, was du alles schon hattest?

    bb



  • Warum setzt du nicht einen Haltepunkt und schaltest die Prozeduren einzeln durch. So musst du doch sehen wo das Programm hinspringt.



  • Deine Variablen Menue und Menuu werden nirgends Initialisiert.
    Demnach werden nach dem ersten, die beiden folgenden switch anweisungen
    übersprungen.

    Danach steht ohne eine weitere Abfrage der Satz den du nicht sehen willst.
    "Wie ist euer Name usw ..."

    Aber ganz generell mal auch wenn / bzw. grade weil du es zum üben machst.

    Schreib so ein Spiel am besten mit Klassen auch wenn es dir vielleicht
    am Anfagn schwer fällt. Weil mit einem Spiel in einer riesigen main
    funktion wirst du nicht glücklich.

    Lieber kleine langsame fortschritte als einfach mal drauf los
    und dann so ein Chaos wie in deinem Code.



  • Also dass mit den Klassen ist wirklich schwer. Mal kapier ich das, dann steig ich da wieder nicht durch^^

    Ich wollte es zuerst so machen:

    class Held
    {
    int Staerke;
    int Geschicklichkeit;
    int Mana;
    int Lebenspunkte;
    usw.
    }

    class Schaf
    {
    int Staerke;
    usw.
    }

    das erschien mir aber unvorteilhaft, denn wenn ich für jedes noch so kleine Monster eine Klasse erstelle, wird das unglaubliche ausmaße annehmen.
    Außerdem weiß ich nicht, wie das Kampfsystem funktioniren soll, wie ich die Lernpunkte beschränken kann, heißt, wenn ich 10 Lernpunkte habe, dass ich auch nur 10 Lernpunkte und nicht unendlich ausgeben kann.
    Dass die Stärke den Angriff erhöht, und dann bin ich ja noch ganz am Anfang^^

    Ich meine, ich brauch auch ein bestimmtest Feld, wo man rumlaufen kann.
    Also, nach Norden, nach Süden, nach Osten, nach Westen. Natürlich nicht visuell. Dann soll auch mal eine Nachricht kommen, wie z.B.

    "Eine riesige Klippe verspeert dir den Weg. Noch ein Schritt weiter und du stürzt ins Meer."

    Was mich brennend interessieren würde, wie ich das Spiel speichern und auch wieder laden kann. Ich weiß, es ist sehr viel, was ich wissen möchte, ich möchte es auch lernen. Ich finde nur kein gescheites Tutorial. ich habe zwar ein Buch, aber damit kann ich jetzt auch nichtmehr weiter.

    Grüße



  • Naja. Sagt dir Vererbung etwas?

    Ein wenig musst du dir auch selber Gedanken machen, wie etwas funktionieren soll. 😉
    Sonst macht es ja keinen Spass, wenn alles bereits vorgegeben ist.

    Speicher kannst du ja ganz einfach mittels Files. Wenn dir if/ofstreams etwas sagen.

    Zum Beispiel hier:
    http://www.cplusplus.com/reference/iostream/ofstream/

    Ansonsten einfach ein wenig googlen zu den Stichworten.



  • class Held 
    { 
    int Staerke; 
    int Geschicklichkeit; 
    int Mana; 
    int Lebenspunkte; 
    } 
    
    //ist doch ganz gut so...
    
    class Schaf 
    { 
    int Staerke; 
    //bla
    }
    

    was spricht dagegen?

    denn wenn ich für jedes noch so kleine Monster eine Klasse erstelle

    oder du würdest was ganz verrücktes machen:

    struct Tdmg
     {
    };
    
    struct Truestung
     {
    };
    
    struct Tspell
     {
    size_t manacost;
    size_t cooldown
    };
    
    struct bar
     {
      size_t insg;
      size_t act;
      bar (size_t _insg) : insg (_insg) {};
      delta_minus (size_t value)
       {
        if (value > act)
          act = 0;
        else act -= value;
       }
      delta_plus (size_t value)
       {
        act += value;
        if (act > insg)
          act = insg;
       }
     };
    
    class creep
    {
     private:
      unsigned char lvl; //bis lvl 255 reicht doch? damit machste so gar die wow-ler platt ;D
     public: //var
      static size_t ruestung_per_lvl;
      static size_t hp_per_lvl;
      static size_t mana_per_lvl;
      bar ruestung;
      bar hp;
      bar mana;
      const Truestung ruestung_art;
     public: //fkt
      creep (unsigned char _lvl, const Truestung &_ruestung)
        : ruestung (ruestung_per_lvl * lvl), hp (hp_per_lvl * lvl), mana (mana_per_lvl * lvl), ruestung_art (_ruestung)
        {};
      unsigned char GetLvl (void) const {return lvl;};
      void GetHit (size_t dmg, const Tdmg &schadensart)
       {
        ;
       }
    };
    

    Wenn du ganz viel Lust hast, dann kannste auch noch verschiedene creep-fähigkeiten erstellen - und das halt iwie mit in die klasse packen...
    was auch noch komplett fehlt sind halt die beiden leeren klassen ganz oben - dachte mir halt, dass man dort die beziehung zwischen dmgart und rüstungsart iwie realisieren kann... Tspell is halt auch nur angedeutet und überhaupt ^^

    also dann - vll kommt dir ja jz ne idee, wie man das alles besser machen könnte?

    bb, Tom



  • Tag'chen,
    Ähm ich an deiner Stelle würde auch besser Vererbung verwenden, wenn du wirklich nicht hast dein Leben damit zu vollbringen Monster Klassen zu basteln 😉

    Wenn du also weißt, dass alle Creeps auch die Attribute:
    - Staerke
    - Intelligenz
    - Agilitaet
    - Willesnkarft
    - ...
    - Healthpoints
    - Manapoints
    - BaseMeeleDam
    - BaseRangeDam
    - BaseSpellDam
    - Level
    - ... was dir noch so einfällt 😉

    besitzen sollen, dann leg dir doch einfach eine Basisklasse an:

    class CCreep {
    
        private:
    
            // creep properties ( s.o. )
    
        public:
    
            // Methods
    };
    

    So könntest du via' Vererbung diese Eigenschaften für Creeps übernehmen und für spezielle Bosmonster erweitern.

    Gruß Tobi.



  • T0bi schrieb:

    So könntest du via' Vererbung diese Eigenschaften für Creeps übernehmen und für spezielle Bosmonster erweitern.

    Oder du machst einfach ein Attribut für den Einheitentyp ( short ) und dann kannst du sehr viele Eigenschaften an einem separaten Ort (z.B. in einem struct ) speichern. Zum Beispiel maximale Lebenspunkte, Angriffsreichweite und sonstige konstante Werte müssen ja nicht für jede Instanz existieren. Dann musst du auch nicht für jeden Typen eine eigene Klasse basteln.

    Da kannst du auch einen Konstruktor machen mit dem Typen als Parameter, und die restlichen Werte berechnen sich dann daraus bzw. werden aus dem jeweiligen struct geholt (bei mehreren creepspezifische Strukturen z.B. in einem Array).



  • Hier sind schon soviele gute Kommentare gekommen, was man alles machen könnte. Das find ich super! Ich persönlich wäre auch für die Verwendung von Klassen mit Vererbung, wie bereits vorgeschlagen mit einer Basisklasse.

    Und damit es nicht gleich so kompliziert wird hier mal ein Beispiel:

    class Figure
    {
      private:
          int Health;
          int Strength;
          ...                // weitere Attribute von Figuren
      public:
          Figure();
          int gethealth();
          ...                // weitere Get-,Set- und andere Methoden
    };
    
    class Gremlin : public Figure
    {
       ...                   // eigene spezifische Attribute und Methoden 
    };
    

    und damit du nicht alles nochmal und nochmal schreiben musst,
    schreibe anstelle von Gremlin oder Monster1 einfach eigene Monstertyen.
    Vielleicht haben ja monster die untot sind von vorneherein irgendwelche
    besonderen Eigenschaften. z.B.: Koennten Baeren auch vom Typ (Monsterklasse)
    natuerlich sein.

    Ich glaube in deinem Falle ist dein Ideenreichtum noch mehr gefragt als die Umsetzung. Es gib so viel, dass man bei solchen Sachen beachten kann/soll/muss.



  • Nexus schrieb:

    T0bi schrieb:

    So könntest du via' Vererbung diese Eigenschaften für Creeps übernehmen und für spezielle Bosmonster erweitern.

    Oder du machst einfach ein Attribut für den Einheitentyp ( short ) und dann kannst du sehr viele Eigenschaften an einem separaten Ort (z.B. in einem struct ) speichern. Zum Beispiel maximale Lebenspunkte, Angriffsreichweite und sonstige konstante Werte müssen ja nicht für jede Instanz existieren. Dann musst du auch nicht für jeden Typen eine eigene Klasse basteln.

    Da kannst du auch einen Konstruktor machen mit dem Typen als Parameter, und die restlichen Werte berechnen sich dann daraus bzw. werden aus dem jeweiligen struct geholt (bei mehreren creepspezifische Strukturen z.B. in einem Array).

    Das wäre eine gte Idee, man könnte - wenn man Ahnung von hat - auch alles in einer DB speichern und dann die Creep Klasse initialisieren, bzw. man könnte die Daten in einer Externen .TXT Datei sichern und dann in der gewünschten Zeile die Daten auslesen, so kannst du deinen Speicher etwas schonen, nicht das wenn du Millionen von Creeptypen hast, der Speicher voll ist.

    Gruß Tobi.



  • T0bi schrieb:

    man könnte die Daten in einer Externen .TXT Datei sichern und dann in der gewünschten Zeile die Daten auslesen, so kannst du deinen Speicher etwas schonen, nicht das wenn du Millionen von Creeptypen hast, der Speicher voll ist.

    Sry, aber den Beitrag hier halte ich für fehl am Platz ^^ Er weiß noch nicht mal richtig was mit Klassen anzufangen und du gehst davon aus, dass es Millionen Creeptypen gibt bzw geben kann...

    Außerdem: Würd ich so was nicht in ne *.txt - Datei schreiben sondern binär in irgend ne Datei (oder halt DB) - wenn überhaupt. Eigentlich wird das Auslesen der Datei/DB bei fast allen "normalen" Projekten den Speichergewinn wieder minimieren... Und mal ehrlich - wie viel RAM hast du und wie groß ist deine Auslagerungsdatei? Mal angenommen, es sind insg. nur 4GB... Denkst du wirklich, dass du mit Creeptypen (selbst mit Millionen) alleine, auch nur 1% voll bekommst? Oo

    bb



  • unskilled schrieb:

    Sry, aber den Beitrag hier halte ich für fehl am Platz ^^ Er weiß noch nicht mal richtig was mit Klassen anzufangen und du gehst davon aus, dass es Millionen Creeptypen gibt bzw geben kann...

    Es ist trotzdem von Vorteil, wenn ihm gesagt wird, dass die vererbten Klassen nicht die beste Lösung bei diesem Problem ist. Klar kann es zur Übung sinnvoll sein, aber wenn man solche Projekte auch etwas grösser werden lässt und etwas ernsthafter bei der Sache ist, kann eine Datenbank schon behilflich sein.

    unskilled schrieb:

    Und mal ehrlich - wie viel RAM hast du und wie groß ist deine Auslagerungsdatei? Mal angenommen, es sind insg. nur 4GB... Denkst du wirklich, dass du mit Creeptypen (selbst mit Millionen) alleine, auch nur 1% voll bekommst? Oo

    Nehmen wir einmal an, es gibt für jeden Creeptypen neben etlichen int und float -Werten noch spezielle Attribute wie z.B. Grafikklassen und Soundsets etc. Wenn du das wirklich für jede Einheit kopieren willst, ist das sicher nicht gerade optimal für den RAM. Klar kann bei diesem Projekt noch nicht die Rede von so etwas sein, aber es ist trotzdem sauberer, man speichert die Werte nur einmal ab. Zentral verwaltete Werte kann man auch leichter verändern, und die Übersichtlichkeit wird gesteigert.

    Und überhaupt: Das Argument, man brauche heute wegen den leistungsfähigen Prozessoren nicht mehr stark auf Performance zu achten und Speicherplatz ist sowieso kein Problem mehr, kann man so ziemlich überall bringen. Trotzdem ist es gut, wenn man von Anfang an lernt, ressourcensparend zu programmieren. Man sieht ja z.B., dass neuere Computerspiele keineswegs schneller sind als alte, und das ist neben verbesserter Grafik etc. auch auf schlampigere und verschwenderische Programmierung zurückzuführen.



  • Ihr habt mich alle voll verwirrt xD
    Ich glaube, ich bin einfach noch nicht soweit. Wobei, wenn ich es nicht mache und mich reinhänge, komme ich auch nicht weiter.
    Aber mit den Klassen ist ja alles schön und gut, aber ich verstehe das mit public, privat und mit den Methoden nicht ganz.

    Also public bedeutet, dass der Anwender die Werte verändern kann?
    Privat bedeutet, dass nur eine interne Aufforderung die Werte ändern kann?
    Methoden sind... ähm damit kann man ja ka.^^
    Konstruktor weiß ich sowieso nicht. Obwohl ich mir das schon paarmal durchgelesen habe.

    Ich danke euch allen für die Hilfe. Sind bestimmt ganz tolle Sachen bei, aber ich verstehe fast nur Bahnhof 😉

    Ich habe mich bzw. meine C++ kenntnisse überschätzt. Ich sollte wohl erstmal damit anfangen, dass man durch die Welt laufen kann und auch auf Monster stößt.

    Kampfsystem, Rüstungen usw. sollen erst später dazu kommen. Damit ich wenigstens schonmal das Spiel ansich soweit fertig habe.
    Ich habe dafür ein halbes Jahr eingeplant. Aber ich denke, dass könnte schon länger werden.

    Quest möchte ich, wenn ich nun irgendwie die Klassen verstehe, auch schon einbauen.
    Wie z.B. Gehe zum Hof von "XXX YYY". Überbringe die Botschaft, dass blabla und soundso sich in der Kaserne melden sollen.

    Meint ihr, dass wäre realisierbar.

    Achja, ihr redet immer davon, dass der code so unendlich lang wird, wenn ich dass auf meine Art mache. Aber wenn ihr z.B.:

    class Monster
    {
    int Staerke
    usw.
    }
    macht, müsst ihr doch auch jedes Monster wieder einzeln ersellen.

    Ich meine, nicht jedes Monster hat die gleichen Werte...

    Achja, jemand hat hier in den Raum geworfen, dass die text datein in einer anderen Datei abzuspeichern sein.
    Das hört sich gut an. Würde den Code bestimmt überschaulicher machen.
    Kann mir jemand erklären, wie das gehen soll?

    Ich finde das echt super nett von euch, dass ihr einem anfänger so helft. Vielleicht, weil ihr selbst so schwierigkeiten hattet.
    Wenn ich das in 10 Jahren spo halbwegs kann, werde ich auch mein bestes geben, um "noobs" zu helfen 😉

    Grüße



  • Achja, ihr redet immer davon, dass der code so unendlich lang wird, wenn ich dass auf meine Art mache. Aber wenn ihr z.B.:

    class Monster
    {
    int Staerke
    usw.
    }
    

    macht, müsst ihr doch auch jedes Monster wieder einzeln ersellen.

    Naja... Man erstellt eine Instanz einer Klasse:

    Monstertyp Monster;
    

    Ich meine, nicht jedes Monster hat die gleichen Werte...

    Richtig, und hier kommt der Konstruktor ins Spiel.
    Wenn du eine Instanz einer Klasse erstellst, kannst du gleich die Attribute
    bestimmen, indem du einen überladenen Konstruktor aufrufst

    class Monstertyp
    {
      private:
         int health;
      public:
         Monster(int h); // Konstruktor
    };
    
    // Übergabe des Parameters h
    Monstertyp::Monster(int h)
    {
       health = h;
    }
    

    Achja, hier noch der Aufruf:

    // Erstellen eines Monsters mit 100 Lebenspunkten
      // Die Zahl legt somit den Wert fest
      Monstertyp Monster1(100);
    

    Bei solchen Themen könnt ich Stunden herumprobieren.

    Noch ein Tip:
    Lass dich von den Projektgrößen und dem Umfang nicht einschüchtern.
    Step-by-Step ist hier das Zauberwort, außerdem wächst man mit der Aufgabe.
    Also noch viel Spass!


Log in to reply