Tic-Tac-Toe - Grundgerüst und Raster

Das Spielfeld

Unser Ziel für diesen Schritt ist es ein Fenster zu öffnen und darin das Spielfeld mit Hilfe von Linien bzw. eigentlich Rechtecken zu zeichnen. Am Ende sollte es in etwa wie auf dem Bild links ausschauen.

Fenster erstellen

Zuerst müssen wir wie bereits gelernt die entsprechende Header einbinden.

#include <iostream>
#include <SDL.h>


Als nächstes definieren wir ein paar Konstanten für die Größe des Spielfeldes, die Dicke der Linien und die Größe der Gewinnmarkierungen. Wir könnten zwar natürlich auch direkt mit den entsprechenden Werten arbeiten, aber zur besseren Lesbarkeit und Wartbarkeit des Codes ist das Auslagern von konstanten Werte in Konstanten oft vorteilhaft.

const size_t SIZE = 400;
const size_t LINE_WIDTH = 5;
const size_t MARKER_SIZE = 50;


Anschließend kommen wir zur main-Funktion in der wir zuerst einmal wie bereits bekannt die SDL initialisieren und ein Fenster erstellen

int main( int argc, char **argv )
{
  if( SDL_Init(SDL_INIT_VIDEO) )
  {
    // Irgendwas ist schiefgegangen. SDL_GetError weiß mehr
    std::cerr << "Konnte SDL nicht initialisieren: "
              << SDL_GetError() << std::endl;
    return 1;
  }
 
  // SDL_Quit registrieren
  atexit(&SDL_Quit);
 
  // Den Fenstertitel setzten (Der 2. Parameter wird auf
  // den meisten Plattformen ignoriert)
  SDL_WM_SetCaption("proggen.org - SDL Tic-Tac-Toe", "Tic-Tac-Toe");
 
  // Ein Fenster erstellen
  SDL_Surface *screen = SDL_SetVideoMode( SIZE, SIZE, 32, SDL_DOUBLEBUF );
 
  if( !screen )
  {
    std::cerr << "Konnte Videomodus nicht setzen: "
              << SDL_GetError() << std::endl;
    return 1;
  }


Hintergrund

Das frisch erhaltenen Fenster können wir jetzt mit Hilfe von SDL_FillRect schön bunt einfärben. Dabei erhalten wir durch einen Aufruf von SDL_MapRGB ein Farbe mit den RGB Farbanteilen (200,255,128) in das Farbformat des Bildschirms konvertiert (zb. wird die Farbtiefe berücksichtig)

  // Hintergrund einfärben
  SDL_FillRect
  (
    screen,
    NULL,
    SDL_MapRGB(screen->format, 200, 255, 128)
  );


Raster

Auf den eingefärbten Hintergrund zeichnen wir im nächsten Schritt das Raster, bestehend aus lauter Rechtecken. Dabei zeichnen wir zuerst zwei senkrechte und anschließend noch zwei waagrechte Rechtecke, um somit 3×3 Felder zu erhalten

  // Das Gitter zeichnen
  const Uint32 line_color = SDL_MapRGB(screen->format, 20, 10, 0);
 
  // Senkrechte Linien zeichnen
  for(size_t x = 1; x <= 2; ++x)
  {
    SDL_Rect line =
    {
      static_cast<Sint16>(x * SIZE/3. - LINE_WIDTH/2. + 0.5),
      0,
      LINE_WIDTH,
      SIZE
    };
    SDL_FillRect(screen, &line, line_color);
  }
 
  // Waagrechte Linien zeichnen
  for(size_t y = 1; y <= 2; ++y)
  {
    SDL_Rect line =
    {
      0,
      static_cast<Sint16>(y * SIZE/3. - LINE_WIDTH/2. + 0.5),
      SIZE,
      LINE_WIDTH
    };
    SDL_FillRect(screen, &line, line_color);
  }


Bis jetzt haben wir noch alles in einen Zwischenspeicher gezeichnet (engl. Backpuffer) den wir jetzt mit einem Aufruf von SDL_Flip auf den Bildschirm kopieren lassen

  // Den Bildschirm anzeigen
  SDL_Flip(screen);


Jetzt brauchen wir nur noch die Nachrichtenschleife in der wir solange bleiben bis der Benutzer das Spiel über einen Klick auf das 'x' des Fensters beendet

  bool running = true;
  SDL_Event event;
 
  // Events abarbeiten
  while( running && SDL_WaitEvent(&event) )
  {
    switch( event.type )
    {
      // Programm sollte beendet werden ('x' im Fenster wurde geklickt)
      case SDL_QUIT:
        running = false;
        break;
    }
  }
 
  return 0;
}


Damit haben wir unser Ziel erreicht und können gleich den nächsten Schritt, nämlich dem Laden und Anzeigen von Bildern als Spielsteine, angehen.


Tic-Tac-Toe mit der SDL ↑ | → Bilder als Spielsteine