Das Menue

So, im Moment sind wir so weit, dass wir wenn wir unsere Exe starten, vor einem Orangen Hintergrund Einen schrift zug sehen, und wenn wir dann eine Taste drücken geht das Programm wieder aus; das ist doch schonmal gar nicht schlecht. Jetzt wäre es natürlich noch besser, wenn das Programm dann weitergeht :-) Und was müsste jetzt kommen? Richtig, das Menue. Wir brauchen jetzt ein Menue, dass uns mit dem Programm interagieren lässt.

Aufruf des Menues

Da bisher nur der Konstruktor unseres Programms aufgerufen wurde, und es extrem unsauber wäre das Menue vom Konstruktor aus aufzurufen, wird das Menue von außen aufgerufen. Das passiert in der main() mit der Zeile „Game→MainMenue();“ Also auf in die 4gewinnt.cpp und, falls das noch nicht passiert ist, die VierGewinnt::MainMenue() - Methode erstellen.

Der Code ...

Das Ganze sieht dann so aus: (aber es ist einfacher als es aussieht, also keine Panik ;-) )

void VierGewinnt::MainMenue(){
    kbd::tasten_leeren();
 
    std::vector<TFONT*> MenuePunkte;
    TFONT *MenuePunkt;
    std::string Caption[4];
    int i = 0;
 
    Caption[0] = "Spiel Starten PvP";
    Caption[1] = "Spiel Starten PvE";
    Caption[2] = "Optionen";
    Caption[3] = "Spiel Beenden";
 
    MenueHintergrund->Anzeigen();
 
    for(i = 0;i<4;i++){
        MenuePunkt = new TFONT();
        MenuePunkt->TextZuweisen(Caption[i].c_str());
        MenuePunkt->PositionSetzen((SCREEN_W - (Caption[i].length()*50))/2,
                              (((SCREEN_H / /*Temp.size() == */4)-50)/2)*i + SCREEN_H/4);
 
        MenuePunkt->ZielSetzen(Speicherscreen);
        MenuePunkt->Anzeigen(true);
 
        MenuePunkte.push_back(MenuePunkt);
        MenuePunkt = NULL;
 
    }
    int k = 0;
    while(true){
        if(kbd::Taste_gedrueckt_char_menue("NACH-OBEN")){
            k--;
            if(k < 0){
                k = MenuePunkte.size() - 1;
            }
        }
 
        if(kbd::Taste_gedrueckt_char_menue("NACH-UNTEN")){
            k++;
            if(k >= MenuePunkte.size()){
                k = 0;
            }
        }
 
        if(kbd::Taste_gedrueckt_char_menue("EINGABE")){
            if(k == 0){
                    Game->NamenZuweisen(PlayerNames[0].c_str(), PlayerNames[1].c_str());
                    Game->StartGame(2);
                    kbd::tasten_leeren();
            }
            if(k == 1){
                    //MainGame->go();
                    kbd::tasten_leeren();
            }
            if(k == 2){
                    Optionen();
                    kbd::tasten_leeren();
            }
            if(k == 3){
                break;
            }
        }
        Pointer->PositionSetzen(MenuePunkte[k]->get_x() - 60, MenuePunkte[k]->get_y());
        MenueHintergrund->Anzeigen();
 
        for(i = 0;i<MenuePunkte.size();i++){
            MenuePunkte[i]->Anzeigen(true);
        }
        Pointer->Anzeigen(true);
 
        blit(Speicherscreen, screen, 0,0,0,0, Aufloesung.w, Aufloesung.h);
        _sleep(50);
    }
 
}
//-----------------------------------------------------------------------------------

... und seine Erklärung

Fangen wir mit dem ersten Teil an:

    kbd::tasten_leeren();
 
    std::vector<TFONT*> MenuePunkte;
    TFONT *MenuePunkt;
    std::string Caption[4];
    int i = 0;
 
    Caption[0] = "Spiel Starten PvP";
    Caption[1] = "Spiel Starten PvE";
    Caption[2] = "Optionen";
    Caption[3] = "Spiel Beenden";
 
    MenueHintergrund->Anzeigen();

