Der Game Konstruktor

Wie ihr bereits am Aufbau gesehen habt, ist der Konstruktor der Game-klasse unsere On-Init() Methode, wenn man so möchte. Es geht jetzt also langsam ans eingemachte.

4Gewinnt.h

Nur damit wir den Konstruktor schreiben können, müssen wir ihn erst mal definieren. Ich gebe euch an dieser Stelle den vollständigen Header, sonst vergesse ich ziemlich sicher, das immer zu aktualisieren. Die Implementierung werden wir dann trotzdem erst Schritt für schritt machen.

#ifndef __4GEWINNT__
#define __4GEWINNT__
 
#include <AllegroW/Allegro.hpp>
#include <vector>
 
#define PLAYER1 0
#define PLAYER2 1
#define UNENTSCHIEDEN 2
 
struct Platz{
    bool Belegt;
    int Player;
};
 
 
class MainGame{
    private:
        allg::TGRAPHIKOBJEKT *Steine[2];
        allg::TGRAPHIKOBJEKT *Pointer;
        allg::TGRAPHIKOBJEKT *FeldPic;
        allg::TGRAPHIKOBJEKT *GameHintergrund;
        allg::TGRAPHIKOBJEKT *MenueHintergrund;
        allg::TFONT *Player[2];
        allg::TFONT *Sieg;
        BITMAP *Ziel;
        //BITMAP *FeldPicTemp;
 
        bool beenden;
 
        Platz Feld[7][6];
        int PlayersTurn;
        int Gewinner;
 
    protected:
        void zugSetzen(int Spalte);
        void GewinnerErmitteln(int, int);
        void SiegerAusgeben();
        void reset();
 
    public:
        MainGame();
        ~MainGame();
 
        void StartGame(int Players = 1);
        void NamenZuweisen(const char* Player1, const char* Player2);
        void Menue();
 
};
 
class VierGewinnt {
    public:
        VierGewinnt();
        ~VierGewinnt();
        void MainMenue();
 
    protected:
        void getPlayerName(int);
        void Optionen();
 
    private:
        BITMAP *Speicherscreen;
        allg::TGRAPHIKOBJEKT *MenueHintergrund;
        allg::TGRAPHIKOBJEKT *Pointer;
        MainGame *Game;
 
        std::string PlayerNames[2];
 
        struct SOLUTION{
            int w;
            int h;
        }Aufloesung;
 
};
 
#endif

Wie ihr seht haben wir hier 2 Klassen. Die VierGewinnt klasse ist die Kapsel, das drumherum, das auch das Menue und solche Sachen einschließt, wohingegen das MainGame wirklich nur das Spiel an sich ist, das dann von der VierGewinnt klasse Genutzt wird. Das Struct platz steht für den Platz, wo ein Spielstein sein kann, und ein daraus entstehendes Array, dient uns dann als Spielfeld für unser 4-Gewinnt.

Die Implementierung der Konstruktors

Kommen wir jetzt also endlich zur Sache. Wir haben eine Main-Funktion, die Unsere Klasse aufruft, und beendet, und wir haben die Definition eines vollständigen 4-Gewinnt Spiels. Falls euer Linker rum meckert, dass ihr Definitionen ohne Implementierung habt, dann müsst ihr leider entweder, eine Leere Methode für jede Methoden-Definition anlegen, oder ihr kommentiert es vorläufig noch in den Headern aus, und nehmt es wieder rein, wenn es gebraucht wird.

Also hier der Konstruktor:

#include "4Gewinnt.h"
#include <AllegroW/Allegro.hpp>
#include <vector>
#include <sstream>
#include <fstream>
 
using namespace allg;
using namespace std;
 
 
VierGewinnt::VierGewinnt(){
    Aufloesung.w = 1024;
    Aufloesung.h = 768;
 
    //initialisieren Des Bildschims, der Tastatur und des Sounds
    initialisieren(Aufloesung.w, Aufloesung.h);
 
    //initialisieren des Bildschirmbuffers auf den erst gezeichnet wird, und
    //der dann auf den Bildschirm gemalt wird um Flimmern zu vermeiden
    Speicherscreen = create_bitmap(Aufloesung.w, Aufloesung.h);
 
 
    MenueHintergrund = new TGRAPHIKOBJEKT(create_bitmap(Aufloesung.w, Aufloesung.h));
    MenueHintergrund->Einfaerben(255, 128, 64);
    MenueHintergrund->ZielSetzen(Speicherscreen);
    MenueHintergrund->Anzeigen();
 
 
    TFONT Text ;
    Text.ZielSetzen(Speicherscreen);
    Text.TextZuweisen("4 Gewinnt Loading");
    Text.PositionSetzen((SCREEN_W - 17*50)/2, (SCREEN_H - 50)/2);
 
    Text.Anzeigen(true);
    blit(Speicherscreen, screen, 0,0,0,0, Aufloesung.w, Aufloesung.h);
 
 
 
 
    Pointer = new TGRAPHIKOBJEKT(".\\Resources\\pointer.bmp");
    Pointer->ZielSetzen(Speicherscreen);
 
    LOCK_FUNCTION(kbd::keypress_handler_no_key_up);
    keyboard_lowlevel_callback = kbd::keypress_handler_no_key_up;
 
    Game = new MainGame();
 
    std::ifstream fin(".\\options.txt");
    for(int i = 0;i<2;i++){
        getline(fin, PlayerNames[i]);
    }
    fin.close();
 
    textout_centre_ex(screen, font, "Bitte eine beliebige Taste druecken", SCREEN_W/2, SCREEN_H - 100,
                 makecol(0, 0, 255), -1);
 
 
    while (!keypressed()) {
        _sleep(500);
         // wenn eine Taste gedrückt wird geht es weiter
    }
 
 
}

