problem mit klassen



  • ok, also alles wird unüberischtlich hier 😃 aber die relevanten teile :

    also erstmal die klasse

    class cschuss
    {
    public:
    
        int x_pos_schuss1 , y_pos_schuss , x_pos_schuss2;
    
        cschuss(int x, int y)
        {
            y_pos_schuss  = y-1;
            x_pos_schuss1 = x+2;
            x_pos_schuss2 = x+9;
        }
    
        void schuss_logik()
        {
    
             if(GetTickCount()>zeit)
             {
                 y_pos_schuss--;
                 zeit=GetTickCount()+20;
             }
        } 
    
        void schuss_grafik()
        {
            textcolor(YELLOW);
            gotoxy(x_pos_schuss1,y_pos_schuss);
            cout<<"*";
            gotoxy(x_pos_schuss1,y_pos_schuss+1);
            cout<<" ";
    
            gotoxy(x_pos_schuss2,y_pos_schuss);
            cout<<"*";
            gotoxy(x_pos_schuss2,y_pos_schuss+1);
            cout<<" ";
    
            if(y_pos_schuss<2)
            {
                gotoxy(x_pos_schuss1,y_pos_schuss);
                cout<<" ";
                gotoxy(x_pos_schuss2,y_pos_schuss);
                cout<<" ";
            } 
    
            gotoxy(x_pos_schuss1,y_pos_schuss+2); cout<<" ";
            gotoxy(x_pos_schuss2,y_pos_schuss+2); cout<<" "; 
    
        }                  
    
    };
    

    dann die spielschleife:

    cschuss* shot = 0;
    
    while(!spiel_schleife)
        {
            delay(30);
            steuerung();
            if(shot)
                    shot->schuss_logik();
    
            grafik();
        }
    

    und dann hier noch die zwei funktionen steuerung() und grafik()

    void steuerung()
    {
        if (kbhit())
        {
             eingabe = getch();
    
             if(eingabe == 75)
                 richtung = 1;
             if(eingabe == 77)
                 richtung = 2;
             if(eingabe == 80)
                 richtung = 0;
             if(eingabe == 32)
             {
                      shot = new cschuss(x_pos_spieler,y_pos_spieler);
                      schuss++;                
             }
             if(eingabe == 27)
                      spiel_schleife = true;
    
             if(eingabe == 'l')
                      --life;
        } 
    
        if(richtung == 1 && x_pos_spieler > 2)
        {
            x_old_pos_spieler = x_pos_spieler;
            x_pos_spieler--;        
         }    
        if(richtung == 2 && x_pos_spieler < 72)
        {
            x_old_pos_spieler = x_pos_spieler; 
            x_pos_spieler++;           
        }
    
    }
    
    void grafik()
    {   
        gotoxy(3,46); textcolor(142); cout<<"Life";
    
        gotoxy(8,46); textcolor(8); 
        for (int i=0;i<20;++i)
            cout<<balken;
    
        textcolor(LIGHTRED);
        for(int i=0;i<life;++i)
        {
            gotoxy(8+i,46);    
            cout<<balken;
        }
    
        if(shot)
        shot->schuss_grafik();
    
        textcolor(7);
        gotoxy(x_old_pos_spieler,y_pos_spieler);   cout<<"        ";
        gotoxy(x_old_pos_spieler,y_pos_spieler+1); cout<<"        ";                                                       
        gotoxy(x_pos_spieler,y_pos_spieler);   cout<<"|  /\\  |";
        gotoxy(x_pos_spieler,y_pos_spieler+1); cout<<"||=||=||";
    }
    


  • Also shot = new blub; kann ja nciht funktionieren. Das rufst du ja in einer ganz anderen Funktion auf wo shot nicht bekannt ist. Also da müsstest du Parameter übergeben:

    cschuss* shot = 0;
    
    while(!spiel_schleife)
    {
        delay(30);
        steuerung(&shot); // shot als Parameter übergeben
        if(shot)
            shot->schuss_logik();    
        grafik();
    }
    
    void steuerung (cschuss*& shot) // geht sowas? probier das mal :D
    

    MfG SideWinder



  • DANKE !!
    funktionier 😃

    nur

    hab ich parameter geändert in

    steuerung(shot);
    

    also, nich als referenz , dann gings 😃

    jzet noch eine frage, es sollen ja mehrer schüsse gleichzeitig fliegen, deshalb ja übehraupt die klasse, sonst wärs ja auch ohne gegangen 🙂

    kann ich einfach shot mit nem index machen ?! also shot[index] ?!
    dann könnte man ganz leicht mehrere verwalten ...



  • 1. Ja klar ohne '&', dachte vorher noch an cschuss** und &shot, dann ist mir aber gekommen, dass Referenzen auf Zeiger auch möglich sein sollten und hab vergessen oben das '&' wieder rauszunehmen.

    2. Nicht so ganz. shot muss dann ein Array von cschuss sein. Viel einfacher als sich da jetzt aber um Speicher zu kümmern, ist es allerdings, ein bereits vorgefertigtes Array aus der STL zu benützen:

    #include <vector>
    using namespace std;
    
    ...
    
    vector<cschuss*> shots;
    
    ...
    
    // Statt shot = new blub;
    shots.push_back(new blub);
    
    // Statt if(shot)
    if(!shots.empty())
        ...
    
    // Statt shot->do_something();
    shot[i]->do_something();
    

    Wenn du alle Schüsse in steuerung() durchgehen willst kannst du dafür Iteratoren benützen:

    vector<cschuss*>::iterator iter = shots.begin();
    while(iter != shots.end())
    {
        (*iter)->do_something();
        ++iter;
    }
    

    Achja und den Kopf von steuerung musst du dann natürlcih auch anpassen, dementsprechend dann eine Referenz auf vector<cschuss*>

    MfG SideWinder



  • ok, vielen dank, werd mich jetzt ma dran setzen un das ausprobieren

    achja, eine sache noch:
    wie lösche ich shot wieder ?!

    nit delete shot; funktionierts irgendwie nich, also bekomm syntax fehler



  • Wo möchtest du denn shot löschen? Bereits den Vektor? Die einzelne Variable die du mit new angelegt hast? Also so wie du das bis jetzt hast sollte delete shot; funktionieren.

    MfG SideWinder



  • noch erstma nur mit dem einen shot

    habs so

    if(shot && shot.y_pos_schuss > 1)
            {
                    shot->schuss_logik();
                    shot->schuss_grafik();
            }
            else
                    delete shot;
    

    mit fehler
    request for member `y_pos_schuss' in `shot', which is of non-class type `cschuss*'



  • Da es sich um einen Zeiger handelt musst du zuerst sagen, dass du nicht den Zeiger haben willst, sondern das Objekt auf das er zeigt. Dann kannst du die Variable abrufen:

    (*shot).y_pos;
    

    Da es den faulen C++-Programmieren aber leid war immer soviel zu schreiben, noch dazu Sonderzeichen wurde dafür ein eigener Operator eingeführt:

    shot->y_pos;
    

    Achja und Variablen (also Attribute) von Klassen public zu machen ist gar nicht gut. Da verwendet man Getter&Setter-Methoden, also soetwas:

    class foo
    {
        int m_bar;
    
        public:
        int getBar ();
        void setBar (int bar);
    }
    
    int foo::getBar () { return m_bar; }
    void foo:setBar (int bar) { m_bar = bar; }
    

    Dann kannst du über diese Methoden auf deine Variable zugreifen, shot bleibt aber ein Zeiger, der richtige Operator ist also immer noch gefragt:

    if(shot && shot->getYPos() > 1)
     ...
    

    MfG SideWinder



  • vielen dank, nochma ^^

    ja, das mit public weiss ich ^^



  • ok, hab noch paar probleme mit den vectoren

    also;
    kopf der steuerung:

    void steuerung(vector<cSchuss*>)
    

    un übergabe:

    steuerung(&shots);
    

    un dann frage, zum berechnen & zeichnen aller schüsse , woltles es so machen, also der code befindet sich inner main inner spielschleife:

    if(!shots.empty())
            {
                    vector<cschuss*>::iterator iter = shots.begin();
                    while(iter != shots.end())
                    {
                        (*iter)->logik();
                        (*iter)->grafik();
                        ++iter;
                    }
            }
    


  • Und dein Problem lautet wie?

    Ich sag dir mal kurz was ich auf den ersten Blick sehe:

    1. Referenz auf den Vektor übergeben.
    2. Referenzen übergibt der Compiler automatisch, da muss kein & davor um die Adresse zu erhalten.

    MfG SideWinder



  • das problem, kurz

    der übergabe / bzw. der erwartete übergabewert stimmt nicht

    also
    void steuerung(vector<cSchuss*>) stimmt

    nur übergeben einfach ohne & ?!



  • Nein stimmt nicht. Wir haben uns ja auf eine Referenzübergabe geeinigt:
    [cpp]
    // Deklaration einer Funktion die einen Parameter als Referenz übernimmt
    void steuerung (vector<cschuss*>& shots)

    // Im Gegensatz zu Zeigern sind Referenzen andere Namen für bestehende Variablen
    // und nicht Zeiger auf Adressen im Speicher, daher haben wir auch nicht die
    // Speicheradresse der Variable mitzuteilen sondern die Variable selbst:
    steuerung(shots);
    [/cpp]

    Edit: Ein paar Enter eingefügt damit der Thread nicht horizontal über 3 Bildschirme verläuft.

    MfG SideWinder



  • ahhh *leucht* ... mir ging ein licht auf 😃
    klar, so isses ^^
    vielen dank

    jetzt hab ich nur noch en verarbeitungs problem, also das mit logik() un grafik() .. weil er arbeit den nächsten schuss erst ab, wenn der vorige fertig is ... aber das is doch, hoffentlich, leicht zu beheben

    also, nochma danke 🙂



  • ok, nach langen versuchen den fehler zu finden, muss ich mich doch noch ma hier melden ...

    und zwar, habe immer noch das problem, das die schüsse nacheinander abgearbeitet werden ...
    hier der code

    if(!shots.empty())
            {
                    vector<cSchuss*>::iterator iter = shots.begin();
                    while(iter != shots.end())
                    {
                        if((*iter)->y_pos_schuss > 2)
                        {
                           (*iter)->logik();       
                           (*iter)->grafik();
                        }    
                        ++iter;
                    }
            }
    

    das ganze befindet sich in der spiel schleife ....

    achja, noch eine kleine sache, wie kann ich einzelne / den kompletten vector löschen ?!
    mit ?

    delete (*iter);
    


  • ich verzweile fast ... 😃

    bekomms einfach nicht hin, das die schüsse gleichzeitig abgearbeitet werden ....
    irgendwie komm ich nich auf den fehler ...



  • 1. Natürlich werden alle Schüsse hintereinander abgearbeitet -> am PC gibt es (außer du hast HT-Technologie, zwei Prozessoren, ...) keine Gleichzeitigkeit. Du kannst im besten Fall erreichen, dass alle Schüsse auf Basis der gleichen Daten berechnet werden und die jeweils neuen Daten erst *nach* dem Durchlauf zählen.

    2. Den kompletten Vektor leeren kannst du mit:

    vec.clear();
    

    Achtung: In deinem Fall hast du dynamisch erzeugte Objekte in deinem Vektor, das heißt du musst noch für jedes Element vorher delete aufrufen:

    vector<cschuss*>::iterator iter = shots.begin();
    while(iter != shots.end())
    {
        delete *iter;
        ++iter;
    }
    

    3. Einzelne Elemente kannst du über den Iterator löschen (auch hier normalerweise *kein* delete notwendig, da die Resorucen vom Vektor selbst freigegeben werden -> da deine Resourcen aber auf weitere Resourcen zeigen musst du wiederrum selbst Hand anlegen)

    // Bei dir also:
    delete *iter;
    iter.remove();
    

    MfG SideWinder



  • ok, danke

    aber hier nochma (mit kommentaren / fragen)

    if(!shots.empty()) // also, wenn "shots" nicht leer ist
            {
                    iter = shots.begin();  // iter auf anfangsposition setzen
                    while(iter != shots.end()) // solange nicht das ende des vectores erreicht wird
                    {
                        if((*iter)->y_pos_schuss > 2) // der schuss soll nich höher als y = 2 fliegen
                        {
                           (*iter)->logik(); //positionsberechnung für den aktuellen schuss      
                           (*iter)->grafik(); //zeichnen des aktuellen schusses
    
                        }    
    
                        ++iter; //aktuellen schuss ändern
                    }
            }
    

    so, die funktionen logik() und grafik() sind aber so aufgebaut, das sie pro aufruf, die position nur um 1 verändern, un dem entsprechend müsste das programm doch so laufen:

    1. schuss
    logik()
    grafik()

    ++iter -> 2.schuss
    logik()
    grafik()

    usw.

    also, müsster er doch eigetnlich alle schüsse "gleichzeitig" ausführen ...



  • *topic wieder hochpush*
    sry , aber hab immer ncoh keine lsg gefunden ....



  • *push* (sry)


Anmelden zum Antworten