Problem mit Snake...(erledigt)



  • Das würde dann ja bezwecken, dass die Schlange, sobald sie in eine Wand fährt, auf der anderen Seite des Feldes wieder herauskommt, verstehe ich das richtig? Ich habe gemerkt, dass ich einige überflüssige Abfragen habe, die Abfragen nach dem "oder" (||) sind unnötig, das sie nie eintreffen werden. @_matze ich habe deinen Vorschlag einmal miteingebaut, und es funktioniert nur teilweise. Wenn die Schlange horizontal kriecht, dann passiert was komisches, wenn sie in die Wand links oder rechts fährt. Zuerst wird das Objekt an zwei völlig falsche Orte gesetzt, zuerst eine Zeile oben, dann eine Zeile unten, komischerweise wird aber die Variable "Zeile" nicht verändert (???) Erst dann stimmt die Position wieder. Ich kann das Problem nicht so richtig beschreiben, am besten ihr seht's euch selbst kurz an, ich habs in dev-cpp geschrieben.

    => Hab den veränderten Code oben aktualisiert.

    mfg Papa_Noah



  • PapaNoah schrieb:

    Das würde dann ja bezwecken, dass die Schlange, sobald sie in eine Wand fährt, auf der anderen Seite des Feldes wieder herauskommt, verstehe ich das richtig?

    Ja, klar. Funktioniert Snake nicht so? Das Snake, dass damals auf meinem Handy war, zeigte jedenfalls genau dieses Verhalten. Ich dachte, das wäre von dir gewünscht.

    PapaNoah schrieb:

    @_matze ich habe deinen Vorschlag einmal miteingebaut, und es funktioniert nur teilweise.

    Sorry, war nicht getestet und eher nur als ein Wink in die richtige Richtung zu verstehen. Dass sich die Zeilenposition verändert, ist aber irgendwie komisch. Mal sehen, ob ich gleich noch Zeit habe, mir das kurz anzusehen (hab viel zu tun im Moment). Vielleicht macht's ja auch ein anderer in der Zwischenzeit.



  • _matze schrieb:

    PapaNoah schrieb:

    Das würde dann ja bezwecken, dass die Schlange, sobald sie in eine Wand fährt, auf der anderen Seite des Feldes wieder herauskommt, verstehe ich das richtig?

    Ja, klar. Funktioniert Snake nicht so? Das Snake, dass damals auf meinem Handy war, zeigte jedenfalls genau dieses Verhalten. Ich dachte, das wäre von dir gewünscht.

    Ja ich mag mich auch daran erinnern, dass ich 2 Versionen Snake gespielt hatte, zum einen die Version, bei welcher man durch die Wände konnte, bei der anderen konnte man das nicht. Das war eigentlich auch nicht das Problem, die Abfragen bereiteten mir Kopfzerbrechen. Sry das sollte nicht irgendwie eine bös gemeinte Frage sein, ich war mir nur nicht ganz sicher, ob dein Vorschlag auch das bewirkt.

    _matze schrieb:

    PapaNoah schrieb:

    @_matze ich habe deinen Vorschlag einmal miteingebaut, und es funktioniert nur teilweise.

    Sorry, war nicht getestet und eher nur als ein Wink in die richtige Richtung zu verstehen. Dass sich die Zeilenposition verändert, ist aber irgendwie komisch. Mal sehen, ob ich gleich noch Zeit habe, mir das kurz anzusehen (hab viel zu tun im Moment). Vielleicht macht's ja auch ein anderer in der Zwischenzeit.

    Kein Problem, es hat mir auf jeden Fall mal einen Schritt weiter geholfen, da nun in etwa das passiert, was ich möchte. Wie gesagt nur diese komische Positionierung stört mich im Moment noch. Über das Aussehen des Spiels mache ich mir später Gedanken, es soll halt einfach mal funktionieren 😉

    Danke für deine Mühe, falls du die Zeit findest möchte ich dir schon im Voraus für die Hilfe danken!

    mfg PapaNoah



  • Notier in bewegeObjekt im case 'L' mal Folgendes (lösche den Rest außer dem break):

    aktuelleSpalte = aktuelleSpalte<=0 ? ANZAHL_SPALTEN-1 : aktuelleSpalte - 1;
    

    Der Fehler ist, dass du einen negativen Spaltenwert zulässt. Damit gehst du im Array auch eine Zeile zurück. Der Inhalt des Arrays liegt ja tatsächlich eindimensional hintereinander im Speicher, auch wenn du es zweidimensional deklariert hast und so ansprichst.

    EDIT: Und die Reihenfolge sollte

    bewegeObjekt(); 
    			zeichneSpielfeld();
    

    sein, sonst stimmt deine Zeilen-/Spalten-Angabe nicht (sie hinkt immer einen hinterher).



  • Blöde Frage, für was steht das Fragezeichen?

    aktuelleSpalte = aktuelleSpalte<=0 ? ANZAHL_SPALTEN-1 : aktuelleSpalte - 1;

    Muss ich das alles auf eine Zeile tun?

    EDIT: Frage oben hat sich erledigt 🙂 Es funktioniert nun, herzlichen Dank!
    Trotzdem nimmt es mich wunder, was diese Zeile genau macht, ich verstehe
    sie nicht ganz :S...

    mfg PapaNoah



  • Das ist der ternäre Operator (der als einziger Operator 3 Operanden braucht). Das ist quasi ein if-ersatz (der aber nur in Ausdrücken verwendet und nicht alleine stehen kann!).

    Statt

    if(b) {
      x=1;
    }else {
      x=0;
    }
    

    kannst du auch

    x = b ? 1 : 0;  //wenn b true ist, dann weise 1 zu, sonst 0
    

    schreiben.

    EDIT: Das Verwenden dieses Operator ist natürlich nicht immer zu empfehlen. Oft leidet die Lesbarkeit darunter. Auch, wenn man meist ein paar Zeilen damit spart.



  • Achso verstehe, das hab ich noch nie gesehen 😕
    Aber es ist logisch, hehe.
    Wieder etwas neue gelernt :p 👍

    Vielen Dank für deine Hilfe, ich bin echt froh, dass das jetzt funktioniert!
    mfg
    PapaNoah



  • Gern geschehen. Du kannst ja später den fertigen Code posten, wenn du Lust hast. Ich bin gespannt, wie du das Wachsen der Schlange löst.



  • Menno... jetzt habe ich mir dein Problem auch angesehen und du bist fertig! Egal hier ist meine Lösung mit einigen Veränderungen

    #define START_ZEILE 5
    #define START_SPALTE 9
    #define ANZAHL_ZEILEN 10
    #define ANZAHL_SPALTEN 10
    
    typedef struct {
        int x;
        int y;
        int dx;
        int dy;
    } snake_t;
    
    void snake_init(void);
    void snake_update(void);
    int snake_check_collision(void);
    void snake_move(void);
    void snake_draw(void);
    
    static snake_t snake;
    char spielfeld[ANZAHL_ZEILEN][ANZAHL_SPALTEN] = {
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' ',' '},
    };
    
    int main(void)
    {
        snake_init();
        while(true) {
            snake_update();
            if(snake_check_collision())
                break;
            snake_move();
            snake_draw();
            Sleep(500);
        }
        printf("\a");
        system("pause");
    }
    
    void snake_init(void)
    {
        snake.x = START_SPALTE;
        snake.y = START_ZEILE;
        snake.dx = -1;
        snake.dy = 0;
    }
    
    void snake_update(void)
    {
        int c;
        if(kbhit()) {
            c = getch();
            if(c == 'w') {
                snake.dx = 0;
                snake.dy = -1;
            } else if(c == 'a') {
                snake.dx = -1;
                snake.dy = 0;
            } else if(c == 's') {
                snake.dx = 0;
                snake.dy = 1;
            } else if(c == 'd') {
                snake.dx = 1;
                snake.dy = 0;
            }
        }
        fflush(stdin);
    }
    
    int snake_check_collision(void)
    {
        if(snake.x + snake.dx < 0 || snake.x + snake.dx > ANZAHL_SPALTEN - 1||
           snake.y + snake.dy < 0 || snake.y + snake.dy > ANZAHL_ZEILEN - 1)
            return 1;
        return 0;
    }
    
    void snake_move(void)
    {
        snake.x += snake.dx;
        snake.y += snake.dy;
    }
    
    void snake_draw(void)
    {
        int zeile, spalte;
    
        system("cls");
    
        printf("+");
        for(spalte = 0; spalte < ANZAHL_SPALTEN; spalte++) {
            printf("-");
        }
        printf("+\n");
        for (zeile = 0; zeile < ANZAHL_ZEILEN; zeile++) {
            printf("|");
            for (spalte = 0; spalte < ANZAHL_SPALTEN; spalte++) {
                printf("%s", (snake.x == spalte && snake.y == zeile) ? "x" : " ");
            }
            printf("|\n");
        }
        printf("+");
        for(spalte = 0; spalte < ANZAHL_SPALTEN; spalte++) {
            printf("-");
        }
        printf("+\n");
    }
    


  • Werde ich machen 🙂

    Ich habe bis jetzt keine Ahnung wie ich das mit der Schlange hinkriegen soll, erst mal Mittagessen 😉

    mfg PapaNoah



  • Ein kleiner Tip:

    typedef struct {
        int x;
        int y;
        int dx;
        int dy;
    } snake_tail_t;
    
    typedef struct {
        int length;
        snake_tail_t tail[SNAKE_MAXLENGTH];
    } snake_t;
    

    Der Kopf ist snake.tail[0]. Der "Schwanz" der Schlange ist gespeicher in den restlichen Elementen von snake.tail[]. In der Funktion snake_move() muß jedes Schwanzstück jeweils die Informationen seines direkten Vorgängers übernehmen.

    Viel spaß! 🙂



  • Damit hast du aber schon sehr viel verraten. 🙂



  • Ich weiß nicht, ob das die beste Lösung ist. Es ist aber am naheliegendsten. Ich hab das eben zu Ende programmiert und es ist ganz witzig. Aber die Win32-Konsole flickert so eklig. Kennt da jemand einen Trick, wie ich das verhindern kann? Ich müßte ja nur vor dem Neuzeichnen die Bildschirm-Aktualisierung der Konsole deaktiveren und nach dem Neuzeichnen wieder freigeben. Aber das geht in der Konsole nicht, oder?


Anmelden zum Antworten