Bitte keine Kritik für doppeltes namespace using, ich versichere euch, es überschneidet sich nicht. Und ja, ich weiß, es ist schlechter Stil, aber ich will ja auch keinen Stilpreis gewinnen.

Fangen wir jetzt mit den Erklärungen an:

    MenueHintergrund = new TGRAPHIKOBJEKT(create_bitmap(Aufloesung.w, Aufloesung.h));
    MenueHintergrund->Einfaerben(255, 128, 64);
    MenueHintergrund->ZielSetzen(Speicherscreen);
    MenueHintergrund->Anzeigen();

Hier wird der Hintergrund geladen, wir wenden einfach nur unsere Klasse TGRAPHIKOBJEKT an.

    TFONT Text ;
    Text.ZielSetzen(Speicherscreen);
    Text.TextZuweisen("4 Gewinnt Loading");
    Text.PositionSetzen((SCREEN_W - 17*50)/2, (SCREEN_H - 50)/2);
 
    Text.Anzeigen(true);
    blit(Speicherscreen, screen, 0,0,0,0, Aufloesung.w, Aufloesung.h);

Hier zeigen wir nun den Text an, die Position ist genau Zentriert. Bildschirmmitte - halbe länge nach links, und halbe breite nach Oben. Danach wird noch die Anzeige gemacht. ALso den Speicherscreen auf den Monitor.

    Pointer = new TGRAPHIKOBJEKT(".\\Resources\\pointer.bmp");
    Pointer->ZielSetzen(Speicherscreen);
 
    LOCK_FUNCTION(kbd::keypress_handler_no_key_up);
    keyboard_lowlevel_callback = kbd::keypress_handler_no_key_up;

So wenn man ein Menue hat, mit verschiedenen Auswahlpunkten, dann braucht man auch irgendeine Möglichkeit anzuzeigen, welcher Menue-Punkt gerade angezeigt wird. Wir nehmen dafür einen Zeiger, der Sieht so aus:pointer.bmp Dieses Bild solltet ihr jetzt runterladen (rechtsklick aufs Bild→grafik speichern unter…) Das solltet ihr jetzt in einem Ordner namens Resourcen speichern. Der Ordner Resourcen sollte sich im Arbeitsverzeichnis des Spiels befinden.

Die unteren Beiden Zeilen sollten keiner Erklärung bedürfen.

    std::ifstream fin(".\\options.txt");
    for(int i = 0;i<2;i++){
        getline(fin, PlayerNames[i]);
    }
    fin.close();

Hier wird ein file options.txt ausgelesen, den ihr jetzt im Arbeitsverzeichnis erstellen solltet. Das File sollte in den ersten beiden Zeilen die Namen der Spieler enthalten.

    textout_centre_ex(screen, font, "Bitte eine beliebige Taste druecken", SCREEN_W/2, SCREEN_H - 100,
                 makecol(0, 0, 255), -1);
 
 
    while (!keypressed()) {
        _sleep(500);
         // wenn eine Taste gedrückt wird geht es weiter
    }

So nachdem jetzt alles erledigt ist, geben wir die Meldung aus, dass alles erledigt ist, und warten darauf, dass eine Taste gedrückt wird.

Soweit zum Konstruktor

Der Destruktor

Ich packe den Jetzt noch hierzu, da er unmittelbar zum Konstruktor gehört, hier wird nur alles wieder zerstört, was im Konstruktor erstellt wurde:

//------------------------------------------------------------------------------------
VierGewinnt::~VierGewinnt(){
    delete Game;
    delete MenueHintergrund;
    delete Pointer;
    destroy_bitmap(Speicherscreen);
}
//------------------------------------------------------------------------------------

hier gehts zurück und hier gehts dann weiter