highscore now working

- added ControllerBase::EnableTextinput() for setting up unicode and key repetitions
- added new state GameStateEnterPlayerName
main
Martin Felis (berta) 2010-07-15 22:47:17 +02:00
parent 38096a4502
commit 91cdebd33a
11 changed files with 150 additions and 28 deletions

View File

@ -27,6 +27,7 @@ BEGIN_ENUM(GameState)
DECL_ENUM_ELEMENT(GameStatePlayerDied),
DECL_ENUM_ELEMENT(GameStateLevelComplete),
DECL_ENUM_ELEMENT(GameStateShowHighscore),
DECL_ENUM_ELEMENT(GameStateEnterPlayername),
DECL_ENUM_ELEMENT(GameStateGameOver)
}
END_ENUM(GameState)

View File

@ -80,7 +80,8 @@ void Model::Process () {
// some action.
Engine::LogDebug ("Switching from %s->%s", GetStringGameState(mLastGameState), GetStringGameState(mGameState));
if (mLastGameState == GameStateMainMenu && mGameState == GameStateRunning) {
if ( (mLastGameState == GameStateMainMenu && mGameState == GameStateRunning)
|| (mLastGameState == GameStateEnterPlayername && mGameState == GameStateRunning)){
OnNewGame();
}
else if (mLastGameState == GameStateRunning && mGameState == GameStatePlayerDied) {
@ -92,13 +93,14 @@ void Model::Process () {
Engine::EventBasePtr gameover_event (new Engine::EventBase());
gameover_event->mEventType = EventGameOver;
QueueEvent (gameover_event);
//mGameState = GameStateGameOver;
}
}
else if (mLastGameState == GameStateLevelComplete && mGameState == GameStateRunning) {
mCurrentLevelIndex++;
if (mCurrentLevelIndex == mLevelList.size()) {
SetGameState(GameStateGameOver);
Engine::EventBasePtr gameover_event (new Engine::EventBase());
gameover_event->mEventType = EventGameOver;
QueueEvent (gameover_event);
} else {
DoLoadLevel(mLevelList[mCurrentLevelIndex].c_str());
}
@ -345,8 +347,10 @@ int Model::DoSaveLevel (const char* filename) {
bool Model::OnLevelComplete() {
Engine::LogMessage ("Level complete!");
if (mCurrentLevelIndex + 1== mLevelList.size()) {
SetGameState(GameStateGameOver);
if (mCurrentLevelIndex + 1 == mLevelList.size()) {
Engine::EventBasePtr gameover_event (new Engine::EventBase());
gameover_event->mEventType = EventGameOver;
QueueEvent (gameover_event);
} else {
SetGameState (GameStateLevelComplete);
}
@ -355,7 +359,7 @@ bool Model::OnLevelComplete() {
}
bool Model::OnGameOver() {
Engine::LogMessage ("Points = %d lowest = %d", mPoints,mHighscoreList.back().points );
Engine::LogMessage ("Points = %d lowest = %d", mPoints, mHighscoreList.back().points );
if (mPoints > mHighscoreList.back().points) {
Engine::LogMessage ("New Highscore!");
AddHighscoreEntry (mPlayerName, mPoints);

View File

@ -9,6 +9,7 @@
#include "UserInterface.h"
#include "Model.h"
#include "View.h"
#include "Controller.h"
#include "Sprite.h"
#include "ShipEntity.h"
@ -35,7 +36,7 @@ bool MainMenuOverlay::OnKeyDown (const SDL_keysym &keysym) {
Engine::RunCommand ("quit");
return true;
case SDLK_RETURN:
GetModel()->SetGameState(GameStateRunning);
GetModel()->SetGameState(GameStateEnterPlayername);
return true;
case SDLK_h:
GetModel()->SetGameState(GameStateShowHighscore);
@ -73,7 +74,8 @@ void MainMenuOverlay::Draw () {
Engine::DrawGLString ( right * 0.5 - 100, bottom * 0.5 - 8 - 64, "A s t e r o i d s");
Engine::DrawGLString ( right * 0.5 - 100, bottom * 0.5 - 8 - 32, "Main Menu");
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8 - 16, "[Return] - Start Game");
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8, "[Escape] - Quit");
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8, "[h] - Show Highscore");
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 + 8, "[Escape] - Quit");
glPopMatrix ();
@ -174,10 +176,10 @@ void GameOverOverlay::Init () {
bool GameOverOverlay::OnKeyDown (const SDL_keysym &keysym) {
switch (keysym.sym) {
case SDLK_ESCAPE:
GetModel()->SetGameState(GameStateMainMenu);
GetModel()->SetGameState(GameStateShowHighscore);
break;
case SDLK_RETURN:
GetModel()->SetGameState(GameStateMainMenu);
GetModel()->SetGameState(GameStateShowHighscore);
break;
default:
break;
@ -424,15 +426,6 @@ bool HighscoreOverlay::OnKeyDown (const SDL_keysym &keysym) {
switch (keysym.sym) {
case SDLK_ESCAPE:
case SDLK_RETURN:
// If we just entered a new entry we simply show the highscore table,
// otherwise we switch back to the main menu
if (GetModel()->mNewestHighscoreEntryIndex < GetModel()->mHighscoreList.size()) {
GetModel()->mNewestHighscoreEntryIndex = GetModel()->mHighscoreList.size();
SDL_EnableUNICODE(-1);
SDL_EnableKeyRepeat(0,100);
return true;
}
GetModel()->SetGameState(GameStateMainMenu);
return true;
@ -443,7 +436,7 @@ bool HighscoreOverlay::OnKeyDown (const SDL_keysym &keysym) {
}
void HighscoreOverlay::Draw () {
glClearColor (0., 0., 0., 1.);
glClearColor (0.1, 0.1, 0.1, 1.);
right = static_cast<float> (Engine::GetWindowWidth());
bottom = static_cast<float> (Engine::GetWindowHeight());
@ -531,4 +524,95 @@ void HighscoreOverlay::Draw () {
};
/**********************
*
* EnterPlayername
*
**********************/
void EnterPlayernameOverlay::Init () {
mPlayerNameInput = "Starkiller";
}
bool EnterPlayernameOverlay::OnKeyDown (const SDL_keysym &keysym) {
GetController()->EnableTextinput(true);
switch (keysym.sym) {
case SDLK_ESCAPE:
GetModel()->SetGameState(GameStateMainMenu);
return true;
case SDLK_BACKSPACE:
if (mPlayerNameInput.size() > 0)
mPlayerNameInput = mPlayerNameInput.substr (0, mPlayerNameInput.size() - 1 );
return true;
break;
case SDLK_RETURN:
// If we just entered a new entry we simply show the highscore table,
// otherwise we switch back to the main menu
GetModel()->SetPlayerName(mPlayerNameInput);
GetController()->EnableTextinput(false);
GetModel()->SetGameState(GameStateRunning);
return true;
default:
break;
}
if (keysym.unicode) {
if ((keysym.unicode & 0xFF80) == 0) {
mPlayerNameInput += keysym.unicode & 0x7F;
return true;
} else {
Engine::LogWarning ("Input key not supported!");
return false;
}
}
return true;
}
void EnterPlayernameOverlay::Draw () {
glClearColor (0.1, 0.1, 0.1, 1.);
right = static_cast<float> (Engine::GetWindowWidth());
bottom = static_cast<float> (Engine::GetWindowHeight());
// we switch to orthographic projection and draw the contents of the 2d
// overlay on top of the previous drawings
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
// first we have to get the size of the current viewport to set up the
// orthographic projection correctly
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
gluOrtho2D (viewport[0], viewport[2], viewport[3], viewport[1]);
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glLoadIdentity ();
GetView()->SelectFont("console.ttf");
float x = right * 0.5 - 100;
float y = bottom * 0.5 - 8 - 128;
// then we do the drawings
Engine::DrawGLString ( x, y, "A s t e r o i d s");
y += 30;
Engine::DrawGLString ( x, y, "Enter your name: ");
std::string name_output (mPlayerNameInput);
name_output += "_";
Engine::DrawGLString ( x + 15*8, y, name_output.c_str());
Engine::DrawGLString ( x + 16, y + 16, "Press [Return] to continue.");
glPopMatrix ();
glMatrixMode (GL_PROJECTION);
glPopMatrix ();
glMatrixMode (GL_MODELVIEW);
};
}

View File

@ -7,6 +7,7 @@ class OverlayBase;
#include "OverlayBase.h"
#include "Sprite.h"
#include <string>
namespace asteroids {
@ -103,6 +104,21 @@ class HighscoreOverlay : public Engine::OverlayBase {
virtual void Draw ();
};
class EnterPlayernameOverlay : public Engine::OverlayBase {
public:
EnterPlayernameOverlay () {
};
virtual ~EnterPlayernameOverlay() {};
virtual void Init ();
virtual bool OnKeyDown (const SDL_keysym &keysym);
virtual void Draw ();
private:
std::string mPlayerNameInput;
};
}
#endif /* USERINTERFACE */

View File

@ -37,6 +37,7 @@ int View::OnInit (int argc, char* argv[]) {
Engine::OverlayBasePtr game_paused_overlay (new GamePausedOverlay);
Engine::OverlayBasePtr player_died_overlay (new PlayerDiedOverlay);
Engine::OverlayBasePtr highscore_overlay (new HighscoreOverlay);
Engine::OverlayBasePtr enterplayername_overlay (new EnterPlayernameOverlay);
mOverlayManager.Register (menu_overlay, GameStateMainMenu);
mOverlayManager.Register (game_running_overlay, GameStateRunning);
@ -45,6 +46,7 @@ int View::OnInit (int argc, char* argv[]) {
mOverlayManager.Register (player_died_overlay, GameStatePlayerDied);
mOverlayManager.Register (game_paused_overlay, GameStatePaused);
mOverlayManager.Register (highscore_overlay, GameStateShowHighscore);
mOverlayManager.Register (enterplayername_overlay, GameStateEnterPlayername);
mOverlayManager.InitOverlays();

View File

@ -130,6 +130,17 @@ void ControllerBase::ProcessEvents () {
}
}
/** \brief Activates or deactivates unicode processing and key delays of the keyboard inputs */
void ControllerBase::EnableTextinput (bool textinput_state) {
if (textinput_state) {
SDL_EnableUNICODE(1);
SDL_EnableKeyRepeat(500, 50);
} else {
SDL_EnableUNICODE(-1);
SDL_EnableKeyRepeat(0, 100);
}
}
/** \brief Keyboard processing */
bool ControllerBase::OnKeyDown (const SDL_keysym &keysym) {
if (mView->mOverlayManager.SendKeyDown (keysym))

View File

@ -44,6 +44,9 @@ class ControllerBase : public Module {
}
bool BindKey (int key, const char *command);
/** \brief Activates or deactivates unicode processing and key delays of the keyboard inputs */
void EnableTextinput (bool textinput_state);
protected:
/** \brief Initializes the system */
virtual int OnInit (int argc, char* argv[]);

View File

@ -27,7 +27,7 @@
* have to know the number of bits that are to be reserved in advance so this
* is hard coded into the library for now.
*/
#define ENTITY_CONTROLLER_MAX_KEY_STATES 64
const int EntityControllerMaxKeyStates = 64;
namespace Engine {

View File

@ -5,20 +5,20 @@
namespace Engine {
bool EntityControllerState::GetKey (int state) {
assert (state < ENTITY_CONTROLLER_MAX_KEY_STATES && state >= 0);
assert (state < EntityControllerMaxKeyStates && state >= 0);
return mKeyState.test (state);
}
void EntityControllerState::SetKey (int state) {
assert (state < ENTITY_CONTROLLER_MAX_KEY_STATES && state >= 0);
assert (state < EntityControllerMaxKeyStates && state >= 0);
LogDebug ("Setting Entity Key State %d", state);
mKeyState.set (state);
}
void EntityControllerState::UnsetKey (int state) {
assert (state < ENTITY_CONTROLLER_MAX_KEY_STATES && state >= 0);
assert (state < EntityControllerMaxKeyStates && state >= 0);
LogDebug ("Unsetting Entity Key State %d", state);
mKeyState.reset (state);

View File

@ -100,7 +100,7 @@ struct EntityPhysicState {
* \todo [Low] The current design is very unflexible. Is there a better way?
*/
struct EntityControllerState {
std::bitset<ENTITY_CONTROLLER_MAX_KEY_STATES> mKeyState;
std::bitset<EntityControllerMaxKeyStates> mKeyState;
bool GetKey (int state);
void SetKey (int state);

View File

@ -1,6 +1,7 @@
#include "DrawingsGL.h"
#include "OverlayBase.h"
#include "SimpleConsoleOverlay.h"
#include "ControllerBase.h"
#include "OGLFT.h"
@ -16,10 +17,10 @@ bool SimpleConsoleOverlay::OnKeyDown (const SDL_keysym &keysym) {
if (mActive) {
// We have to call SetActive() to actually
// activate the unicode processing of SDL
SetActive (false);
EngineGetController()->EnableTextinput(false);
}
else {
SetActive (true);
EngineGetController()->EnableTextinput(true);
}
return true;
@ -31,7 +32,7 @@ bool SimpleConsoleOverlay::OnKeyDown (const SDL_keysym &keysym) {
// check for input that requires actions
switch (keysym.sym) {
case SDLK_ESCAPE:
SetActive (false);
EngineGetController()->EnableTextinput(false);
return true;
break;
case SDLK_BACKSPACE: