Teil 7: Tastaturabfrage

Hier siehst du unser neues Spielzeug, den Gleiter des Spielers:
TODO
Bevor wir dieses Ding steuern können, brauchen wir allerdings noch ein bischen Input von der Tastatur. Wenn wir uns die SDL Dokumentation mal anschauen, wird schnell klar, was für uns interessant ist. Wir fangen wie gehabt die SDL_KEYDOWN und zusätzlich die SDL_KEYUP Nachricht ab und speichern den Status jeder Taste in einem bool Array. Die Tastaturkonstanten stehen im SDL-Header SDL_keysym.h. Am Ende der Enumerierung bescheren sie uns sogar ein SDLK_LAST, womit klar ist, wie groß unser Array sein muß. Als Datenhaltungsklasse implementieren wir wieder ein kleines Singleton, das nichts weiter macht, als sich den Zustand einer Taste zu merken. Diesmal landen die folgenden zwei Dateien im Verzeichnis /core.
Datei /core/KeyboardManager.h

#ifndef KEYBOARDMANAGER_H
#define KEYBOARDMANAGER_H
#include <SDL.h>
// --------------------------------------------------------------------------------
class CKeyboardManager
{
public:
  static CKeyboardManager* GetInstance();
  static void DestroyInstance();
  void SetKeyDown( const int iKey );
  void SetKeyUp( const int iKey );
  bool KeyDown( const int iKey ) const;
private:
  CKeyboardManager();
  ~CKeyboardManager();
  static CKeyboardManager* m_pInstance;
  bool m_abDown[ SDLK_LAST ];
};
#define KEYBOARD CKeyboardManager::GetInstance()
#endif

Die Implementierung der Funktionen ist entsprechend trivial:
Datei /core/KeyboardManager.cpp

#include "KeyboardManager.h"
#include <memory.h>
// --------------------------------------------------------------------------------
CKeyboardManager* CKeyboardManager::m_pInstance = 0;
// --------------------------------------------------------------------------------
CKeyboardManager* CKeyboardManager::GetInstance()
{
  if( 0 == m_pInstance )
  {
     m_pInstance = new CKeyboardManager;
  }
  return m_pInstance;
}
// --------------------------------------------------------------------------------
void CKeyboardManager::DestroyInstance()
{
  if( m_pInstance )
  {
     delete m_pInstance;
     m_pInstance = 0;
  }
}
// --------------------------------------------------------------------------------
CKeyboardManager::CKeyboardManager()
{
  memset( m_abDown, 0, sizeof( bool ) * SDLK_LAST );
}
// --------------------------------------------------------------------------------
CKeyboardManager::~CKeyboardManager()
{
}
// --------------------------------------------------------------------------------
void CKeyboardManager::SetKeyDown( const int iKey )
{
  m_abDown[ iKey ] = true;
}
// --------------------------------------------------------------------------------
void CKeyboardManager::SetKeyUp( const int iKey )
{
  m_abDown[ iKey ] = false;
}
// --------------------------------------------------------------------------------
bool CKeyboardManager::KeyDown( const int iKey ) const
{
  return m_abDown[ iKey ];
}

Nun muß noch das Hauptprogramm erweitert werden, so daß die SDL_KEYDOWN und SDL_KEYUP Nachrichten abgefangen werden. Außerdem muß die Singleton-Instanz beim Programmende zerstört werden. Die Änderungen siehst Du hier:
Datei /Main.cpp

#include <core/KeyboardManager.h>
[...]
  SDL_Event event;
  while( !KEYBOARD->KeyDown( SDLK_ESCAPE ) )
  {
     if( SDL_PollEvent( &event ) )
     {
        if( event.type == SDL_KEYDOWN )
        {
           KEYBOARD->SetKeyDown( event.key.keysym.sym );
        }
        else if( event.type == SDL_KEYUP )
        {
           KEYBOARD->SetKeyUp( event.key.keysym.sym );
        }
     }
     SDL_FillRect( g_pBackSurface, 0, SDL_MapRGB( g_pBackSurface->format, 0, 0, 0 ) );
     GAMEMANAGER->BeginFrame();
     GAMEMANAGER->Idle();
     GAMEMANAGER->EndFrame();
     SDL_Flip( g_pBackSurface );
  }
  KEYBOARD->DestroyInstance();
  GAMEMANAGER->Uninitialize();
  GAMEMANAGER->DestroyInstance();

Das Zerstören der Instanz habe ich übrigens auch beim GameManager vergessen, das ist dann hiermit nachgeholt 😉 Zum Thema Memory Leaks werde ich später sicher auch nochmal was loswerden.
Im nächsten Teil werden wir die Tastatur dann auch mal direkt in den Einsatz bringen.

Leave a Reply

Your email address will not be published. Required fields are marked *