[Add] Initial work on a title screen.

This commit is contained in:
Tamir Atias 2012-04-19 08:14:35 +03:00
parent 3e20041111
commit ca10800c79
13 changed files with 451 additions and 40 deletions

View File

@ -100,6 +100,7 @@
<ClInclude Include="..\..\src\Level\MapTile.h" /> <ClInclude Include="..\..\src\Level\MapTile.h" />
<ClInclude Include="..\..\src\Level\Tileset.h" /> <ClInclude Include="..\..\src\Level\Tileset.h" />
<ClInclude Include="..\..\src\Main\Game.h" /> <ClInclude Include="..\..\src\Main\Game.h" />
<ClInclude Include="..\..\src\Main\TitleScreen.h" />
<ClInclude Include="..\..\src\Math\FPS.h" /> <ClInclude Include="..\..\src\Math\FPS.h" />
<ClInclude Include="..\..\src\Math\MathBox.h" /> <ClInclude Include="..\..\src\Math\MathBox.h" />
<ClInclude Include="..\..\src\Math\Rect.h" /> <ClInclude Include="..\..\src\Math\Rect.h" />
@ -128,6 +129,8 @@
<ClInclude Include="..\..\src\TMXParser\TmxTile.h" /> <ClInclude Include="..\..\src\TMXParser\TmxTile.h" />
<ClInclude Include="..\..\src\TMXParser\TmxTileset.h" /> <ClInclude Include="..\..\src\TMXParser\TmxTileset.h" />
<ClInclude Include="..\..\src\TMXParser\TmxUtil.h" /> <ClInclude Include="..\..\src\TMXParser\TmxUtil.h" />
<ClInclude Include="..\..\src\UI\Button.h" />
<ClInclude Include="..\..\src\UI\Menu.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\Actor\Actor.cpp" /> <ClCompile Include="..\..\src\Actor\Actor.cpp" />
@ -145,6 +148,7 @@
<ClCompile Include="..\..\src\Level\Tileset.cpp" /> <ClCompile Include="..\..\src\Level\Tileset.cpp" />
<ClCompile Include="..\..\src\Main\Game.cpp" /> <ClCompile Include="..\..\src\Main\Game.cpp" />
<ClCompile Include="..\..\src\Main\main.cpp" /> <ClCompile Include="..\..\src\Main\main.cpp" />
<ClCompile Include="..\..\src\Main\TitleScreen.cpp" />
<ClCompile Include="..\..\src\Math\FPS.cpp" /> <ClCompile Include="..\..\src\Math\FPS.cpp" />
<ClCompile Include="..\..\src\Math\Timer.cpp" /> <ClCompile Include="..\..\src\Math\Timer.cpp" />
<ClCompile Include="..\..\src\Math\Vec2.cpp" /> <ClCompile Include="..\..\src\Math\Vec2.cpp" />
@ -167,6 +171,8 @@
<ClCompile Include="..\..\src\TMXParser\TmxTile.cpp" /> <ClCompile Include="..\..\src\TMXParser\TmxTile.cpp" />
<ClCompile Include="..\..\src\TMXParser\TmxTileset.cpp" /> <ClCompile Include="..\..\src\TMXParser\TmxTileset.cpp" />
<ClCompile Include="..\..\src\TMXParser\TmxUtil.cpp" /> <ClCompile Include="..\..\src\TMXParser\TmxUtil.cpp" />
<ClCompile Include="..\..\src\UI\Button.cpp" />
<ClCompile Include="..\..\src\UI\Menu.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="tinyxml.vcxproj"> <ProjectReference Include="tinyxml.vcxproj">

View File

