Kleines logisches Problem in meinem Programm.



  • Hi,

    im Vorrrrrrraus: Es handelt sich hier um ein logisches Problem. Wer bei solchen also nicht helfen will, kann jetzt wieder gehen 🤡

    Ich habe bei einem kleinen Spielchen das ich gerade Bastle ein kleines Problem. In folgender Datei befinden sich sämtlich bisher verwendenen Bilder, sowie der komplette Quellcode und ein Visual Studio 2005 Projekt. Zum Kompilieren wird eine aktuelle Version der SDL Lib gebraucht.

    http://www.megaupload.com/?d=JQYZRGGR

    Ich will natürlich nicht dass ihr alle Dateien durchwühlen müsst, also beschreibe ich mal wo es hakt:

    In folgendem Abschnitt des Codes aus der Datei "Gamestates.h", soll praktisch ein Bitmapaustausch stattfinden. Wird die Taste "Pfeiltaste oben" oder "Pfeiltaste unten" gedrückt, so soll ein Sprite unsichtbar gemacht werden während das andere auftaucht. Ausgedrückt in diesem kleinen Codeschnipsel:

    //Wenn "Pfeiltaste oben" oder "Pfeiltaste unten" gedrückt wurde
    		if(keys[SDLK_UP] || keys[SDLK_DOWN])
    		{
    			newGameIsSelected = !newGameIsSelected;
                            //Diese Variable benutze ich um rauszufinden was gerade
                            //angewählt ist. Eigentlich will ich dann einen zweiten
                            //Button mit "Exit" anwählen, welcher aber noch nicht
                            //vorhanden ist
    		}
    
    		//Escape
    		if(keys[SDLK_ESCAPE])
    		{
    			return EXIT_PROGRAM;
    		}
    
    		////////////////////////////////////////////////
    
    		//Zeichnen//////////////////////////////////////
    		if(newGameIsSelected)
    		{
    			newGame->visibility(false);
    			newGameSelected->visibility(true);
    		}
    		else
    		{
    			newGame->visibility(true);
    			newGameSelected->visibility(false);
    		}
    

    newGame und newGameSelected sind jeweils die genannten Sprites, zwischen denen ein Austausch stattfinden soll. Die Methode visibility(bool isVisible); ändert dabei einfach, ob das Ding jetzt zu zeichnen ist oder nicht. Wenn es weiter interresant sein sollte, findet ihr näheres in den entsprechenden Quellcodedateien ("Sprite.h", "Sprite.cpp"). Gezeichnet werden die Bitmaps, indem sie am Anfang der Methode (hier nicht sichtbar zugunsten der Übersichtlichkeit) als Zeiger einer Verwaltungsklasse (mit dem Namen "Application") übergeben wird.

    Das Problem welches nun auftritt ist, das nur eine der beiden Bitmaps gezeichnet wird. Bzw. die Bitmap die gezeichnet wird, immer die gleiche bleibt.

    Und ich komm nach langem Grübeln nicht dahinter weshalb.

    Ich hoffe jemand von euch hat da ne Idee,

    mfg Travis



  • hm...
    hab zwar kP wo der fehler konkret liegt (das ganze projekt runterzuladen ist meiner meinung nach n bissl zu viel aufwand 😉 ) aber ich würde mal empfehlen, einfach mal den debugger anzuwerfen, und zu schauen, was für werte die variablen deiner sprite-objekte beim aufruf deiner "draw()"-funktion haben, wenn da alles richtig ist, schaust du dir halt die "draw"-funktion genauer an, falls nicht, muss schon beim aufruf von "visibility()" irgendetwas schief gehen.[warum nich "setVisible" ?, wäre irgendwie einleuchtender, was die funktion macht...] Ich kann das von meinem standpunkt aus irgendwie nicht so wirklich einschätzen, ob dieser codefragment

    if(newGameIsSelected){
       newGame->visibility(false);
       newGameSelected->visibility(true);
    }else{
       newGame->visibility(true);
       newGameSelected->visibility(false);
    }
    

    sich auch an der richtigen stelle befindet, und tatsächlich bei jedem betätigen der taste ausgeführt wird.

    und ganz allgemein: wenn du schon fast so etwas wie eine eigene GUI entwirfst, dann erstell doch gleich mal eine eigene "button" klasse (mit den ganzen sprites und bFocus-eigenschaften etc) , eine "menu" klasse, die die "buttons" sowie den cursel speichert usw usw... dann lässt sich das durcheinander vermeiden:

    if(keys[SDLK_UP] || keys[SDLK_DOWN])
    {
       newGameIsSelected = !newGameIsSelected;
    }
    

    was willst du da machen, wenn du irgendwann ein menu mit "ne" "save" "load" "credits" "options" "exit" usw hast? 50000 bool variablen anlegen? würde nicht sonderlich zur übersichtlichkeit beitragen 🤡



  • Laut Debugger sind die Werte in Ordnung.

    Zur GUI: Das Spiel hat wenns hochkommt 4 Buttons... überlass das Klassendesign ruhig mir 🙂

    Ausserdem sollten die Anweisungen auch bei jedem Tastendruck ausgeführt werden. ESC Taste funktioniert prima.



  • das der wert von newGameIsSelected meist richtig ist glaub ich gern

    in void Barkanoid::Application::run()
    frag mal am anfang ob sprites.size() > 0 ist

    (und lass mich bitte wissen, hab kein win und testn ohne mitgelieferten makefile ist zu muehsam)

    alle achtung davor wie verwirrend man so eine mailoop gestalten kann, classendesign ueberlass ich aber gerne dir, misch mich da sicher nicht ein:-)



  • das sprite wird ohne fehler geladen, falls du das meinst. wenn ich nur eines von beiden zeichnen lasse funktioniert das ja prima.



  • schreib mal das

    std::cout << "Sprites.size()=" << sprites.size() << std::endl;

    als erste zeile in void Barkanoid::Application::run()
    (include <iostream> nicht vergessen

    wuerd mich interessieren ob da dann immer 0 steht

    da naechste checkpunkt waer dann in der loop
    if(sprites[i]->visible()){
    //kommt er jede loop daher?
    sprites[i]->draw();
    }

    und im sprite

    if(m_visible)
    {
    //macht er das jede loop fuer jede was gezeichnet werden soll?
    SDL_BlitSurface(m_bitmap,&m_src,m_screen,&m_position);
    }



  • Sorry dAhA, dass ich deine Vorschläge ignoriere, jedoch liegt der Fehler sicher woanders.

    Es ist langsam zum verzweifeln. Folgende Anwendungsfälle funktionieren wenn die Taste "Pfeiltaste nach oben" gedrückt wurde: [code jetzt leicht abgeändert]

    Anwendungsfall 1:

    while(SDL_PollEvent(&event))
    		{
    
    			switch(event.key.keysym.sym)
    			{
    			case SDLK_UP:
    
    				std::cout<<"lolol"; //Funktioniert!
    				break;
    
    			case SDLK_DOWN:
    
    				break;
    			case SDLK_ESCAPE:
    				return EXIT_PROGRAM;
    				break;
    			}
    
    			switch(event.type)
    			{
    			case SDL_QUIT:
    				return EXIT_PROGRAM;
    				break;
    			}
    		}
    

    AnwFall 2:

    //bissel gekürzt
    
    switch(event.key.keysym.sym)
    			{
    			case SDLK_UP:
    
    				return EXIT_PROGRAM; //funzt
    				break;
    
    			case SDLK_DOWN:
    
    				break;
    			case SDLK_ESCAPE:
    				return EXIT_PROGRAM;
    				break;
    			}
    

    Aber vollkommen unlogischerweise funktioniert folgendes nicht:

    switch(event.key.keysym.sym)
    			{
    			case SDLK_UP:
    
    				newGame->visibility(false);
    				break;
    
    			case SDLK_DOWN:
    
    				break;
    			case SDLK_ESCAPE:
    				return EXIT_PROGRAM;
    				break;
    			}
    

    wenn ich jedoch schlicht und einfach irgendwo anders an der stelle des codes die sichtbarkeit ausstelle, verschwindet das sprite wie es soll.

    langsam bin ich echt ratlos 😕 debugger gibt auch keine anderen werde als erwartet.


  • Mod

    TravisG schrieb:

    if(keys[SDLK_UP] || keys[SDLK_DOWN])
    			newGameIsSelected = !newGameIsSelected;
    

    ist das dauernde flippen absicht?



  • TravisG schrieb:

    Sorry dAhA, dass ich deine Vorschläge ignoriere, jedoch liegt der Fehler sicher woanders.

    naja, dann wuensch ich dir weiterhin viel spass beim fehler suchen

    edit:
    ich finds lustig

    TravisG schrieb:

    Es ist langsam zum verzweifeln.

    TravisG schrieb:

    langsam bin ich echt ratlos

    bei mir geht dein prog mittlerweile, gratulation, ist damit auf mehreren plattformen lauffaehig, einmal is neues spiel hell, einmal dunkel..



  • @TravisG: Lern einfach mal den Debugger benutzen. f'`8k

    Autocogito

    Gruß, TGGC (making great games since 1992)



  • daHa schrieb:

    TravisG schrieb:

    Sorry dAhA, dass ich deine Vorschläge ignoriere, jedoch liegt der Fehler sicher woanders.

    naja, dann wuensch ich dir weiterhin viel spass beim fehler suchen

    edit:
    ich finds lustig

    TravisG schrieb:

    Es ist langsam zum verzweifeln.

    TravisG schrieb:

    langsam bin ich echt ratlos

    bei mir geht dein prog mittlerweile, gratulation, ist damit auf mehreren plattformen lauffaehig, einmal is neues spiel hell, einmal dunkel..

    kein grund gleich sauer zu werden, jeder kann sich ja mal irren. ich glaub ich weiss jetzt worauf du hinaus wolltest, hab das wohl irgendwie überlesen. da du wohl hier kein bock mehr hast versuch ich jetzt rauszufinden wie ich den fehler mit sprite.size() = 0 behebe.

    edit:

    TravisG schrieb:

    jeder kann sich ja mal irren

    sorry, bis auf tggc natürlich.



  • bin und war nicht sauer

    vielleich hilft dir das zu einem erfolgerlebnis

    constructor
    destructor
    copyconstructor
    zuweisungsoperator
    haengt wie mit
    variable
    referenz
    pointer
    zusammen, insbesondere, bezug zu deinem problem, wenn mans an funktionen uebergibt

    funktionen die behauten etwas zurueckzugeben sollten das auch tun
    zuerst wild drauflos coden und sich um speicherfreigaben dann zu kuemmern ist ganz schlecht
    compiler warnings sollte man ernst nehemn



  • daHa schrieb:

    bin und war nicht sauer

    vielleich hilft dir das zu einem erfolgerlebnis

    constructor
    destructor
    copyconstructor
    zuweisungsoperator
    haengt wie mit
    variable
    referenz
    pointer
    zusammen, insbesondere, bezug zu deinem problem, wenn mans an funktionen uebergibt

    danke, im moment versteh ich noch nicht was du damit sagen willst, aber vielleicht find ich das noch raus 🙂



  • hm.. so wie es aussieht wird das Objekt der Klasse GS_Mainmenu irgendwo gelöscht / neu erstellt oder ich habe irgendwas anderes verpasst. nach deinem tip probierte ich mal das mit einem counter aus:

    int run (t Application)
    {
    //...
    ++counter;
    std::cout<<"counter: "<<counter<<std::endl;
    
    //..
    }
    

    und es wird tatsächlich immer 1 ausgegeben.

    jetzt muss ich noch rausfinden wo das speicherproblem entsteht, auf den ersten blick sehe ich hier nichts weiter.



  • Vielleicht jetzt einfach mal an den richtigen Stellen die Breakpoints setzen? f'`8k

    Autocogito

    Gruß, TGGC (making great games since 1992)



  • int run (t Application)

    was passiert da?

    constructor
    destructor
    copyconstructor
    zuweisungsoperator

    und warum?
    und wie koenntest da was beeinflussen?

    wennst das hast bist einen wirklichen schritt weiter gekommen, dann fehlt dir nur mehr sauberes aufraeumen, und aja, das mit den rueckgabewerten von funktionen

    so nutz man optimal einen regentag



  • ja, das problem ist endlich gelöst. jetzt wo ich es entdeckt habe erscheint es mir doch ziemlich doof, so etwas zu übersehen. danke für die hilfe


Anmelden zum Antworten