From 710d3e2509751676d81743c30b40c4a6a09b34d3 Mon Sep 17 00:00:00 2001 From: "Martin Felis (berta)" Date: Sun, 2 May 2010 22:39:49 +0200 Subject: [PATCH] improved font handling and HUD --- asteroids/MenuOverlay.cc | 23 +++++++-- asteroids/MenuOverlay.h | 3 ++ asteroids/Model.cc | 12 +++-- asteroids/Model.h | 3 ++ asteroids/View.cc | 1 + data/fonts/AldotheApache.ttf | Bin 0 -> 17092 bytes data/fonts/fonts.txt | 3 ++ engine/SimpleConsoleOverlay.cc | 2 + engine/ViewBase.cc | 88 +++++++++++++++++++++++++++------ engine/ViewBase.h | 20 +++++++- engine/ViewBaseGlobal.h | 1 + 11 files changed, 132 insertions(+), 24 deletions(-) create mode 100644 data/fonts/AldotheApache.ttf create mode 100644 data/fonts/fonts.txt diff --git a/asteroids/MenuOverlay.cc b/asteroids/MenuOverlay.cc index 8a0fd66..2961b44 100644 --- a/asteroids/MenuOverlay.cc +++ b/asteroids/MenuOverlay.cc @@ -8,6 +8,7 @@ #include "OverlayBase.h" #include "MenuOverlay.h" #include "Model.h" +#include "View.h" #include "Sprite.h" #include "ShipEntity.h" @@ -24,6 +25,11 @@ void MenuOverlay::Init () { if (!mShipSprite.LoadFromPNG("./data/textures/ship.png")) Engine::LogError ("Could not load ship sprite!"); + // setup of the HUD font + mView->LoadFont ("AldotheApache.ttf", 20); + mView->SelectFont ("AldotheApache.ttf"); + mView->SetFontJustification (Engine::FontJustificationRight); + assert (mShipSprite.GetWidth() > 1); mShipSprite.SetScale (0.1); } @@ -110,6 +116,8 @@ void MenuOverlay::Draw () { glPushMatrix (); glLoadIdentity (); + mView->SelectFont("console.ttf"); + // then we do the drawings if (mModel->GetGameState() == GameStateRunning) { glClearColor (0., 0., 0., 1.); @@ -137,10 +145,17 @@ void MenuOverlay::DrawGameRunning() { right = static_cast (Engine::GetWindowWidth()); bottom = static_cast (Engine::GetWindowHeight()); - int i; - for (i = 0; i < mModel->GetPlayerLives(); i++) { - mShipSprite.DrawAt2D (right - 32 - i*20, bottom - 16); - } + mView->SelectFont ("AldotheApache.ttf"); + + std::ostringstream out_stream; + out_stream << mModel->GetPlayerLives() << " x "; + mView->DrawGLString (right - 64, bottom - 20, out_stream.str().c_str()); + + mShipSprite.DrawAt2D (right - 32 - 10, bottom - 16); + + out_stream.str(""); + out_stream << mModel->GetPoints(); + mView->DrawGLString (right - 10, 40, out_stream.str().c_str()); } void MenuOverlay::DrawPlayerDied () { diff --git a/asteroids/MenuOverlay.h b/asteroids/MenuOverlay.h index 2f4cd27..e6f0bb4 100644 --- a/asteroids/MenuOverlay.h +++ b/asteroids/MenuOverlay.h @@ -11,6 +11,7 @@ class OverlayBase; namespace asteroids { class Model; +class View; class MenuOverlay : public Engine::OverlayBase { public: @@ -30,9 +31,11 @@ class MenuOverlay : public Engine::OverlayBase { void DrawPlayerDied (); void SetModel (Model *model) { mModel = model; }; + void SetView (View *view) { mView = view; }; private: Model *mModel; + View *mView; Engine::Sprite mShipSprite; }; diff --git a/asteroids/Model.cc b/asteroids/Model.cc index 141c5fb..95fa5df 100644 --- a/asteroids/Model.cc +++ b/asteroids/Model.cc @@ -9,6 +9,7 @@ #include "EntityFactory.h" #include "AsteroidsEvents.h" +#include "AsteroidEntity.h" #include @@ -56,6 +57,7 @@ void Model::Process () { if (mLastGameState == GameStateMainMenu && mGameState == GameStateRunning) { mPlayerLives = 3; mCurrentLevelIndex = 0; + mPoints = 0; DoLoadLevel (mLevelList[mCurrentLevelIndex].c_str()); } else if (mLastGameState == GameStateRunning && mGameState == GameStatePlayerDied) { @@ -75,8 +77,7 @@ void Model::Process () { } } else if (mLastGameState == GameStatePlayerDied && mGameState == GameStateRunning) - // DoLoadLevel (mLevelPath); - assert (0); + DoLoadLevel(mLevelList[mCurrentLevelIndex].c_str()); else if (mLastGameState == GameStateRunning && mGameState == GameStateGameOver) ClearEntities(); @@ -105,13 +106,14 @@ unsigned int Model::InitLevelList () { Engine::LogError ("Could not init level list: %s is not a directory!"); } - boost::filesystem::directory_iterator end_iter; for (boost::filesystem::directory_iterator dir_iter(level_dir); dir_iter != end_iter; ++dir_iter) { if (boost::filesystem::is_regular_file (dir_iter->status())) { - mLevelList.push_back (std::string(level_dir_name) + dir_iter->path().filename()); + std::string level_relative_path (level_dir_name); + level_relative_path += dir_iter->path().filename(); + mLevelList.push_back (level_relative_path); Engine::LogDebug ("Found level %s", mLevelList[mLevelList.size()-1].c_str()); } } @@ -248,6 +250,8 @@ void Model::OnKillEntity (const Engine::EntityBase *entity) { if (entity_type == GameEntityTypeAsteroid) { unsigned int i; + const AsteroidEntity *asteroid = static_cast(entity); + mPoints += 150 + asteroid->mSubAsteroidsCount * 75; for (i = 0; i < mAsteroids.size(); i++) { if (mAsteroids.at(i) == entity->mId) { diff --git a/asteroids/Model.h b/asteroids/Model.h index f916ce9..ac790f3 100644 --- a/asteroids/Model.h +++ b/asteroids/Model.h @@ -21,6 +21,7 @@ class Model : public Engine::ModelBase { GameState GetGameState () { return mGameState; }; int GetPlayerLives () { return mPlayerLives; }; + unsigned int GetPoints () { return mPoints; }; float GetWorldWidth (); float GetWorldHeight (); @@ -31,6 +32,7 @@ class Model : public Engine::ModelBase { virtual void OnDestroy() { Engine::ModelBase::OnDestroy(); mAsteroids.clear(); + mLevelList.clear(); delete mLevelCompleteEventHandler; }; virtual void OnRegisterCommands (); @@ -48,6 +50,7 @@ class Model : public Engine::ModelBase { GameState mLastGameState; int mPlayerLives; + unsigned int mPoints; std::vector mLevelList; unsigned int mCurrentLevelIndex; diff --git a/asteroids/View.cc b/asteroids/View.cc index e8c8974..3abc3d3 100644 --- a/asteroids/View.cc +++ b/asteroids/View.cc @@ -32,6 +32,7 @@ int View::OnInit (int argc, char* argv[]) { // We want menu mMenuOverlay = boost::shared_ptr (new MenuOverlay); mMenuOverlay->SetModel ((Model*) mModel); + mMenuOverlay->SetView (this); mMenuOverlay->Init(); AddOverlay (mMenuOverlay); diff --git a/data/fonts/AldotheApache.ttf b/data/fonts/AldotheApache.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4328d879ca68e6d9bf4f1d4ae5243d2bf1e9ff82 GIT binary patch literal 17092 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 ) { - LogError ("Could not load font %s!", "./data/fonts/console.ttf"); - exit (-1); - } + + LoadFont ("console.ttf"); + mCurrentFont = mFonts["console.ttf"]; + SetFontColor (1., 1., 1.); OverlayBasePtr console_overlay(new SimpleConsoleOverlay); AddOverlay (console_overlay); - mConsoleFont->setForegroundColor (1., 1., 1.); - mDrawAxis = false; mDrawGrid = false; @@ -77,13 +72,16 @@ int ViewBase::OnInit (int argc, char* argv[]) { } void ViewBase::OnDestroy () { - if (mConsoleFont ) - delete mConsoleFont; - mConsoleFont = NULL; - while (mOverlays.size() > 0) mOverlays.pop_back(); + std::map::iterator iter; + + for (iter = mFonts.begin(); iter != mFonts.end(); ++iter) { + delete iter->second; + } + mFonts.clear(); + ViewInstance = NULL; LogDebug ("View Destroy"); @@ -189,9 +187,63 @@ void ViewBase::Draw () { SDL_GL_SwapBuffers (); } +/* Fonts */ +bool ViewBase::LoadFont (const char *font_name, float point_size) { + std::string font_path ("./data/fonts/"); + font_path += font_name; + + LogDebug ("Loading font %s size %f from %s", font_name, point_size, font_path.c_str()); + + OGLFT::Monochrome *font = new OGLFT::Monochrome (font_path.c_str(), point_size); + if ( font == 0 || !font->isValid() ) { + LogError ("Could not load font %s!", font_path.c_str()); + } + font->setForegroundColor(1., 1., 1.); + + mFonts.insert(std::make_pair(font_name, font)); +} + +void ViewBase::SelectFont (const char *font) { + std::map::iterator font_iter; + + font_iter = mFonts.find(font); + + if (font_iter != mFonts.end()) { + mCurrentFont = font_iter->second; + return; + } + + LogDebug ("Font %s not found, trying to load it", font); + if (LoadFont (font)) { + font_iter = mFonts.find(font); + + assert (mFonts.find(font) != mFonts.end()); + + mCurrentFont = font_iter->second; + + return; + } + + LogError("Error trying to load font %s", font); +} + +void ViewBase::SetFontJustification (FontJustification justification) { + if (justification == FontJustificationRight) + mCurrentFont->setHorizontalJustification(OGLFT::Face::RIGHT); + else if (justification == FontJustificationCenter) + mCurrentFont->setHorizontalJustification(OGLFT::Face::CENTER); + else mCurrentFont->setHorizontalJustification(OGLFT::Face::LEFT); + +} + +void ViewBase::SetFontColor (float r, float g, float b) { + assert (mCurrentFont); + mCurrentFont->setForegroundColor(r, g, b); +}; + void ViewBase::DrawGLString (float x, float y, const char* str) { glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - mConsoleFont->draw (x, y, str); + mCurrentFont->draw (x, y, str); } void ViewBase::GetCamereEye (float *eye_out) { @@ -310,6 +362,14 @@ void DrawGLString (float x, float y, const char* str) { ViewInstance->DrawGLString (x, y, str); } +void SelectFont (const char* font) { + if (!ViewInstance) { + LogError ("Cannot select font: View not yet initialized!"); + return; + } + ViewInstance->SelectFont(font); +} + unsigned int GetWindowWidth() { return ViewInstance->GetWindowWidth (); } diff --git a/engine/ViewBase.h b/engine/ViewBase.h index b62083f..c81d4a8 100644 --- a/engine/ViewBase.h +++ b/engine/ViewBase.h @@ -11,6 +11,12 @@ namespace OGLFT { namespace Engine { +enum FontJustification { + FontJustificationRight = 0, + FontJustificationCenter, + FontJustificationLeft +}; + class Module; class ModelBase; class CameraBase; @@ -20,6 +26,7 @@ class CameraBase; class ViewBase : public Module{ public: + ViewBase() : mModel(NULL), mCamera(NULL), mCurrentFont(NULL) {} virtual ~ViewBase() {}; /** \brief Resizes the View */ @@ -28,9 +35,15 @@ class ViewBase : public Module{ /** \brief Performs all drawing */ virtual void Draw (); + /* Fonts */ + bool LoadFont (const char *font_name, float point_size=12); + void SelectFont (const char *font_name); + void SetFontJustification (FontJustification justification); + void SetFontColor (float r, float g, float b); /** \brief Draws a string at the given position using current projection * and modelview matrices */ void DrawGLString (float x, float y, const char* str); + /** \brief Stores the eye poisition in eye_out */ void GetCamereEye (float *eye_out); @@ -87,8 +100,11 @@ class ViewBase : public Module{ int mGridSizeX; int mGridSizeZ; - /** \brief Font that is used in the console */ - OGLFT::Monochrome* mConsoleFont; + /** \brief The font that is currently used */ + OGLFT::Monochrome* mCurrentFont; + + /** \brief Contains all the fonts that are to be used */ + std::map mFonts; friend class Engine; }; diff --git a/engine/ViewBaseGlobal.h b/engine/ViewBaseGlobal.h index 6bc5295..b91af06 100644 --- a/engine/ViewBaseGlobal.h +++ b/engine/ViewBaseGlobal.h @@ -6,6 +6,7 @@ namespace Engine { /** \brief Draws the given string at the given position using the current * OpenGL transformations */ void DrawGLString (float x, float y, const char* str); +void SelectFont (const char* font); unsigned int GetWindowWidth(); unsigned int GetWindowHeight();