Zuerst leeren wir den Keyboard-Buffer, damit nicht, falls z.B. bei dem Punkt „bitte drücken sie eine beliebige Taste um fortzufahren“ Enter gedrückt wurde, direkt im Menue der Punkt ausgewählt wird, wo der Zeiger steht. Danach werden ein paar Variablen erstellt, deren Nutzen ihr unten sehen werdet. Caption enthält genau die Texte die im Menue angezeigt werden. Letzten Endes wird dann nochmal der Bildschirm Orange übermalt.

    for(i = 0;i<4;i++){
        MenuePunkt = new TFONT();
        MenuePunkt->TextZuweisen(Caption[i].c_str());
        MenuePunkt->PositionSetzen((SCREEN_W - (Caption[i].length()*50))/2,
                              (((SCREEN_H / 4)-50)/2)*i + SCREEN_H/4);
 
        MenuePunkt->ZielSetzen(Speicherscreen);
        MenuePunkt->Anzeigen(true);
 
        MenuePunkte.push_back(MenuePunkt);
        MenuePunkt = NULL;
 
    }

Hier werden die 4 Menuepunkte dann auf den Bildschirm gebracht. Es wird immer zuerst der Schriftzug für den Entsprechenden Text erzeugt, dann wird seine Position ausgerechnet, der X-Wert ist ziemlich schnell erklärt, man nimmt die Bildschirmmitte und zieht davon die Hälfte der Länge des Textes ab, und danach hat man ihn genau Zentriert. Der Y-Wert ist etwas komplizierter. Der Gedanke ist, dass bei 4 Punkten jedem Punkt ein Viertel des Bildschrims zusteht, allerdings sähe das doof aus, deshalb rücken die näher zusammen, und lassen das obere und das untere viertel frei. Also erst ein Viertel der höhe, dann minus 50 und durch 2, damit es genau in der Mitte dieses Viertels ist, und dann mal seiner Position, das + ein Viertel der Höhe sorgt dafür, dass das obere Viertel frei bleibt.

 int k = 0;
    while(true){
        if(kbd::Taste_gedrueckt_char_menue("NACH-OBEN")){
            k--;
            if(k < 0){
                k = MenuePunkte.size() - 1;
            }
        }
 
        if(kbd::Taste_gedrueckt_char_menue("NACH-UNTEN")){
            k++;
            if(k >= MenuePunkte.size()){
                k = 0;
            }
        }
 
        if(kbd::Taste_gedrueckt_char_menue("EINGABE")){
            if(k == 0){
                    Game->NamenZuweisen(PlayerNames[0].c_str(), PlayerNames[1].c_str());
                    Game->StartGame(2);
                    kbd::tasten_leeren();
            }
            if(k == 1){
                    //MainGame->go();
                    kbd::tasten_leeren();
            }
            if(k == 2){
                    Optionen();
                    kbd::tasten_leeren();
            }
            if(k == 3){
                break;
            }
        }
        Pointer->PositionSetzen(MenuePunkte[k]->get_x() - 60, MenuePunkte[k]->get_y());
        MenueHintergrund->Anzeigen();
 
        for(i = 0;i<MenuePunkte.size();i++){
            MenuePunkte[i]->Anzeigen(true);
        }
        Pointer->Anzeigen(true);
 
        blit(Speicherscreen, screen, 0,0,0,0, Aufloesung.w, Aufloesung.h);
        _sleep(50);
    }

kommen wir jetzt zu dem wirklich Wichtigen. Der Endlosschleife. Eine solche wird es auch später im eigentlichen Spiel geben, hier verrechnet der Computer die Interaktionen, und errechnet die Folgen. Ntürlich wird auch die Anzeige hier gemacht. In diesem Fall bedeutet das, dass der Zeiger verschoben wird, und bei Druck auf Eingabe wird die Entsprechende Aktion ausgeführt. k ist der Index, der anzeigt, auf welchem Menuepunkt der Zeiger gerade steht. Dementsprechend wird, wenn NACH-OBEN oder NACH-UNTEN gedrückt wird. Der Index erhöht oder veringert, wenn er dann oben oder unten anstößt, wird er auf die andere Seite gesetzt.

Wird ENTER gedrückt, wird je nachdem, wo der Zeiger gerade steht, was wir ja dank k wissen, die eingestellte Aktion ausgeführt, also das Spiel gestartet, oder ein Entsprechendes Untermenue aufgerufen. Dem Spiel werden dann die Namen übergeben, weil es sie auch anzeigen soll. Und die 2 in der Klammer beim Starten bedeutet, es sind 2 Spieler, ne 1 würde die KI starten, die ich leider erst noch selbst schreiben muss, bevor ich dieses Tutorial fertigstellen kann. Anschließend wird die Postion des Zeigers berechnet, und danach wird alles angezeigt.

Zurück Weiter zu Das Spielfeld