@ -46,6 +46,9 @@
<Filter Include="Animation"> <Filter Include="Animation">
<UniqueIdentifier>{2826112d-5f07-4ee2-b4b4-2be9289c6811}</UniqueIdentifier> <UniqueIdentifier>{2826112d-5f07-4ee2-b4b4-2be9289c6811}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="UI">
<UniqueIdentifier>{da9ad984-368f-4f6f-8f68-648733ae3a44}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\Main\Game.h"> <ClInclude Include="..\..\src\Main\Game.h">
@ -183,6 +186,15 @@
<ClInclude Include="..\..\src\Animation\AnimationSequence.h"> <ClInclude Include="..\..\src\Animation\AnimationSequence.h">
<Filter>Animation</Filter> <Filter>Animation</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\UI\Button.h">
<Filter>UI</Filter>
</ClInclude>
<ClInclude Include="..\..\src\Main\TitleScreen.h">
<Filter>Main</Filter>
</ClInclude>
<ClInclude Include="..\..\src\UI\Menu.h">
<Filter>UI</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\Main\main.cpp"> <ClCompile Include="..\..\src\Main\main.cpp">
@ -296,5 +308,14 @@
<ClCompile Include="..\..\src\Animation\AnimatingSprite.cpp"> <ClCompile Include="..\..\src\Animation\AnimatingSprite.cpp">
<Filter>Animation</Filter> <Filter>Animation</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\UI\Button.cpp">
<Filter>UI</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Main\TitleScreen.cpp">
<Filter>Main</Filter>
</ClCompile>
<ClCompile Include="..\..\src\UI\Menu.cpp">
<Filter>UI</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -19,8 +19,8 @@ Font::~Font(void) {
} }
} }
bool Font::Load(const std::string& filename) { bool Font::Load(const std::string& filename, int size) {
TTF_Font* font = TTF_OpenFont(filename.c_str(), 16); TTF_Font* font = TTF_OpenFont(filename.c_str(), size);
if(!font) { if(!font) {
Debug::logger->message("Error loading %s: %s", filename.c_str(), TTF_GetError()); Debug::logger->message("Error loading %s: %s", filename.c_str(), TTF_GetError());
return false; return false;
@ -94,7 +94,7 @@ bool Font::Load(const std::string& filename) {
return true; return true;
} }
void Font::DrawText(int xOffset, int yOffset, const char* text) { void Font::RenderText(int xOffset, int yOffset, const char* text) {
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
BindTexture(_texture); BindTexture(_texture);
@ -159,3 +159,24 @@ void Font::DrawText(int xOffset, int yOffset, const char* text) {
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
} }
void Font::TextSize(const char* text, int& width, int& height) {
width = 0;
height = _lineSkip;
int textLength = strlen(text);
for(int i = 0; i < textLength; i++) {
char c = text[i];
if(c == '\n') {
height += _lineSkip;
continue;
} else if(c == ' ') {
width += _spaceWidth;
continue;
} else if(c == '\t') {
width += _tabWidth;
continue;
}
width += _characters[(int)c].advance;
}
}

View File

@ -16,16 +16,15 @@ struct FontChar {
int advance; int advance;
}; };
class Font : public Resource { class Font {
template<class T> friend class ResourceManager;
public: public:
Font(void); Font(void);
~Font(void); ~Font(void);
bool Load(const std::string& filename); bool Load(const std::string& filename, int size);
void DrawText(int xOffset, int yOffset, const char* text); void RenderText(int xOffset, int yOffset, const char* text);
void TextSize(const char* text, int& width, int& height);
int GetLineSkip() const { return _lineSkip; } int GetLineSkip() const { return _lineSkip; }
float* GetColor() { return _color; } float* GetColor() { return _color; }

View File

@ -12,8 +12,10 @@
#include "../System/Debug.h" #include "../System/Debug.h"
#include "../Sprite/Sprite.h" #include "../Sprite/Sprite.h"
#include "../Texture/Texture.h" #include "../Texture/Texture.h"
#include "../Level/Level.h" #include "../Level/Level.h"
#include "Game.h" #include "Game.h"
#include "TitleScreen.h"
Game::Game(void) { Game::Game(void) {
_level = new Level(); _level = new Level();
@ -23,8 +25,13 @@ Game::Game(void) {
_NPC->SetXY(30.0f, 30.0f); _NPC->SetXY(30.0f, 30.0f);
_testFont = new Font(); _testFont = new Font();
_testFont->Load("../Data/Font/Fairydust.ttf"); _testFont->Load("../Data/Font/Fairydust.ttf", 24);
_testFont->SetColor(0.0f, 1.0f, 1.0f, 1.0f); _testFont->SetColor(0.0f, 1.0f, 1.0f, 1.0f);
_titleScreen = new TitleScreen();
_inTitleScreen = true;
_running = true;
} }
Game::~Game(void) { Game::~Game(void) {
@ -56,7 +63,80 @@ void Game::Prepare(float dt) {
void Game::Render(void) { void Game::Render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(_inTitleScreen) {
RenderTitle();
} else {
RenderGame();
}
}
void Game::Shutdown(void) {
Debug::logger->message("\n ----- Cleaning Engine -----");
delete _testFont;
delete _NPC;
delete _player;
delete _level;
delete _titleScreen;
}
void Game::ProcessEvents(float dt) {
if(_inTitleScreen) {
UpdateTitle(dt);
} else {
UpdateGame(dt);
}
}
void Game::OnResize(int width, int height) {
glViewport(0, 0, width, height);
windowWidth = width;
windowHeight = height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble)windowWidth, (GLdouble)windowHeight, 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Game::UpdateTitle(float dt) {
_titleScreen->Update(dt);
if(!_titleScreen->IsAlive()) {
switch(_titleScreen->GetResult()) {
case TitleScreen::QUIT:
_running = false;
break;
case TitleScreen::NEW_GAME:
_inTitleScreen = false;
break;
}
}
}
void Game::UpdateGame(float dt) {
_player->Update(dt);
_NPC->Update(dt);
_level->Update(dt);
}
void Game::RenderTitle(void) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
_titleScreen->Render();
}
void Game::RenderGame(void) {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
@ -80,35 +160,8 @@ void Game::Render(void) {
_level->Draw(xOffset, yOffset); _level->Draw(xOffset, yOffset);
_player->Render(); _player->Render();
_NPC->Render(); _NPC->Render();
_testFont->DrawText( _testFont->RenderText(
_player->GetX() - 5, _player->GetX() - 5,
_player->GetY() - _testFont->GetLineSkip() - 2, _player->GetY() - _testFont->GetLineSkip() - 2,
"Miss D"); "Miss D");
} }
void Game::Shutdown(void) {
Debug::logger->message("\n ----- Cleaning Engine -----");
delete _testFont;
delete _NPC;
delete _player;
delete _level;
}
void Game::ProcessEvents(float dt) {
_player->Update(dt);
_NPC->Update(dt);
}
void Game::OnResize(int width, int height) {
glViewport(0, 0, width, height);
windowWidth = width;
windowHeight = height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble)windowWidth, (GLdouble)windowHeight, 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

View File

@ -6,6 +6,8 @@
class Sprite; class Sprite;
class Level; class Level;
class Button;
class TitleScreen;
class Game { class Game {
public: public:
@ -21,9 +23,22 @@ public:
void OnResize(int width, int height); void OnResize(int width, int height);
bool IsRunning() { return _running; }
void SetRunning(bool running) { _running = running; }
private: private:
void UpdateTitle(float dt);
void UpdateGame(float dt);
void RenderTitle(void);
void RenderGame(void);
Font* _testFont; Font* _testFont;
Player* _player; Player* _player;
NPC* _NPC; NPC* _NPC;
Level* _level; Level* _level;
TitleScreen* _titleScreen;
bool _inTitleScreen;
bool _running;
}; };

61
src/Main/TitleScreen.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "TitleScreen.h"
#include "../Font/Font.h"
#include "../UI/Button.h"
#include "../Global/Globals.h"
TitleScreen::TitleScreen(void) {
_alive = true;
_result = TitleScreen::QUIT;
_font = new Font();
_font->Load("../Data/Font/fairydust.ttf", 24);
Button* newGameButton = new Button();
Button* loadGameButton = new Button();
Button* quitButton = new Button();
newGameButton->SetFont(_font);
loadGameButton->SetFont(_font);
quitButton->SetFont(_font);
newGameButton->SetText("New Game");
loadGameButton->SetText("Load Game");
quitButton->SetText("Quit");
_menu.AddButton(newGameButton);
_menu.AddButton(loadGameButton);
_menu.AddButton(quitButton);
_menu.AlignButtons(Menu::ALIGN_VERTICALLY);
_menu.SetXY(32, windowHeight - 128);
}
TitleScreen::~TitleScreen(void) {
if(_font) {
delete _font;
_font = NULL;
}
}
void TitleScreen::Update(float dt) {
_menu.Update();
switch(_menu.GetTriggeredButton()) {
case 0:
_alive = false;
_result = TitleScreen::NEW_GAME;
break;
case 1:
_alive = false;
_result = TitleScreen::LOAD_GAME;
break;
case 2:
_alive = false;
_result = TitleScreen::QUIT;
break;
}
}
void TitleScreen::Render(void) {
_menu.Render();
}

30
src/Main/TitleScreen.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include "../UI/Menu.h"
class Font;
class TitleScreen {
public:
enum {
NEW_GAME,
LOAD_GAME,
QUIT
};
TitleScreen(void);
~TitleScreen(void);
void Update(float dt);
void Render(void);
bool IsAlive(void) { return _alive; }
int GetResult(void) { return _result; }
private:
bool _alive;
int _result;
Font* _font;
Menu _menu;
};

View File

@ -99,12 +99,11 @@ int main(int argc, char** argv) {
// screws up for me. -- Allanis. // screws up for me. -- Allanis.
game.OnResize(windowWidth, windowHeight); game.OnResize(windowWidth, windowHeight);
bool isRunning = true; while(game.IsRunning()) {
while(isRunning) {
while(SDL_PollEvent(&event)) { while(SDL_PollEvent(&event)) {
if((event.type == SDL_QUIT) || KeyStillDown(SDLK_ESCAPE)) { if((event.type == SDL_QUIT) || KeyStillDown(SDLK_ESCAPE)) {
isRunning = false; game.SetRunning(false);
break; break;
} }
if(event.type == SDL_VIDEORESIZE) { if(event.type == SDL_VIDEORESIZE) {

58
src/UI/Button.cpp Normal file
View File

@ -0,0 +1,58 @@
#include "Button.h"
#include "../Font/Font.h"
#include "../IO/Input.h"
Button::Button(void) {
_text = "";
_font = NULL;
_highlighted = false;
_triggered = false;
x = 0;
y = 0;
w = 0;
h = 0;
}
void Button::Update(void) {
_triggered = false;
int mouseX = ::GetX();
int mouseY = ::GetY();
if((mouseX >= x) && (mouseX < (x + w)) &&
(mouseY >= y) && (mouseY < (y + h)))
{
_highlighted = true;
if(MouseUp(SDL_BUTTON(1))) {
_triggered = true;
}
} else {
_highlighted = false;
}
}
void Button::Render(void) {
if(_font) {
if(_highlighted) {
_font->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
} else {
_font->SetColor(0.5f, 0.5f, 0.5f, 1.0f);
}
_font->RenderText(x, y, _text.GetPointer());
_font->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
}
}
void Button::SetFont(Font* font) {
_font = font;
if(_text.Length() > 0) {
font->TextSize(_text.GetPointer(), w, h);
}
}
void Button::SetText(const String& text) {
_text = text;
if((_text.Length() > 0) && _font) {
_font->TextSize(text.GetPointer(), w, h);
}
}

44
src/UI/Button.h Normal file
View File

@ -0,0 +1,44 @@
#pragma once
#include "../System/String.h"
#include "../Font/Font.h"
class Button {
public:
Button(void);
void Update(void);
void Render(void);
Font* GetFont(void) { return _font; }
void SetFont(Font* font);
const String& GetText(void) const { return _text;}
void SetText(const String& text);
bool IsHighlighted(void) const { return _highlighted; }
void SetHighlighted(bool highlighted) { _highlighted = highlighted; }
bool Triggered(void) const { return _triggered; }
int GetX(void) const { return x; }
int GetY(void) const { return y; }
void SetX(int x) { this->x = x; }
void SetY(int y) { this->y = y; }
void SetXY(int x, int y) { SetX(x); SetY(y); }
int GetWidth(void) const { return w; }
int GetHeight(void) const { return h; }
private:
Font* _font;
String _text;
bool _highlighted;
bool _triggered;
int x;
int y;
int w;
int h;
};

67
src/UI/Menu.cpp Normal file
View File

@ -0,0 +1,67 @@
#include "Menu.h"
#include "Button.h"
Menu::Menu(void) {
_triggeredButton = -1;
x = 0;
y = 0;
}
Menu::~Menu(void) {
for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
delete (*i);
}
_buttons.clear();
}
void Menu::AddButton(Button* button) {
_buttons.push_back(button);
}
void Menu::AlignButtons(int how) {
int x = 0;
int y = 0;
for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
Button* button = (*i);
button->SetXY(x, y);
if(how == Menu::ALIGN_HORIZONTALLY) {
x += button->GetWidth() + 24;
} else if(how == Menu::ALIGN_VERTICALLY) {
y += button->GetHeight() + 2;
}
}
}
void Menu::Update(void) {
_triggeredButton = -1;
int index = 0;
for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
Button* button = (*i);
int oldX = button->GetX();
int oldY = button->GetY();
button->SetXY(oldX + x, oldY + y);
button->Update();
button->SetXY(oldX, oldY);
if(button->Triggered()) {
_triggeredButton = index;
}
index++;
}
}
void Menu::Render(void) {
for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
Button* button = (*i);
int oldX = button->GetX();
int oldY = button->GetY();
button->SetXY(oldX + x, oldY + y);
button->Render();
button->SetXY(oldX, oldY);
}
}

37
src/UI/Menu.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#include <list>
class Button;
class Menu {
public:
enum {
ALIGN_HORIZONTALLY,
ALIGN_VERTICALLY
};
Menu(void);
~Menu(void);
void AddButton(Button* button);
void AlignButtons(int how);
void Update(void);
void Render(void);
int GetTriggeredButton() const { return _triggeredButton; }
int GetX(void) const { return x; }
int GetY(void) const { return y; }
void SetX(int x) { this->x = x; }
void SetY(int y) { this->y = y; }
void SetXY(int x, int y) { SetX(x); SetY(y); }
private:
std::list<Button*> _buttons;
int _triggeredButton;
int x;
int y;
};