[Add] New memory management.
[Clean] Source code was messy, so I have given it a good clean.
This commit is contained in:
parent
d16472c28e
commit
896b966530
@ -12,7 +12,6 @@ HEADERS += ../src/Libs/wglext.h \
|
||||
../src/libUnuk/Engine/WorldManager.h \
|
||||
../src/libUnuk/Engine/ParticleEmitter.h \
|
||||
../src/libUnuk/Engine/NPC.h \
|
||||
../src/libUnuk/Engine/MemManager.h \
|
||||
../src/libUnuk/Engine/MemClass.h \
|
||||
../src/libUnuk/Engine/Collision.h \
|
||||
../src/libUnuk/Engine/Character.h \
|
||||
@ -49,11 +48,11 @@ HEADERS += ../src/Libs/wglext.h \
|
||||
../src/libUnuk/System/MathBox.h \
|
||||
../src/libUnuk/Engine/Pathfinding.h \
|
||||
../src/libUnuk/UI/SavegameMenu.h \
|
||||
../src/libUnuk/Engine/Spells.h
|
||||
../src/libUnuk/Engine/Spells.h \
|
||||
../src/libUnuk/Engine/MemManager.h
|
||||
SOURCES += ../src/libUnuk/Engine/WorldManager.cpp \
|
||||
../src/libUnuk/Engine/ParticleEmitter.cpp \
|
||||
../src/libUnuk/Engine/NPC.cpp \
|
||||
../src/libUnuk/Engine/MemManager.cpp \
|
||||
../src/libUnuk/Engine/Collision.cpp \
|
||||
../src/libUnuk/Engine/Character.cpp \
|
||||
../src/libUnuk/Sprite/TextureManager.cpp \
|
||||
@ -86,4 +85,5 @@ SOURCES += ../src/libUnuk/Engine/WorldManager.cpp \
|
||||
../src/libUnuk/UI/Bar.cpp \
|
||||
../src/libUnuk/System/Vec2.cpp \
|
||||
../src/libUnuk/UI/SavegameMenu.cpp \
|
||||
../src/libUnuk/Engine/Spells.cpp
|
||||
../src/libUnuk/Engine/Spells.cpp \
|
||||
../src/libUnuk/Engine/MemManager.cpp
|
||||
|
@ -5,470 +5,472 @@
|
||||
#include "../libUnuk/UI/EventHistory.h"
|
||||
|
||||
Game::Game(void) {
|
||||
Debug::logger->message("Creating characters..");
|
||||
_player = new Player(&_map);
|
||||
_map.SetPlayer(_player);
|
||||
Debug::logger->message("Creating characters..");
|
||||
_player = new Player(&_map);
|
||||
_map.SetPlayer(_player);
|
||||
|
||||
_runGameReturnValue = gameMainMenu;
|
||||
_runGameReturnValue = gameMainMenu;
|
||||
}
|
||||
|
||||
Game::~Game(void) {
|
||||
Debug::logger->message("\n----- Cleaning Up ------");
|
||||
// cleaning _player up caused a nice seg fault. I'll look later.
|
||||
//delete _player;
|
||||
Debug::logger->message("\n----- Cleaning Up ------");
|
||||
// cleaning _player up caused a nice seg fault. I'll look later.
|
||||
//delete _player;
|
||||
}
|
||||
|
||||
void Game::New(const string& savegameIDArg) {
|
||||
_saveGameID = savegameIDArg;
|
||||
NewSavegame(savegameIDArg);
|
||||
_saveGameID = savegameIDArg;
|
||||
NewSavegame(savegameIDArg);
|
||||
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
_map.FindSpawnPoint(spawnX, spawnY, 40, 45);
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
_map.FindSpawnPoint(spawnX, spawnY, 40, 45);
|
||||
|
||||
_player->SetXY((float)spawnX, (float)spawnY);
|
||||
_player->SetXY((float)spawnX, (float)spawnY);
|
||||
}
|
||||
|
||||
void Game::Load(const string& savegameIDArg) {
|
||||
_saveGameID = savegameIDArg;
|
||||
LoadSavegame(savegameIDArg);
|
||||
_saveGameID = savegameIDArg;
|
||||
LoadSavegame(savegameIDArg);
|
||||
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
_map.FindSpawnPoint(spawnX, spawnY, 40, 45);
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
_map.FindSpawnPoint(spawnX, spawnY, 40, 45);
|
||||
|
||||
_player->SetXY((float)spawnX, (float)spawnY);
|
||||
_player->SetXY((float)spawnX, (float)spawnY);
|
||||
}
|
||||
|
||||
gameNavVal_t Game::Run(void) {
|
||||
_player->LoadSprites("../Data/Media/Images/Characters/Reniesta.png", 40, 45);
|
||||
_player->LoadSprites("../Data/Media/Images/Characters/Reniesta.png", 40, 45);
|
||||
|
||||
int fps = 0;
|
||||
int frame = 0;
|
||||
int nextGameTick = SDL_GetTicks();
|
||||
int fps = 0;
|
||||
int frame = 0;
|
||||
int nextGameTick = SDL_GetTicks();
|
||||
|
||||
Timer frameTimer;
|
||||
frameTimer.Start();
|
||||
Timer frameTimer;
|
||||
frameTimer.Start();
|
||||
|
||||
Timer fpsCalc;
|
||||
fpsCalc.Start();
|
||||
Timer fpsCalc;
|
||||
fpsCalc.Start();
|
||||
|
||||
Timer renderTimer;
|
||||
Timer updateTimer;
|
||||
Timer renderTimer;
|
||||
Timer updateTimer;
|
||||
|
||||
stringstream playerHealth;
|
||||
_playerHealth.SetXY(15, 27);
|
||||
_playerHealth.SetTextBlended("Player Health - XX", vsmall, COLOUR_WHITE);
|
||||
stringstream playerHealth;
|
||||
_playerHealth.SetXY(15, 27);
|
||||
_playerHealth.SetTextBlended("Player Health - XX", vsmall, COLOUR_WHITE);
|
||||
|
||||
stringstream playerExp;
|
||||
_playerExp.SetXY(15, 57);
|
||||
_playerExp.SetTextBlended("Player Level XX (XX/XX)", vsmall, COLOUR_WHITE);
|
||||
stringstream playerExp;
|
||||
_playerExp.SetXY(15, 57);
|
||||
_playerExp.SetTextBlended("Player Level XX (XX/XX)", vsmall, COLOUR_WHITE);
|
||||
|
||||
_gameRenderTime.SetXY(10, 90);
|
||||
_gameRenderTime.SetTextBlended("Render - XX", vsmall, COLOUR_BLACK);
|
||||
_gameRenderTime.SetXY(10, 90);
|
||||
_gameRenderTime.SetTextBlended("Render - XX", vsmall, COLOUR_BLACK);
|
||||
|
||||
_gameUpdateTime.SetXY(10, 110);
|
||||
_gameUpdateTime.SetTextBlended("Update - XX", vsmall, COLOUR_BLACK);
|
||||
_gameUpdateTime.SetXY(10, 110);
|
||||
_gameUpdateTime.SetTextBlended("Update - XX", vsmall, COLOUR_BLACK);
|
||||
|
||||
stringstream playerXYString;
|
||||
_playerXY.SetXY(10, 130);
|
||||
_playerXY.SetTextBlended("Player coords - XX XX", vsmall, COLOUR_BLACK);
|
||||
stringstream playerXYString;
|
||||
_playerXY.SetXY(10, 130);
|
||||
_playerXY.SetTextBlended("Player coords - XX XX", vsmall, COLOUR_BLACK);
|
||||
|
||||
_playerHealthBar.SetBackgroundRGB(0, 0, 0);
|
||||
_playerHealthBar.SetForegroundRGB(255, 0, 0);
|
||||
_playerHealthBar.SetXY(10, 20);
|
||||
_playerHealthBar.SetWidthHeight(200, 25);
|
||||
_playerHealthBar.SetBackgroundRGB(0, 0, 0);
|
||||
_playerHealthBar.SetForegroundRGB(255, 0, 0);
|
||||
_playerHealthBar.SetXY(10, 20);
|
||||
_playerHealthBar.SetWidthHeight(200, 25);
|
||||
|
||||
_playerExpBar.SetBackgroundRGB(0, 0, 0);
|
||||
_playerExpBar.SetForegroundRGB(0, 0, 255);
|
||||
_playerExpBar.SetXY(10, 50);
|
||||
_playerExpBar.SetWidthHeight(200, 25);
|
||||
_playerExpBar.SetProgress(0.0f);
|
||||
_playerExpBar.SetBackgroundRGB(0, 0, 0);
|
||||
_playerExpBar.SetForegroundRGB(0, 0, 255);
|
||||
_playerExpBar.SetXY(10, 50);
|
||||
_playerExpBar.SetWidthHeight(200, 25);
|
||||
_playerExpBar.SetProgress(0.0f);
|
||||
|
||||
eventHistory = new EventHistory();
|
||||
eventHistory = new EventHistory();
|
||||
|
||||
_gameRunning = true;
|
||||
while(_gameRunning) {
|
||||
bool stillRunning = true;
|
||||
_gameRunning = true;
|
||||
while(_gameRunning) {
|
||||
bool stillRunning = true;
|
||||
|
||||
updateTimer.Start();
|
||||
while((int)SDL_GetTicks() > nextGameTick) {
|
||||
HandleInput();
|
||||
if (!_gameRunning) {
|
||||
stillRunning = false;
|
||||
break;
|
||||
}
|
||||
updateTimer.Start();
|
||||
while((int)SDL_GetTicks() > nextGameTick) {
|
||||
HandleInput();
|
||||
if (!_gameRunning) {
|
||||
stillRunning = false;
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateGame();
|
||||
UpdateGame();
|
||||
|
||||
nextGameTick += SKIP_TICKS;
|
||||
}
|
||||
updateTimer.Pause();
|
||||
nextGameTick += SKIP_TICKS;
|
||||
}
|
||||
updateTimer.Pause();
|
||||
|
||||
if (!stillRunning) {
|
||||
break;
|
||||
}
|
||||
if (!stillRunning) {
|
||||
break;
|
||||
}
|
||||
|
||||
renderTimer.Start();
|
||||
Render();
|
||||
renderTimer.Pause();
|
||||
renderTimer.Start();
|
||||
Render();
|
||||
renderTimer.Pause();
|
||||
|
||||
// Calculate and display our FPS.
|
||||
if(fpsCalc.GetTicks() >= 1000) {
|
||||
fps = frame / (fpsCalc.GetTicks() / 1000);
|
||||
// Calculate and display our FPS.
|
||||
if(fpsCalc.GetTicks() >= 1000) {
|
||||
fps = frame / (fpsCalc.GetTicks() / 1000);
|
||||
|
||||
stringstream caption;
|
||||
caption << "Unuk - FPS: " << fps;
|
||||
stringstream caption;
|
||||
caption << "Unuk - FPS: " << fps;
|
||||
|
||||
SDL_WM_SetCaption(caption.str().c_str(), NULL);
|
||||
SDL_WM_SetCaption(caption.str().c_str(), NULL);
|
||||
|
||||
fpsCalc.Start();
|
||||
frame = 0;
|
||||
fpsCalc.Start();
|
||||
frame = 0;
|
||||
|
||||
playerHealth.str("");
|
||||
playerHealth << "Player Health - " << _player->GetHealth();
|
||||
_playerHealth.SetTextBlended(playerHealth.str(), vsmall, COLOUR_WHITE);
|
||||
playerHealth.str("");
|
||||
playerHealth << "Player Health - " << _player->GetHealth();
|
||||
_playerHealth.SetTextBlended(playerHealth.str(), vsmall, COLOUR_WHITE);
|
||||
|
||||
_playerHealthBar.SetProgress((float)_player->GetHealth() / 100.0f);
|
||||
_playerHealthBar.SetProgress((float)_player->GetHealth() / 100.0f);
|
||||
|
||||
playerExp.str("");
|
||||
playerExp << "Player Level " << _player->GetLevel() << " (" << _player->GetExp() << "/" << Player::EXP_TABLE[_player->GetLevel() - 1] << ")";
|
||||
_playerExp.SetTextBlended(playerExp.str(), vsmall, COLOUR_WHITE);
|
||||
playerExp.str("");
|
||||
playerExp << "Player Level " << _player->GetLevel() << " (" << _player->GetExp() << "/" << Player::EXP_TABLE[_player->GetLevel() - 1] << ")";
|
||||
_playerExp.SetTextBlended(playerExp.str(), vsmall, COLOUR_WHITE);
|
||||
|
||||
_playerExpBar.SetProgress((float)_player->GetExp() / (float)Player::EXP_TABLE[_player->GetLevel() - 1]);
|
||||
_playerExpBar.SetProgress((float)_player->GetExp() / (float)Player::EXP_TABLE[_player->GetLevel() - 1]);
|
||||
|
||||
// Check to see if we are allowed to display debug info.
|
||||
if(debugEnabled) {
|
||||
_gameUpdateTime.SetTextBlended("Update - " + updateTimer.GetTicksStr(), vsmall, COLOUR_BLACK);
|
||||
_gameRenderTime.SetTextBlended("Render - " + renderTimer.GetTicksStr(), vsmall, COLOUR_BLACK);
|
||||
// Check to see if we are allowed to display debug info.
|
||||
if(debugEnabled) {
|
||||
_gameUpdateTime.SetTextBlended("Update - " + updateTimer.GetTicksStr(), vsmall, COLOUR_BLACK);
|
||||
_gameRenderTime.SetTextBlended("Render - " + renderTimer.GetTicksStr(), vsmall, COLOUR_BLACK);
|
||||
|
||||
playerXYString.str("");
|
||||
playerXYString << "Player coords: x" << _player->GetX() << ", y" << _player->GetY();
|
||||
_playerXY.SetTextBlended(playerXYString.str(), vsmall, COLOUR_BLACK);
|
||||
}
|
||||
}
|
||||
// Restrict the fps.
|
||||
if(1000 / MAX_FPS > frameTimer.GetTicks()) {
|
||||
// SDL_Delay does not accept a float so for higher framerate
|
||||
// limits there's an innacuracy. This is as much as 3fps
|
||||
// at a limit of 60fps.
|
||||
SDL_Delay((1000 / MAX_FPS) - frameTimer.GetTicks());
|
||||
}
|
||||
frameTimer.Start();
|
||||
frame++;
|
||||
}
|
||||
playerXYString.str("");
|
||||
playerXYString << "Player coords: x" << _player->GetX() << ", y" << _player->GetY();
|
||||
_playerXY.SetTextBlended(playerXYString.str(), vsmall, COLOUR_BLACK);
|
||||
}
|
||||
}
|
||||
// Restrict the fps.
|
||||
if(1000 / MAX_FPS > frameTimer.GetTicks()) {
|
||||
// SDL_Delay does not accept a float so for higher framerate
|
||||
// limits there's an innacuracy. This is as much as 3fps
|
||||
// at a limit of 60fps.
|
||||
SDL_Delay((1000 / MAX_FPS) - frameTimer.GetTicks());
|
||||
}
|
||||
frameTimer.Start();
|
||||
frame++;
|
||||
}
|
||||
|
||||
delete eventHistory;
|
||||
delete eventHistory;
|
||||
|
||||
return _runGameReturnValue;
|
||||
return _runGameReturnValue;
|
||||
}
|
||||
|
||||
void Game::HandleInput(void) {
|
||||
if(_ingameMenu.GetStatus() == false) {
|
||||
while(SDL_PollEvent(&event)) {
|
||||
_player->HandleInput();
|
||||
if(_ingameMenu.GetStatus() == false) {
|
||||
while(SDL_PollEvent(&event)) {
|
||||
_player->HandleInput();
|
||||
|
||||
if(event.key.type == SDL_KEYDOWN) {
|
||||
if(event.key.keysym.sym == SDLK_ESCAPE)
|
||||
_ingameMenu.SetStatus(true);
|
||||
if(event.key.keysym.sym == SDLK_p)
|
||||
debugEnabled = !debugEnabled;
|
||||
if(event.key.keysym.sym == SDLK_0)
|
||||
eventHistory->LogEvent("Item gained.");
|
||||
}
|
||||
else if(event.type == SDL_QUIT) {
|
||||
_gameRunning = false;
|
||||
_runGameReturnValue = gameQuitGame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch(_ingameMenu.HandleInput()) {
|
||||
case ingameMenuNothing:
|
||||
break;
|
||||
case ingameMenuResume:
|
||||
_ingameMenu.SetStatus(false);
|
||||
break;
|
||||
case ingameMenuSaveGame:
|
||||
SaveSavegame();
|
||||
_ingameMenu.SetStatus(false);
|
||||
Debug::logger->message("Game Saved!");
|
||||
break;
|
||||
case ingameMenuLoadGame:
|
||||
LoadSavegame(_saveGameID);
|
||||
_ingameMenu.SetStatus(false);
|
||||
Debug::logger->message("Game Loaded!");
|
||||
break;
|
||||
case ingameMenuOptions:
|
||||
break;
|
||||
case ingameMenuMainMenu:
|
||||
SDL_FillRect(screen, NULL, 0);
|
||||
_gameRunning = false;
|
||||
break;
|
||||
}
|
||||
if(event.key.type == SDL_KEYDOWN) {
|
||||
if(event.key.keysym.sym == SDLK_ESCAPE)
|
||||
_ingameMenu.SetStatus(true);
|
||||
if(event.key.keysym.sym == SDLK_p)
|
||||
debugEnabled = !debugEnabled;
|
||||
if(event.key.keysym.sym == SDLK_0)
|
||||
eventHistory->LogEvent("Item gained.");
|
||||
}
|
||||
else if(event.type == SDL_QUIT) {
|
||||
_gameRunning = false;
|
||||
_runGameReturnValue = gameQuitGame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch(_ingameMenu.HandleInput()) {
|
||||
case ingameMenuNothing:
|
||||
break;
|
||||
case ingameMenuResume:
|
||||
_ingameMenu.SetStatus(false);
|
||||
break;
|
||||
case ingameMenuSaveGame:
|
||||
SaveSavegame();
|
||||
_ingameMenu.SetStatus(false);
|
||||
Debug::logger->message("Game Saved!");
|
||||
break;
|
||||
case ingameMenuLoadGame:
|
||||
LoadSavegame(_saveGameID);
|
||||
_ingameMenu.SetStatus(false);
|
||||
Debug::logger->message("Game Loaded!");
|
||||
break;
|
||||
case ingameMenuOptions:
|
||||
break;
|
||||
case ingameMenuMainMenu:
|
||||
SDL_FillRect(screen, NULL, 0);
|
||||
_gameRunning = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(event.type == SDL_QUIT) {
|
||||
_gameRunning = false;
|
||||
_ingameMenu.SetStatus(false);
|
||||
_runGameReturnValue = gameQuitGame;
|
||||
}
|
||||
}
|
||||
if(event.type == SDL_QUIT) {
|
||||
_gameRunning = false;
|
||||
_ingameMenu.SetStatus(false);
|
||||
_runGameReturnValue = gameQuitGame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::UpdateGame(void) {
|
||||
if(_ingameMenu.GetStatus() == false) {
|
||||
_map.Update();
|
||||
_player->Update();
|
||||
|
||||
UpdateInput();
|
||||
if(_ingameMenu.GetStatus() == false) {
|
||||
_map.Update();
|
||||
_player->Update();
|
||||
|
||||
if(gameOver) {
|
||||
gameOver = false;
|
||||
|
||||
|
||||
_map.New();
|
||||
_player->SetHealth(100);
|
||||
_player->SetLevelLiteral(1);
|
||||
_player->SetExpLiteral(0);
|
||||
|
||||
|
||||
New(_saveGameID);
|
||||
}
|
||||
|
||||
} else {
|
||||
// :D
|
||||
}
|
||||
|
||||
} else {
|
||||
// :D
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Game::Render(void) {
|
||||
//SDL_FillRect(screen, NULL, 0); // You might want to clear the buffer! --konom | I don't want a blacked out ingame menu, save it for MainMenu. --Allanis
|
||||
if(_ingameMenu.GetStatus() == false) {
|
||||
_map.Render();
|
||||
_player->Render();
|
||||
//SDL_FillRect(screen, NULL, 0);
|
||||
if(_ingameMenu.GetStatus() == false) {
|
||||
_map.Render();
|
||||
_player->Render();
|
||||
|
||||
_playerHealthBar.DrawLiteral();
|
||||
_playerHealth.RenderLiteral();
|
||||
_playerHealthBar.DrawLiteral();
|
||||
_playerHealth.RenderLiteral();
|
||||
|
||||
_playerExpBar.DrawLiteral();
|
||||
_playerExp.RenderLiteral();
|
||||
_playerExpBar.DrawLiteral();
|
||||
_playerExp.RenderLiteral();
|
||||
|
||||
if(debugEnabled) {
|
||||
_gameRenderTime.RenderLiteral();
|
||||
_gameUpdateTime.RenderLiteral();
|
||||
_playerXY.RenderLiteral();
|
||||
_npcHealth.RenderLiteral();
|
||||
}
|
||||
if(debugEnabled) {
|
||||
_gameRenderTime.RenderLiteral();
|
||||
_gameUpdateTime.RenderLiteral();
|
||||
_playerXY.RenderLiteral();
|
||||
_npcHealth.RenderLiteral();
|
||||
}
|
||||
|
||||
eventHistory->Render();
|
||||
eventHistory->Render();
|
||||
|
||||
} else {
|
||||
_ingameMenu.Render();
|
||||
}
|
||||
SDL_Flip(screen);
|
||||
} else {
|
||||
_ingameMenu.Render();
|
||||
}
|
||||
SDL_Flip(screen);
|
||||
}
|
||||
|
||||
void Game::NewSavegame(const string savegameIDArg) {
|
||||
string saveFilename = "../Save/" + savegameIDArg;
|
||||
string saveFilename = "../Save/" + savegameIDArg;
|
||||
|
||||
_map.New();
|
||||
_map.Save(_saveGameID);
|
||||
_map.New();
|
||||
_map.Save(_saveGameID);
|
||||
|
||||
TiXmlDocument doc;
|
||||
TiXmlDocument doc;
|
||||
|
||||
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "", "");
|
||||
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "", "");
|
||||
|
||||
TiXmlElement* saveElement = new TiXmlElement("save");
|
||||
TiXmlElement* saveElement = new TiXmlElement("save");
|
||||
|
||||
TiXmlElement* nameElement = new TiXmlElement("name");
|
||||
TiXmlText* nameText = new TiXmlText("Allanis"); //TODO: replace with _player->GetName() when it works. --konom
|
||||
nameElement->LinkEndChild(nameText);
|
||||
TiXmlElement* nameElement = new TiXmlElement("name");
|
||||
TiXmlText* nameText = new TiXmlText("Allanis"); //TODO: replace with _player->GetName() when it works.
|
||||
nameElement->LinkEndChild(nameText);
|
||||
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
_map.FindSpawnPoint(spawnX, spawnY, 40, 45);
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
_map.FindSpawnPoint(spawnX, spawnY, 40, 45);
|
||||
|
||||
_player->SetXY(spawnX, spawnY);
|
||||
_player->SetXY(spawnX, spawnY);
|
||||
|
||||
std::stringstream xString;
|
||||
xString << spawnX;
|
||||
std::stringstream xString;
|
||||
xString << spawnX;
|
||||
|
||||
TiXmlElement* xElement = new TiXmlElement("x");
|
||||
TiXmlText* xText = new TiXmlText(xString.str().c_str());
|
||||
xElement->LinkEndChild(xText);
|
||||
TiXmlElement* xElement = new TiXmlElement("x");
|
||||
TiXmlText* xText = new TiXmlText(xString.str().c_str());
|
||||
xElement->LinkEndChild(xText);
|
||||
|
||||
std::stringstream yString;
|
||||
yString << spawnY;
|
||||
std::stringstream yString;
|
||||
yString << spawnY;
|
||||
|
||||
TiXmlElement* yElement = new TiXmlElement("y");
|
||||
TiXmlText* yText = new TiXmlText(yString.str().c_str());
|
||||
yElement->LinkEndChild(yText);
|
||||
TiXmlElement* yElement = new TiXmlElement("y");
|
||||
TiXmlText* yText = new TiXmlText(yString.str().c_str());
|
||||
yElement->LinkEndChild(yText);
|
||||
|
||||
_player->SetLevelLiteral(1);
|
||||
_player->SetLevelLiteral(1);
|
||||
|
||||
TiXmlElement* levelElement = new TiXmlElement("level");
|
||||
TiXmlText* levelText = new TiXmlText("1");
|
||||
levelElement->LinkEndChild(levelText);
|
||||
TiXmlElement* levelElement = new TiXmlElement("level");
|
||||
TiXmlText* levelText = new TiXmlText("1");
|
||||
levelElement->LinkEndChild(levelText);
|
||||
|
||||
_player->SetExpLiteral(0);
|
||||
_player->SetExpLiteral(0);
|
||||
|
||||
TiXmlElement* expElement = new TiXmlElement("exp");
|
||||
TiXmlText* expText = new TiXmlText("0");
|
||||
expElement->LinkEndChild(expText);
|
||||
TiXmlElement* expElement = new TiXmlElement("exp");
|
||||
TiXmlText* expText = new TiXmlText("0");
|
||||
expElement->LinkEndChild(expText);
|
||||
|
||||
TiXmlElement* healthElement = new TiXmlElement("health");
|
||||
TiXmlText* healthText = new TiXmlText("100");
|
||||
healthElement->LinkEndChild(healthText);
|
||||
TiXmlElement* healthElement = new TiXmlElement("health");
|
||||
TiXmlText* healthText = new TiXmlText("100");
|
||||
healthElement->LinkEndChild(healthText);
|
||||
|
||||
TiXmlElement* mapElement = new TiXmlElement("map");
|
||||
TiXmlText* mapText = new TiXmlText("map"); //TODO: replace with actual map name.
|
||||
mapElement->LinkEndChild(mapText);
|
||||
TiXmlElement* mapElement = new TiXmlElement("map");
|
||||
TiXmlText* mapText = new TiXmlText("map"); //TODO: replace with actual map name.
|
||||
mapElement->LinkEndChild(mapText);
|
||||
|
||||
saveElement->LinkEndChild(nameElement);
|
||||
saveElement->LinkEndChild(xElement);
|
||||
saveElement->LinkEndChild(yElement);
|
||||
saveElement->LinkEndChild(levelElement);
|
||||
saveElement->LinkEndChild(expElement);
|
||||
saveElement->LinkEndChild(healthElement);
|
||||
saveElement->LinkEndChild(mapElement);
|
||||
saveElement->LinkEndChild(nameElement);
|
||||
saveElement->LinkEndChild(xElement);
|
||||
saveElement->LinkEndChild(yElement);
|
||||
saveElement->LinkEndChild(levelElement);
|
||||
saveElement->LinkEndChild(expElement);
|
||||
saveElement->LinkEndChild(healthElement);
|
||||
saveElement->LinkEndChild(mapElement);
|
||||
|
||||
doc.LinkEndChild(decl);
|
||||
doc.LinkEndChild(saveElement);
|
||||
doc.LinkEndChild(decl);
|
||||
doc.LinkEndChild(saveElement);
|
||||
|
||||
doc.SaveFile(saveFilename.c_str());
|
||||
doc.SaveFile(saveFilename.c_str());
|
||||
}
|
||||
|
||||
void Game::LoadSavegame(const string savegameIDArg) {
|
||||
_saveGameID = savegameIDArg;
|
||||
string saveFilename = "../Save/" + _saveGameID;
|
||||
_saveGameID = savegameIDArg;
|
||||
string saveFilename = "../Save/" + _saveGameID;
|
||||
|
||||
// Converting to XML ftw!
|
||||
TiXmlDocument mapFile(saveFilename.c_str());
|
||||
// Converting to XML ftw!
|
||||
TiXmlDocument mapFile(saveFilename.c_str());
|
||||
|
||||
// Create new save if can't load file.
|
||||
if(!mapFile.LoadFile()) {
|
||||
New(savegameIDArg);
|
||||
return;
|
||||
}
|
||||
// Create new save if can't load file.
|
||||
if(!mapFile.LoadFile()) {
|
||||
New(savegameIDArg);
|
||||
return;
|
||||
}
|
||||
|
||||
TiXmlElement* rootElem = NULL;
|
||||
TiXmlElement* dataElem = NULL;
|
||||
TiXmlElement* rootElem = NULL;
|
||||
TiXmlElement* dataElem = NULL;
|
||||
|
||||
// <save> - Grab a save file.
|
||||
rootElem = mapFile.FirstChildElement("save");
|
||||
assert(rootElem != NULL);
|
||||
if(rootElem) {
|
||||
// <name> - Parse the player name.
|
||||
dataElem = rootElem->FirstChildElement("name");
|
||||
assert(dataElem != NULL);
|
||||
// <save> - Grab a save file.
|
||||
rootElem = mapFile.FirstChildElement("save");
|
||||
assert(rootElem != NULL);
|
||||
if(rootElem) {
|
||||
// <name> - Parse the player name.
|
||||
dataElem = rootElem->FirstChildElement("name");
|
||||
assert(dataElem != NULL);
|
||||
|
||||
// Overloaded new/delete operator takes this out of scope..
|
||||
// TODO: Fix.
|
||||
//_player->SetName(dataElem->GetText());
|
||||
// </name>
|
||||
// Overloaded new/delete operator takes this out of scope..
|
||||
// TODO: Fix.
|
||||
//_player->SetName(dataElem->GetText());
|
||||
// </name>
|
||||
|
||||
/*
|
||||
// <x> - Parse the player x coord.
|
||||
dataElem = dataElem->NextSiblingElement("x");
|
||||
assert(dataElem != NULL);
|
||||
int playerX = atoi(dataElem->GetText());
|
||||
// </x>
|
||||
/*
|
||||
// <x> - Parse the player x coord.
|
||||
dataElem = dataElem->NextSiblingElement("x");
|
||||
assert(dataElem != NULL);
|
||||
int playerX = atoi(dataElem->GetText());
|
||||
// </x>
|
||||
|
||||
// <y> - Parse the player y coord.
|
||||
dataElem = dataElem->NextSiblingElement("y");
|
||||
assert(dataElem != NULL);
|
||||
int playerY = atoi(dataElem->GetText());
|
||||
// </y>
|
||||
_player->SetXY((float)playerX, (float)playerY);
|
||||
// <y> - Parse the player y coord.
|
||||
dataElem = dataElem->NextSiblingElement("y");
|
||||
assert(dataElem != NULL);
|
||||
int playerY = atoi(dataElem->GetText());
|
||||
// </y>
|
||||
_player->SetXY((float)playerX, (float)playerY);
|
||||
*/
|
||||
|
||||
// <level> - Parse the player level.
|
||||
dataElem = dataElem->NextSiblingElement("level");
|
||||
assert(dataElem != NULL);
|
||||
int playerLevel = atoi(dataElem->GetText());
|
||||
// </level>
|
||||
// <level> - Parse the player level.
|
||||
dataElem = dataElem->NextSiblingElement("level");
|
||||
assert(dataElem != NULL);
|
||||
int playerLevel = atoi(dataElem->GetText());
|
||||
// </level>
|
||||
|
||||
_player->SetLevelLiteral(playerLevel);
|
||||
_player->SetLevelLiteral(playerLevel);
|
||||
|
||||
// <exp> - Parse the player exp.
|
||||
dataElem = dataElem->NextSiblingElement("exp");
|
||||
assert(dataElem != NULL);
|
||||
int playerExp = atoi(dataElem->GetText());
|
||||
// </exp>
|
||||
// <exp> - Parse the player exp.
|
||||
dataElem = dataElem->NextSiblingElement("exp");
|
||||
assert(dataElem != NULL);
|
||||
int playerExp = atoi(dataElem->GetText());
|
||||
// </exp>
|
||||
|
||||
_player->SetExpLiteral(playerExp);
|
||||
_player->SetExpLiteral(playerExp);
|
||||
|
||||
// <health> - Parse the player health.
|
||||
dataElem = dataElem->NextSiblingElement("health");
|
||||
assert(dataElem != NULL);
|
||||
int playerHealth = atoi(dataElem->GetText());
|
||||
// </health>
|
||||
// <health> - Parse the player health.
|
||||
dataElem = dataElem->NextSiblingElement("health");
|
||||
assert(dataElem != NULL);
|
||||
int playerHealth = atoi(dataElem->GetText());
|
||||
// </health>
|
||||
|
||||
_player->SetHealthLiteral(playerHealth);
|
||||
}
|
||||
// <save>
|
||||
_player->SetHealthLiteral(playerHealth);
|
||||
}
|
||||
// <save>
|
||||
|
||||
// </save>
|
||||
// </save>
|
||||
|
||||
_map.Load(_saveGameID);
|
||||
_map.Load(_saveGameID);
|
||||
}
|
||||
|
||||
void Game::SaveSavegame(void) {
|
||||
string saveFilename = "../Save/" + _saveGameID;
|
||||
string saveFilename = "../Save/" + _saveGameID;
|
||||
|
||||
TiXmlDocument doc;
|
||||
TiXmlDocument doc;
|
||||
|
||||
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "", "");
|
||||
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "", "");
|
||||
|
||||
TiXmlElement* saveElement = new TiXmlElement("save");
|
||||
TiXmlElement* saveElement = new TiXmlElement("save");
|
||||
|
||||
TiXmlElement* nameElement = new TiXmlElement("name");
|
||||
TiXmlText* nameText = new TiXmlText("Allanis"); //TODO: replace with _player->GetName() when it works. --konom
|
||||
nameElement->LinkEndChild(nameText);
|
||||
TiXmlElement* nameElement = new TiXmlElement("name");
|
||||
TiXmlText* nameText = new TiXmlText("Allanis"); //TODO: replace with _player->GetName() when it works. --konom
|
||||
nameElement->LinkEndChild(nameText);
|
||||
|
||||
/*
|
||||
std::stringstream xString;
|
||||
xString << _player->GetX();
|
||||
/*
|
||||
std::stringstream xString;
|
||||
xString << _player->GetX();
|
||||
|
||||
TiXmlElement* xElement = new TiXmlElement("x");
|
||||
TiXmlText* xText = new TiXmlText(xString.str().c_str());
|
||||
xElement->LinkEndChild(xText);
|
||||
TiXmlElement* xElement = new TiXmlElement("x");
|
||||
TiXmlText* xText = new TiXmlText(xString.str().c_str());
|
||||
xElement->LinkEndChild(xText);
|
||||
|
||||
std::stringstream yString;
|
||||
yString << _player->GetY();
|
||||
std::stringstream yString;
|
||||
yString << _player->GetY();
|
||||
|
||||
TiXmlElement* yElement = new TiXmlElement("y");
|
||||
TiXmlText* yText = new TiXmlText(yString.str().c_str());
|
||||
yElement->LinkEndChild(yText);
|
||||
TiXmlElement* yElement = new TiXmlElement("y");
|
||||
TiXmlText* yText = new TiXmlText(yString.str().c_str());
|
||||
yElement->LinkEndChild(yText);
|
||||
*/
|
||||
|
||||
std::stringstream levelString;
|
||||
levelString << _player->GetLevel();
|
||||
std::stringstream levelString;
|
||||
levelString << _player->GetLevel();
|
||||
|
||||
TiXmlElement* levelElement = new TiXmlElement("level");
|
||||
TiXmlText* levelText = new TiXmlText(levelString.str().c_str());
|
||||
levelElement->LinkEndChild(levelText);
|
||||
TiXmlElement* levelElement = new TiXmlElement("level");
|
||||
TiXmlText* levelText = new TiXmlText(levelString.str().c_str());
|
||||
levelElement->LinkEndChild(levelText);
|
||||
|
||||
std::stringstream expString;
|
||||
expString << _player->GetExp();
|
||||
std::stringstream expString;
|
||||
expString << _player->GetExp();
|
||||
|
||||
TiXmlElement* expElement = new TiXmlElement("exp");
|
||||
TiXmlText* expText = new TiXmlText(expString.str().c_str());
|
||||
expElement->LinkEndChild(expText);
|
||||
TiXmlElement* expElement = new TiXmlElement("exp");
|
||||
TiXmlText* expText = new TiXmlText(expString.str().c_str());
|
||||
expElement->LinkEndChild(expText);
|
||||
|
||||
std::stringstream healthString;
|
||||
healthString << _player->GetHealth();
|
||||
std::stringstream healthString;
|
||||
healthString << _player->GetHealth();
|
||||
|
||||
TiXmlElement* healthElement = new TiXmlElement("health");
|
||||
TiXmlText* healthText = new TiXmlText(healthString.str().c_str());
|
||||
healthElement->LinkEndChild(healthText);
|
||||
TiXmlElement* healthElement = new TiXmlElement("health");
|
||||
TiXmlText* healthText = new TiXmlText(healthString.str().c_str());
|
||||
healthElement->LinkEndChild(healthText);
|
||||
|
||||
saveElement->LinkEndChild(nameElement);
|
||||
//saveElement->LinkEndChild(xElement);
|
||||
//saveElement->LinkEndChild(yElement);
|
||||
saveElement->LinkEndChild(levelElement);
|
||||
saveElement->LinkEndChild(expElement);
|
||||
saveElement->LinkEndChild(healthElement);
|
||||
saveElement->LinkEndChild(nameElement);
|
||||
//saveElement->LinkEndChild(xElement);
|
||||
//saveElement->LinkEndChild(yElement);
|
||||
saveElement->LinkEndChild(levelElement);
|
||||
saveElement->LinkEndChild(expElement);
|
||||
saveElement->LinkEndChild(healthElement);
|
||||
|
||||
doc.LinkEndChild(decl);
|
||||
doc.LinkEndChild(saveElement);
|
||||
doc.LinkEndChild(decl);
|
||||
doc.LinkEndChild(saveElement);
|
||||
|
||||
doc.SaveFile(saveFilename.c_str());
|
||||
doc.SaveFile(saveFilename.c_str());
|
||||
|
||||
_map.Save(_saveGameID);
|
||||
_map.Save(_saveGameID);
|
||||
}
|
||||
|
@ -23,46 +23,46 @@ enum gameNavVal_t { gameMainMenu, gameQuitGame };
|
||||
|
||||
class Game {
|
||||
public:
|
||||
Game(void);
|
||||
~Game(void);
|
||||
Game(void);
|
||||
~Game(void);
|
||||
|
||||
void New(const string& savegameIDArg);
|
||||
void Load(const string& savegameIDArg);
|
||||
void New(const string& savegameIDArg);
|
||||
void Load(const string& savegameIDArg);
|
||||
|
||||
gameNavVal_t Run(void);
|
||||
gameNavVal_t Run(void);
|
||||
|
||||
private:
|
||||
void HandleInput(void);
|
||||
void UpdateGame(void);
|
||||
void Render(void);
|
||||
void HandleInput(void);
|
||||
void UpdateGame(void);
|
||||
void Render(void);
|
||||
|
||||
void NewSavegame(const string savegameIDArg);
|
||||
void LoadSavegame(const string savegameIDArg);
|
||||
void SaveSavegame(void);
|
||||
void NewSavegame(const string savegameIDArg);
|
||||
void LoadSavegame(const string savegameIDArg);
|
||||
void SaveSavegame(void);
|
||||
|
||||
static const int MAX_FPS = 200;
|
||||
static const int GAME_UPDATES_PER_SECOND = 60;
|
||||
static const int SKIP_TICKS = 1000 / GAME_UPDATES_PER_SECOND;
|
||||
static const int MAX_FPS = 200;
|
||||
static const int GAME_UPDATES_PER_SECOND = 60;
|
||||
static const int SKIP_TICKS = 1000 / GAME_UPDATES_PER_SECOND;
|
||||
|
||||
bool _gameRunning;
|
||||
bool _gameRunning;
|
||||
|
||||
gameNavVal_t _runGameReturnValue;
|
||||
gameNavVal_t _runGameReturnValue;
|
||||
|
||||
string _saveGameID;
|
||||
string _mapID;
|
||||
string _saveGameID;
|
||||
string _mapID;
|
||||
|
||||
Text _gameUpdateTime;
|
||||
Text _gameRenderTime;
|
||||
Text _playerXY;
|
||||
Text _npcHealth;
|
||||
Text _gameUpdateTime;
|
||||
Text _gameRenderTime;
|
||||
Text _playerXY;
|
||||
Text _npcHealth;
|
||||
|
||||
IngameMenu _ingameMenu;
|
||||
LevelGen _map;
|
||||
IngameMenu _ingameMenu;
|
||||
LevelGen _map;
|
||||
|
||||
Player* _player;
|
||||
Player* _player;
|
||||
|
||||
Text _playerHealth;
|
||||
Text _playerExp;
|
||||
Bar _playerHealthBar;
|
||||
Bar _playerExpBar;
|
||||
Text _playerHealth;
|
||||
Text _playerExp;
|
||||
Bar _playerHealthBar;
|
||||
Bar _playerExpBar;
|
||||
};
|
||||
|
@ -1,39 +1,40 @@
|
||||
#include "Player.h"
|
||||
#include "Globals.h"
|
||||
#include "../libUnuk/UI/EventHistory.h"
|
||||
#include "../libUnuk/System/Input.h"
|
||||
|
||||
// Pixels * 60 / sec.
|
||||
const float Player::PLAYER_SPEED = Character::CHARACTER_SPEED + 0.5f;
|
||||
const float Player::PLAYER_SPEED = Character::CHARACTER_SPEED + 1.0f;
|
||||
|
||||
// Amount of Exp needed every level
|
||||
const int Player::EXP_TABLE[MAX_LEVEL] = {
|
||||
10,
|
||||
30,
|
||||
90,
|
||||
150,
|
||||
300,
|
||||
512,
|
||||
1000,
|
||||
2000,
|
||||
3500,
|
||||
5000,
|
||||
6500,
|
||||
8500,
|
||||
10250,
|
||||
12000,
|
||||
15000,
|
||||
25000,
|
||||
50000,
|
||||
65000,
|
||||
80000,
|
||||
100000
|
||||
10,
|
||||
30,
|
||||
90,
|
||||
150,
|
||||
300,
|
||||
512,
|
||||
1000,
|
||||
2000,
|
||||
3500,
|
||||
5000,
|
||||
6500,
|
||||
8500,
|
||||
10250,
|
||||
12000,
|
||||
15000,
|
||||
25000,
|
||||
50000,
|
||||
65000,
|
||||
80000,
|
||||
100000
|
||||
};
|
||||
|
||||
Player::Player(LevelGen *mapArg) : Character(mapArg) {
|
||||
_level = 1;
|
||||
_exp = 0;
|
||||
_lastTileX = 0;
|
||||
_lastTileY = 0;
|
||||
_level = 1;
|
||||
_exp = 0;
|
||||
_lastTileX = 0;
|
||||
_lastTileY = 0;
|
||||
}
|
||||
|
||||
Player::~Player(void) {
|
||||
@ -41,108 +42,108 @@ Player::~Player(void) {
|
||||
}
|
||||
|
||||
void Player::HandleInput(void) {
|
||||
if(event.key.type == SDL_KEYDOWN) {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_w:
|
||||
case SDLK_UP:
|
||||
yVel -= PLAYER_SPEED;
|
||||
xVel = 0;
|
||||
directionFacing = FACING_UP;
|
||||
break;
|
||||
case SDLK_s:
|
||||
case SDLK_DOWN:
|
||||
yVel += PLAYER_SPEED;
|
||||
xVel = 0;
|
||||
directionFacing = FACING_DOWN;
|
||||
break;
|
||||
case SDLK_a:
|
||||
case SDLK_LEFT:
|
||||
xVel -= PLAYER_SPEED;
|
||||
yVel = 0;
|
||||
directionFacing = FACING_LEFT;
|
||||
break;
|
||||
case SDLK_d:
|
||||
case SDLK_RIGHT:
|
||||
xVel += PLAYER_SPEED;
|
||||
yVel = 0;
|
||||
directionFacing = FACING_RIGHT;
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
attacking = true;
|
||||
attackTimer.Start();
|
||||
map->GetWorld().OnPlayerAttack(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(event.key.type == SDL_KEYUP) {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_w: case SDLK_UP: yVel = 0; break;
|
||||
case SDLK_s: case SDLK_DOWN: yVel = 0; break;
|
||||
case SDLK_a: case SDLK_LEFT: xVel = 0; break;
|
||||
case SDLK_d: case SDLK_RIGHT: xVel = 0; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else if(event.type == SDL_MOUSEBUTTONDOWN) {
|
||||
if(event.button.button == SDL_BUTTON_LEFT) {
|
||||
attacking = true;
|
||||
attackTimer.Start();
|
||||
map->GetWorld().OnPlayerAttack(this);
|
||||
}
|
||||
}
|
||||
if(event.key.type == SDL_KEYDOWN) {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_w:
|
||||
case SDLK_UP:
|
||||
yVel -= PLAYER_SPEED;
|
||||
xVel = 0;
|
||||
directionFacing = FACING_UP;
|
||||
break;
|
||||
case SDLK_s:
|
||||
case SDLK_DOWN:
|
||||
yVel += PLAYER_SPEED;
|
||||
xVel = 0;
|
||||
directionFacing = FACING_DOWN;
|
||||
break;
|
||||
case SDLK_a:
|
||||
case SDLK_LEFT:
|
||||
xVel -= PLAYER_SPEED;
|
||||
yVel = 0;
|
||||
directionFacing = FACING_LEFT;
|
||||
break;
|
||||
case SDLK_d:
|
||||
case SDLK_RIGHT:
|
||||
xVel += PLAYER_SPEED;
|
||||
yVel = 0;
|
||||
directionFacing = FACING_RIGHT;
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
attacking = true;
|
||||
attackTimer.Start();
|
||||
map->GetWorld().OnPlayerAttack(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(event.key.type == SDL_KEYUP) {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_w: case SDLK_UP: yVel = 0; break;
|
||||
case SDLK_s: case SDLK_DOWN: yVel = 0; break;
|
||||
case SDLK_a: case SDLK_LEFT: xVel = 0; break;
|
||||
case SDLK_d: case SDLK_RIGHT: xVel = 0; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else if(event.type == SDL_MOUSEBUTTONDOWN) {
|
||||
if(event.button.button == SDL_BUTTON_LEFT) {
|
||||
attacking = true;
|
||||
attackTimer.Start();
|
||||
map->GetWorld().OnPlayerAttack(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::Update(void) {
|
||||
Move();
|
||||
//AddSpeachBubble("Woot, My name is Allanis, welcome to my home. Just testing some more text to see if this works..");
|
||||
Move();
|
||||
//AddSpeachBubble("Woot, My name is Allanis, welcome to my home. Just testing some more text to see if this works..");
|
||||
|
||||
// For now The camera will be static.
|
||||
//SetCamera();
|
||||
|
||||
// For now The camera will be static.
|
||||
//SetCamera();
|
||||
|
||||
tileX = x / AStarTile::FAKE_SIZE;
|
||||
tileY = y / AStarTile::FAKE_SIZE;
|
||||
|
||||
if(tileX != _lastTileX || tileY != _lastTileY) {
|
||||
_lastTileX = tileX;
|
||||
_lastTileY = tileY;
|
||||
if(tileX != _lastTileX || tileY != _lastTileY) {
|
||||
_lastTileX = tileX;
|
||||
_lastTileY = tileY;
|
||||
|
||||
map->GetWorld().OnPlayerMove(this);
|
||||
}
|
||||
map->GetWorld().OnPlayerMove(this);
|
||||
}
|
||||
|
||||
_healthBar.SetProgress((float)GetHealth() / 100.0f);
|
||||
_healthBar.SetProgress((float)GetHealth() / 100.0f);
|
||||
}
|
||||
|
||||
void Player::SetName(string nameArg) {
|
||||
_name = nameArg;
|
||||
_name = nameArg;
|
||||
}
|
||||
|
||||
void Player::Move() {
|
||||
map->MoveIfPossible(this, xVel, yVel, true);
|
||||
Character::HealthBarScroll();
|
||||
map->MoveIfPossible(this, xVel, yVel, true);
|
||||
Character::HealthBarScroll();
|
||||
}
|
||||
|
||||
void Player::SetLevel(int level) {
|
||||
_level = level;
|
||||
_exp = _exp - EXP_TABLE[level - 1];
|
||||
if(_exp < 0) {
|
||||
_exp = 0;
|
||||
}
|
||||
if(_level == MAX_LEVEL) {
|
||||
eventHistory->LogEvent("YOU BEAT IT! I'M SO PROUD!");
|
||||
eventHistory->LogEvent("*Sheds Tear*");
|
||||
}
|
||||
_level = level;
|
||||
_exp = _exp - EXP_TABLE[level - 1];
|
||||
if(_exp < 0) {
|
||||
_exp = 0;
|
||||
}
|
||||
if(_level == MAX_LEVEL) {
|
||||
eventHistory->LogEvent("YOU BEAT IT! I'M SO PROUD!");
|
||||
eventHistory->LogEvent("*Sheds Tear*");
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SetExp(int exp) {
|
||||
std::stringstream evtMsg;
|
||||
evtMsg << "Gained " << (exp - _exp) << " Experience Points.";
|
||||
eventHistory->LogEvent(evtMsg.str());
|
||||
std::stringstream evtMsg;
|
||||
evtMsg << "Gained " << (exp - _exp) << " Experience Points.";
|
||||
eventHistory->LogEvent(evtMsg.str());
|
||||
|
||||
_exp = exp;
|
||||
if(_level != MAX_LEVEL && _exp >= EXP_TABLE[_level - 1]) {
|
||||
eventHistory->LogEvent("Player leveled up!");
|
||||
SetLevel(_level + 1);
|
||||
}
|
||||
_exp = exp;
|
||||
if(_level != MAX_LEVEL && _exp >= EXP_TABLE[_level - 1]) {
|
||||
eventHistory->LogEvent("Player leveled up!");
|
||||
SetLevel(_level + 1);
|
||||
}
|
||||
}
|
||||
|
@ -8,41 +8,41 @@
|
||||
|
||||
class Player : public Character {
|
||||
public:
|
||||
Player(LevelGen* mapArg);
|
||||
~Player(void);
|
||||
Player(LevelGen* mapArg);
|
||||
~Player(void);
|
||||
|
||||
void HandleInput(void);
|
||||
void Update(void);
|
||||
void HandleInput(void);
|
||||
void Update(void);
|
||||
|
||||
void SetName(string nameArg);
|
||||
string GetName(void) { return _name; }
|
||||
void SetName(string nameArg);
|
||||
string GetName(void) { return _name; }
|
||||
|
||||
void SetLevel(int level);
|
||||
int GetLevel(void) { return _level; }
|
||||
void SetLevel(int level);
|
||||
int GetLevel(void) { return _level; }
|
||||
|
||||
void SetExp(int exp);
|
||||
int GetExp(void) { return _exp; }
|
||||
void SetExp(int exp);
|
||||
int GetExp(void) { return _exp; }
|
||||
|
||||
void SetLevelLiteral(int level) { _level = level; }
|
||||
void SetExpLiteral(int exp) { _exp = exp; }
|
||||
void SetHealthLiteral(int health) { _health = health; }
|
||||
void SetLevelLiteral(int level) { _level = level; }
|
||||
void SetExpLiteral(int exp) { _exp = exp; }
|
||||
void SetHealthLiteral(int health) { _health = health; }
|
||||
|
||||
void SetXY(float xArg, float yArg) { x = xArg, y = yArg; _lastTileX = xArg / TILE_WIDTH; _lastTileY = yArg / TILE_HEIGHT; }
|
||||
void SetXY(float xArg, float yArg) { x = xArg, y = yArg; _lastTileX = xArg / TILE_WIDTH; _lastTileY = yArg / TILE_HEIGHT; }
|
||||
|
||||
static const int MAX_LEVEL = 20;
|
||||
static const int EXP_TABLE[MAX_LEVEL];
|
||||
static const int MAX_LEVEL = 20;
|
||||
static const int EXP_TABLE[MAX_LEVEL];
|
||||
|
||||
protected:
|
||||
void Move(void);
|
||||
void CheckTileCollisions(void);
|
||||
void Move(void);
|
||||
void CheckTileCollisions(void);
|
||||
|
||||
private:
|
||||
static const float PLAYER_SPEED;
|
||||
static const float PLAYER_SPEED;
|
||||
|
||||
string _name;
|
||||
int _level;
|
||||
int _exp;
|
||||
string _name;
|
||||
int _level;
|
||||
int _exp;
|
||||
|
||||
int _lastTileX;
|
||||
int _lastTileY;
|
||||
int _lastTileX;
|
||||
int _lastTileY;
|
||||
};
|
||||
|
@ -9,7 +9,9 @@
|
||||
#include "../libUnuk/UI/SavegameMenu.h"
|
||||
#include "../libUnuk/Engine/NPC.h"
|
||||
#include "../libUnuk/System/Debug.h"
|
||||
#include "../libUnuk/System/Input.h"
|
||||
#include "../libUnuk/Engine/MemClass.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Globals.h"
|
||||
#include "Game.h"
|
||||
@ -34,24 +36,24 @@ static gameNavVal_t RunGame(bool load) {
|
||||
} else if(savegameMenuRet == savegameMenuCancel) {
|
||||
return gameMainMenu;
|
||||
}
|
||||
|
||||
|
||||
std::stringstream saveFilename;
|
||||
saveFilename << "save_" << savegameMenu.GetSelection();
|
||||
|
||||
Debug::logger->message("Entering game state..");
|
||||
Game* game = new Game;
|
||||
|
||||
if(load) {
|
||||
game->Load(saveFilename.str());
|
||||
} else {
|
||||
game->New(saveFilename.str());
|
||||
}
|
||||
Debug::logger->message("Entering game state..");
|
||||
Game* game = new Game;
|
||||
|
||||
gameNavVal_t ret = game->Run();
|
||||
if(load) {
|
||||
game->Load(saveFilename.str());
|
||||
} else {
|
||||
game->New(saveFilename.str());
|
||||
}
|
||||
|
||||
delete game;
|
||||
gameNavVal_t ret = game->Run();
|
||||
|
||||
return ret;
|
||||
delete game;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) || defined(_DEBUG)
|
||||
@ -60,93 +62,100 @@ int main() {
|
||||
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int) {
|
||||
#endif
|
||||
|
||||
Debug::openLog(true);
|
||||
Debug::logger->message("\n----- Engine Loading -----");
|
||||
Debug::openLog(true);
|
||||
Debug::logger->message("\n----- Engine Loading -----");
|
||||
|
||||
if(SDL_Init(SDL_INIT_VIDEO == -1)) {
|
||||
system("zenity --error --text=\"Could not load SDL\"");
|
||||
Debug::logger->message("Error: Could not load SDL");
|
||||
return 1;
|
||||
} else
|
||||
Debug::logger->message("SDL loaded..");
|
||||
if(SDL_Init(SDL_INIT_VIDEO == -1)) {
|
||||
system("zenity --error --text=\"Could not load SDL\"");
|
||||
Debug::logger->message("Error: Could not load SDL");
|
||||
return 1;
|
||||
} else
|
||||
Debug::logger->message("SDL loaded..");
|
||||
|
||||
if(TTF_Init() == -1) {
|
||||
system("zenity --error --text=\"Could not load SDL_TTF\"");
|
||||
Debug::logger->message("Error: Could not load SDL_TTF");
|
||||
return 1;
|
||||
} else
|
||||
Debug::logger->message("SDL_TTF loaded..");
|
||||
if(TTF_Init() == -1) {
|
||||
system("zenity --error --text=\"Could not load SDL_TTF\"");
|
||||
Debug::logger->message("Error: Could not load SDL_TTF");
|
||||
return 1;
|
||||
} else
|
||||
Debug::logger->message("SDL_TTF loaded..");
|
||||
|
||||
|
||||
|
||||
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_HWSURFACE);
|
||||
Debug::logger->message("Video mode set..");
|
||||
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_HWSURFACE);
|
||||
Debug::logger->message("Video mode set..");
|
||||
|
||||
SDL_WM_SetCaption("fps - 00", NULL);
|
||||
SDL_WM_SetCaption("fps - 00", NULL);
|
||||
|
||||
srand((unsigned int)time(NULL));
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
camera.x = 0;
|
||||
camera.y = 0;
|
||||
camera.w = SCREEN_WIDTH;
|
||||
camera.h = SCREEN_HEIGHT;
|
||||
camera.x = 0;
|
||||
camera.y = 0;
|
||||
camera.w = SCREEN_WIDTH;
|
||||
camera.h = SCREEN_HEIGHT;
|
||||
|
||||
errorTexture = LoadImage("../Data/Media/error.png");
|
||||
errorTexture = LoadImage("../Data/Media/error.png");
|
||||
|
||||
Text::LoadFonts();
|
||||
Text::LoadFonts();
|
||||
|
||||
Debug::logger->message("Creating mainmenu..");
|
||||
MainMenu* menu = new MainMenu;
|
||||
Debug::logger->message("Creating mainmenu..");
|
||||
MainMenu* menu = new MainMenu;
|
||||
|
||||
Debug::logger->message("\n----- Engine Initialization Complete -----");
|
||||
Debug::logger->message("\n----- Logic -----");
|
||||
// Initiate input.
|
||||
Debug::logger->message("Setting up I/O..");
|
||||
CreateInput();
|
||||
|
||||
bool menuRunning = true;
|
||||
while(menuRunning) {
|
||||
switch(menu->Run()) {
|
||||
case mainMenuNewGame:
|
||||
delete menu;
|
||||
switch(RunGame(false)) {
|
||||
case gameMainMenu:
|
||||
menu = new MainMenu;
|
||||
break;
|
||||
case gameQuitGame:
|
||||
menuRunning = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case mainMenuLoadGame:
|
||||
delete menu;
|
||||
switch(RunGame(true)) {
|
||||
case gameMainMenu:
|
||||
menu = new MainMenu;
|
||||
break;
|
||||
case gameQuitGame:
|
||||
menuRunning = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case mainMenuOptions:
|
||||
break;
|
||||
case mainMenuExitGame:
|
||||
menuRunning = false;
|
||||
delete menu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//stringstream caption;
|
||||
//caption << "Unuk - FPS: " << fps;
|
||||
Debug::logger->message("\n----- Engine Initialization Complete -----");
|
||||
Debug::logger->message("\n----- Logic -----");
|
||||
|
||||
//SDL_WM_SetCaption(caption.str().c_str(), NULL);
|
||||
bool menuRunning = true;
|
||||
while(menuRunning) {
|
||||
switch(menu->Run()) {
|
||||
case mainMenuNewGame:
|
||||
delete menu;
|
||||
switch(RunGame(false)) {
|
||||
case gameMainMenu:
|
||||
menu = new MainMenu;
|
||||
break;
|
||||
case gameQuitGame:
|
||||
menuRunning = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case mainMenuLoadGame:
|
||||
delete menu;
|
||||
switch(RunGame(true)) {
|
||||
case gameMainMenu:
|
||||
menu = new MainMenu;
|
||||
break;
|
||||
case gameQuitGame:
|
||||
menuRunning = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case mainMenuOptions:
|
||||
break;
|
||||
case mainMenuExitGame:
|
||||
menuRunning = false;
|
||||
delete menu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up after ourselves.
|
||||
Text::FreeFonts();
|
||||
//stringstream caption;
|
||||
//caption << "Unuk - FPS: " << fps;
|
||||
|
||||
SDL_FreeSurface(screen);
|
||||
SDL_FreeSurface(errorTexture);
|
||||
//SDL_WM_SetCaption(caption.str().c_str(), NULL);
|
||||
|
||||
SDL_Quit();
|
||||
TTF_Quit();
|
||||
// Clean up after ourselves.
|
||||
Text::FreeFonts();
|
||||
|
||||
return 0;
|
||||
SDL_FreeSurface(screen);
|
||||
SDL_FreeSurface(errorTexture);
|
||||
|
||||
DestroyInput();
|
||||
|
||||
SDL_Quit();
|
||||
TTF_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,104 +4,104 @@
|
||||
const float Character::CHARACTER_SPEED = 2.0f;
|
||||
|
||||
Character::Character(LevelGen* mapArg) {
|
||||
map = mapArg;
|
||||
attacking = false;
|
||||
directionFacing = FACING_DOWN;
|
||||
_animationStage = ANIM_NO_FOOT;
|
||||
_animationTimer.Start();
|
||||
_leftFoot = false;
|
||||
_health = 100;
|
||||
map = mapArg;
|
||||
attacking = false;
|
||||
directionFacing = FACING_DOWN;
|
||||
_animationStage = ANIM_NO_FOOT;
|
||||
_animationTimer.Start();
|
||||
_leftFoot = false;
|
||||
_health = 100;
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = 40;
|
||||
w = 40;
|
||||
h = 45;
|
||||
xVel = 0.0f;
|
||||
yVel = 0.0f;
|
||||
|
||||
_texture = NULL;
|
||||
yVel = 0.0f;
|
||||
|
||||
_healthBar.SetBackgroundRGB(0, 0, 0);
|
||||
_healthBar.SetForegroundRGB(255, 0, 0);
|
||||
_texture = NULL;
|
||||
|
||||
_showHealthBar = false;
|
||||
_healthBar.SetBackgroundRGB(0, 0, 0);
|
||||
_healthBar.SetForegroundRGB(255, 0, 0);
|
||||
|
||||
_showHealthBar = false;
|
||||
}
|
||||
|
||||
Character::~Character(void) {
|
||||
SDL_FreeSurface(_texture);
|
||||
SDL_FreeSurface(_texture);
|
||||
}
|
||||
|
||||
void Character::LoadSprites(string filename, int wArg, int hArg) {
|
||||
if(_texture != NULL)
|
||||
SDL_FreeSurface(_texture);
|
||||
if(_texture != NULL)
|
||||
SDL_FreeSurface(_texture);
|
||||
|
||||
_texture = LoadImageAlpha(filename.c_str());
|
||||
_texture = LoadImageAlpha(filename.c_str());
|
||||
|
||||
w = (float)wArg;
|
||||
h = (float)hArg;
|
||||
w = (float)wArg;
|
||||
h = (float)hArg;
|
||||
|
||||
for(int m_direction = 0; m_direction < 4; m_direction++) {
|
||||
for(int m_action = 0; m_action < 4; m_action++) {
|
||||
_sprites[m_direction][m_action].x = (Sint16)(w * m_action);
|
||||
_sprites[m_direction][m_action].y = (Sint16)(h * m_direction);
|
||||
_sprites[m_direction][m_action].w = (Sint16)w;
|
||||
_sprites[m_direction][m_action].h = (Sint16)h;
|
||||
}
|
||||
}
|
||||
for(int m_direction = 0; m_direction < 4; m_direction++) {
|
||||
for(int m_action = 0; m_action < 4; m_action++) {
|
||||
_sprites[m_direction][m_action].x = (Sint16)(w * m_action);
|
||||
_sprites[m_direction][m_action].y = (Sint16)(h * m_direction);
|
||||
_sprites[m_direction][m_action].w = (Sint16)w;
|
||||
_sprites[m_direction][m_action].h = (Sint16)h;
|
||||
}
|
||||
}
|
||||
|
||||
_healthBar.SetWidthHeight((int)w, 10);
|
||||
_healthBar.SetWidthHeight((int)w, 10);
|
||||
}
|
||||
|
||||
void Character::Render(void) {
|
||||
if(attacking && attackTimer.GetTicks() < ATTACKING_DISPLAY_LEN) {
|
||||
ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][ANIM_ATTACK]);
|
||||
return;
|
||||
}
|
||||
else if(attacking)
|
||||
attacking = false;
|
||||
if(attacking && attackTimer.GetTicks() < ATTACKING_DISPLAY_LEN) {
|
||||
ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][ANIM_ATTACK]);
|
||||
return;
|
||||
}
|
||||
else if(attacking)
|
||||
attacking = false;
|
||||
|
||||
if(xVel == 0.0f && yVel == 0.0f)
|
||||
ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][ANIM_NO_FOOT]);
|
||||
else {
|
||||
if(_animationTimer.GetTicks() > ANIMATION_SPEED) {
|
||||
if(_animationStage == ANIM_NO_FOOT) {
|
||||
if(_leftFoot == true)
|
||||
_animationStage = ANIM_RIGHT_FOOT;
|
||||
else
|
||||
_animationStage = ANIM_LEFT_FOOT;
|
||||
}
|
||||
else if(_animationStage == ANIM_LEFT_FOOT) {
|
||||
_animationStage = ANIM_NO_FOOT;
|
||||
_leftFoot = true;
|
||||
}
|
||||
else if(_animationStage == ANIM_RIGHT_FOOT) {
|
||||
_animationStage = ANIM_NO_FOOT;
|
||||
_leftFoot = false;
|
||||
}
|
||||
_animationTimer.Start();
|
||||
}
|
||||
ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][_animationStage]);
|
||||
}
|
||||
if(xVel == 0.0f && yVel == 0.0f)
|
||||
ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][ANIM_NO_FOOT]);
|
||||
else {
|
||||
if(_animationTimer.GetTicks() > ANIMATION_SPEED) {
|
||||
if(_animationStage == ANIM_NO_FOOT) {
|
||||
if(_leftFoot == true)
|
||||
_animationStage = ANIM_RIGHT_FOOT;
|
||||
else
|
||||
_animationStage = ANIM_LEFT_FOOT;
|
||||
}
|
||||
else if(_animationStage == ANIM_LEFT_FOOT) {
|
||||
_animationStage = ANIM_NO_FOOT;
|
||||
_leftFoot = true;
|
||||
}
|
||||
else if(_animationStage == ANIM_RIGHT_FOOT) {
|
||||
_animationStage = ANIM_NO_FOOT;
|
||||
_leftFoot = false;
|
||||
}
|
||||
_animationTimer.Start();
|
||||
}
|
||||
ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][_animationStage]);
|
||||
}
|
||||
|
||||
if(_showHealthBar && (_healthBarDuration.GetTicks() >= 5000)) {
|
||||
_healthBarDuration.Stop();
|
||||
_showHealthBar = false;
|
||||
}
|
||||
if(_showHealthBar && (_healthBarDuration.GetTicks() >= 5000)) {
|
||||
_healthBarDuration.Stop();
|
||||
_showHealthBar = false;
|
||||
}
|
||||
|
||||
if(_showHealthBar) {
|
||||
_healthBar.Draw();
|
||||
}
|
||||
if(_showHealthBar) {
|
||||
_healthBar.Draw();
|
||||
}
|
||||
}
|
||||
|
||||
void Character::Update(void) {
|
||||
_healthBar.SetProgress((float)_health / 100.0f);
|
||||
_healthBar.SetProgress((float)_health / 100.0f);
|
||||
}
|
||||
|
||||
void Character::OnAttack(void) {
|
||||
_healthBarDuration.Start();
|
||||
_showHealthBar = true;
|
||||
_healthBarDuration.Start();
|
||||
_showHealthBar = true;
|
||||
}
|
||||
|
||||
void Character::HealthBarScroll(void) {
|
||||
_healthBar.SetXY((int)x, (int)(y - _healthBar.GetHeight() - 5));
|
||||
_healthBar.SetXY((int)x, (int)(y - _healthBar.GetHeight() - 5));
|
||||
}
|
||||
|
@ -20,99 +20,99 @@ class LevelGen;
|
||||
|
||||
class Character {
|
||||
public:
|
||||
Character(LevelGen* mapArg);
|
||||
~Character(void);
|
||||
Character(LevelGen* mapArg);
|
||||
~Character(void);
|
||||
|
||||
void LoadSprites(string filename, int wArg, int hArg);
|
||||
void LoadSprites(string filename, int wArg, int hArg);
|
||||
|
||||
float GetX(void) { return x; }
|
||||
float GetY(void) { return y; }
|
||||
float GetWidth(void) { return w; }
|
||||
float GetHeight(void) { return h; }
|
||||
float GetX(void) { return x; }
|
||||
float GetY(void) { return y; }
|
||||
float GetWidth(void) { return w; }
|
||||
float GetHeight(void) { return h; }
|
||||
|
||||
void SetXY(float xArg, float yArg) { x = xArg, y = yArg; }
|
||||
void SetXVelocity(float arg) { xVel = arg; }
|
||||
void SetYVelocity(float arg) { yVel = arg; }
|
||||
void SetXY(float xArg, float yArg) { x = xArg, y = yArg; }
|
||||
void SetXVelocity(float arg) { xVel = arg; }
|
||||
void SetYVelocity(float arg) { yVel = arg; }
|
||||
|
||||
void SetHealth(int health) { _health = health; }
|
||||
int GetHealth(void) { return _health; }
|
||||
void SetHealth(int health) { _health = health; }
|
||||
int GetHealth(void) { return _health; }
|
||||
|
||||
int GetDirectionFacing(void) { return directionFacing; }
|
||||
void SetDirectionFacing(int dir) { directionFacing = dir; }
|
||||
int GetDirectionFacing(void) { return directionFacing; }
|
||||
void SetDirectionFacing(int dir) { directionFacing = dir; }
|
||||
|
||||
void Render(void);
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
void Update(void);
|
||||
|
||||
void OnAttack(void);
|
||||
void OnAttack(void);
|
||||
|
||||
// Overload new and delete operators to utilize MemManager.
|
||||
inline void* operator new(size_t size) {
|
||||
return gMemManager.Allocate(size);
|
||||
}
|
||||
// Overload new and delete operators to utilize MemManager.
|
||||
// inline void* operator new(size_t size) {
|
||||
// return gMemManager.Allocate(size);
|
||||
// }
|
||||
|
||||
inline void operator delete(void* object) {
|
||||
gMemManager.Free(object);
|
||||
}
|
||||
// inline void operator delete(void* object) {
|
||||
// gMemManager.Free(object);
|
||||
// }
|
||||
|
||||
inline void* operator new [](size_t size) {
|
||||
return gMemManager.Allocate(size);
|
||||
}
|
||||
// inline void* operator new [](size_t size) {
|
||||
// return gMemManager.Allocate(size);
|
||||
// }
|
||||
|
||||
inline void operator delete [](void* object) {
|
||||
gMemManager.Free(object);
|
||||
}
|
||||
// inline void operator delete [](void* object) {
|
||||
// gMemManager.Free(object);
|
||||
// }
|
||||
|
||||
enum {
|
||||
FACING_UP,
|
||||
FACING_RIGHT,
|
||||
FACING_DOWN,
|
||||
FACING_LEFT
|
||||
};
|
||||
enum {
|
||||
FACING_UP,
|
||||
FACING_RIGHT,
|
||||
FACING_DOWN,
|
||||
FACING_LEFT
|
||||
};
|
||||
|
||||
protected:
|
||||
void HealthBarScroll(void);
|
||||
void HealthBarScroll(void);
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float w;
|
||||
float h;
|
||||
float x;
|
||||
float y;
|
||||
float w;
|
||||
float h;
|
||||
|
||||
float xVel;
|
||||
float yVel;
|
||||
float xVel;
|
||||
float yVel;
|
||||
|
||||
int tileX;
|
||||
int tileY;
|
||||
int tileX;
|
||||
int tileY;
|
||||
|
||||
Timer attackTimer;
|
||||
bool attacking;
|
||||
Timer attackTimer;
|
||||
bool attacking;
|
||||
|
||||
int _health;
|
||||
int _health;
|
||||
|
||||
LevelGen* map;
|
||||
LevelGen* map;
|
||||
|
||||
static const float CHARACTER_SPEED;
|
||||
static const float CHARACTER_SPEED;
|
||||
|
||||
int directionFacing;
|
||||
int directionFacing;
|
||||
|
||||
static const int ANIM_LEFT_FOOT = 0;
|
||||
static const int ANIM_NO_FOOT = 1;
|
||||
static const int ANIM_RIGHT_FOOT = 2;
|
||||
static const int ANIM_ATTACK = 3;
|
||||
static const int ANIM_LEFT_FOOT = 0;
|
||||
static const int ANIM_NO_FOOT = 1;
|
||||
static const int ANIM_RIGHT_FOOT = 2;
|
||||
static const int ANIM_ATTACK = 3;
|
||||
|
||||
Bar _healthBar;
|
||||
Timer _healthBarDuration;
|
||||
bool _showHealthBar;
|
||||
Bar _healthBar;
|
||||
Timer _healthBarDuration;
|
||||
bool _showHealthBar;
|
||||
|
||||
private:
|
||||
static const int ANIMATION_SPEED = 200;
|
||||
static const int ATTACKING_DISPLAY_LEN = 150;
|
||||
static const int ANIMATION_SPEED = 200;
|
||||
static const int ATTACKING_DISPLAY_LEN = 150;
|
||||
|
||||
SDL_Surface* _texture;
|
||||
SDL_Surface* _texture;
|
||||
|
||||
// [direction][action]
|
||||
SDL_Rect _sprites[4][4];
|
||||
// [direction][action]
|
||||
SDL_Rect _sprites[4][4];
|
||||
|
||||
Timer _animationTimer;
|
||||
int _animationStage;
|
||||
bool _leftFoot;
|
||||
Timer _animationTimer;
|
||||
int _animationStage;
|
||||
bool _leftFoot;
|
||||
};
|
||||
|
@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
#include "MemManager.h"
|
||||
|
||||
extern MemManager gMemManager;
|
||||
|
||||
class MemClass {
|
||||
public:
|
||||
MemClass(void) : r(0), c(0) {}
|
||||
MemClass(double a, double b): r(a), c(b) {}
|
||||
|
||||
inline void* operator new(size_t size) {
|
||||
return gMemManager.Allocate(size);
|
||||
}
|
||||
|
||||
inline void operator delete(void* object) {
|
||||
gMemManager.Free(object);
|
||||
}
|
||||
|
||||
inline void* operator new [](size_t size) {
|
||||
return gMemManager.Allocate(size);
|
||||
}
|
||||
|
||||
inline void operator delete [](void* object) {
|
||||
gMemManager.Free(object);
|
||||
}
|
||||
|
||||
private:
|
||||
// Real part.
|
||||
double r;
|
||||
// Complex part.
|
||||
double c;
|
||||
};
|
@ -1,206 +1,535 @@
|
||||
#include "MemClass.h"
|
||||
#include <new>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MemManager.h"
|
||||
|
||||
MemManager gMemManager;
|
||||
|
||||
void BitMapEntry::SetBit(int position, bool flag) {
|
||||
blocksAvailable += flag ? 1 : -1;
|
||||
int elementNo = position / INT_SIZE;
|
||||
int bitNo = position % INT_SIZE;
|
||||
if(flag)
|
||||
bitMap[elementNo] = bitMap[elementNo] | (1 << bitNo);
|
||||
else
|
||||
bitMap[elementNo] = bitMap[elementNo] & ~(1 << bitNo);
|
||||
// This is rather C'ish, it can't really be helped since using new/delete inside allocation
|
||||
// routines would be, well, no fun. This also excludes SDL containers.
|
||||
|
||||
// Don't use this here..
|
||||
#ifdef new
|
||||
#undef new
|
||||
#endif
|
||||
|
||||
// We will dump the report here..
|
||||
const char logFileName[] = "../Bin/MemLeaks.log";
|
||||
|
||||
// Longs are guaranteed to be 2 bits.
|
||||
typedef unsigned long uint32;
|
||||
|
||||
// Identifiers which are placed to allocated buffer (4-byte alignment)
|
||||
const uint32 memPrefix = 0xBAADF00D;
|
||||
const uint32 memPostfix = 0xBABE2BED;
|
||||
const uint32 memNotUsed = 0xDEADC0DE;
|
||||
|
||||
// Identifiers for array / non array allocations / deleted allocations.
|
||||
const uint32 nonArrayAllocation = 0x2BADF00D;
|
||||
const uint32 arrayAllocation = 0xBAD4ACE2;
|
||||
const uint32 invalidAllocation = 0x76543210;
|
||||
|
||||
// Amount. Be careful, this could be a memory overkill.
|
||||
const int numberPrefix = 32; // 128 bytes.
|
||||
const int numberPostfix = 32; // 128 bytes.
|
||||
|
||||
void RemoveMessages(void) {
|
||||
#ifdef _WIN32
|
||||
MSG msg = { 0 };
|
||||
while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
|
||||
if(msg.message == WM_PAINT)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void BitMapEntry::SetMultipleBits(int position, bool flag, int count) {
|
||||
blocksAvailable += flag ? count : -count;
|
||||
int elementNo = position / INT_SIZE;
|
||||
int bitNo = position % INT_SIZE;
|
||||
struct AllocationUnit {
|
||||
// Just for convenience.
|
||||
uint32* prefixPointer;
|
||||
uint32* postfixPointer;
|
||||
uint32* dataPointer;
|
||||
|
||||
int bitSize = (count <= INT_SIZE - bitNo) ? count : INT_SIZE - bitNo;
|
||||
SetRangeOfInt(&bitMap[elementNo], bitNo + bitSize - 1, bitNo, flag);
|
||||
count -= bitSize;
|
||||
if(!count) return;
|
||||
// Size with and withough manager extras.
|
||||
size_t requestedSize;
|
||||
size_t overallSize;
|
||||
|
||||
int i = ++elementNo;
|
||||
while(count >= 0) {
|
||||
if(count <= INT_SIZE) {
|
||||
SetRangeOfInt(&bitMap[i], count - 1, 0, flag);
|
||||
return;
|
||||
} else
|
||||
bitMap[i] = flag ? unsigned (-1) : 0;
|
||||
count -= 32;
|
||||
i++;
|
||||
}
|
||||
// Catches mixing new[]/delete and new/delete[] changed from bool to int
|
||||
// to catch problems with memory blocks allocated without using memory manager.
|
||||
int arrayAllocated;
|
||||
|
||||
// Allocation info which may or may not be present.
|
||||
char* allocatedFrom;
|
||||
|
||||
// Allocation was marked during last snapshot, therfore, it will not be shown
|
||||
// at leak snapshot dump.
|
||||
bool markedSnapshot;
|
||||
};
|
||||
|
||||
AllocationUnit* CreateAllocationUnit(void) {
|
||||
AllocationUnit* unit = static_cast<AllocationUnit*> (malloc(sizeof(AllocationUnit)));
|
||||
|
||||
unit->prefixPointer = 0;
|
||||
unit->postfixPointer = 0;
|
||||
unit->dataPointer = 0;
|
||||
|
||||
unit->requestedSize = 0;
|
||||
unit->overallSize = 0;
|
||||
|
||||
unit->arrayAllocated = nonArrayAllocation;
|
||||
unit->allocatedFrom = 0;
|
||||
|
||||
unit->markedSnapshot = false;
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
||||
void BitMapEntry::SetRangeOfInt(int* element, int msb, int lsb, bool flag) {
|
||||
if(flag) {
|
||||
int mask = (unsigned(-1) << lsb) & (unsigned(-1) >> (INT_SIZE - msb - 1));
|
||||
*element |= mask;
|
||||
} else {
|
||||
int mask = (unsigned(-1) << lsb) & (unsigned(-1) >> (INT_SIZE - msb - 1));
|
||||
*element &= ~mask;
|
||||
}
|
||||
void deleteAllocationUnit(AllocationUnit* unit) {
|
||||
if(unit->allocatedFrom)
|
||||
free(unit->allocatedFrom);
|
||||
if(unit->prefixPointer)
|
||||
free(unit->prefixPointer);
|
||||
unit->arrayAllocated = invalidAllocation;
|
||||
free(unit);
|
||||
}
|
||||
|
||||
MemClass* BitMapEntry::FirstFreeBlock(size_t/* size*/) {
|
||||
for(int i = 0; i < BIT_MAP_ELEMENTS; i++) {
|
||||
if(bitMap[i] == 0)
|
||||
// There aint any bits free.
|
||||
continue;
|
||||
// Allocation information.
|
||||
|
||||
// Yield the first bit position. This is a 1
|
||||
// in an int from the right.
|
||||
int result = bitMap[i] & -(bitMap[i]);
|
||||
//void* address = 0;
|
||||
int basePos = (INT_SIZE * i);
|
||||
struct AllocationLink {
|
||||
AllocationUnit* allocationUnit;
|
||||
AllocationLink* next;
|
||||
};
|
||||
|
||||
switch(result) {
|
||||
// Make the corresponfing bit 0 so block is no longer free.
|
||||
case 0x00000001: return ComplexObjectAddress(basePos + 0);
|
||||
case 0x00000002: return ComplexObjectAddress(basePos + 1);
|
||||
case 0x00000004: return ComplexObjectAddress(basePos + 2);
|
||||
case 0x00000008: return ComplexObjectAddress(basePos + 3);
|
||||
case 0x00000010: return ComplexObjectAddress(basePos + 4);
|
||||
case 0x00000020: return ComplexObjectAddress(basePos + 5);
|
||||
case 0x00000040: return ComplexObjectAddress(basePos + 6);
|
||||
case 0x00000080: return ComplexObjectAddress(basePos + 7);
|
||||
case 0x00000100: return ComplexObjectAddress(basePos + 8);
|
||||
case 0x00000200: return ComplexObjectAddress(basePos + 9);
|
||||
case 0x00000400: return ComplexObjectAddress(basePos + 10);
|
||||
case 0x00000800: return ComplexObjectAddress(basePos + 11);
|
||||
case 0x00001000: return ComplexObjectAddress(basePos + 12);
|
||||
case 0x00002000: return ComplexObjectAddress(basePos + 13);
|
||||
case 0x00004000: return ComplexObjectAddress(basePos + 14);
|
||||
case 0x00008000: return ComplexObjectAddress(basePos + 15);
|
||||
case 0x00010000: return ComplexObjectAddress(basePos + 16);
|
||||
case 0x00020000: return ComplexObjectAddress(basePos + 17);
|
||||
case 0x00040000: return ComplexObjectAddress(basePos + 18);
|
||||
case 0x00080000: return ComplexObjectAddress(basePos + 19);
|
||||
case 0x00100000: return ComplexObjectAddress(basePos + 20);
|
||||
case 0x00200000: return ComplexObjectAddress(basePos + 21);
|
||||
case 0x00400000: return ComplexObjectAddress(basePos + 22);
|
||||
case 0x00800000: return ComplexObjectAddress(basePos + 23);
|
||||
case 0x01000000: return ComplexObjectAddress(basePos + 24);
|
||||
case 0x02000000: return ComplexObjectAddress(basePos + 25);
|
||||
case 0x04000000: return ComplexObjectAddress(basePos + 26);
|
||||
case 0x08000000: return ComplexObjectAddress(basePos + 27);
|
||||
case 0x10000000: return ComplexObjectAddress(basePos + 28);
|
||||
case 0x20000000: return ComplexObjectAddress(basePos + 29);
|
||||
case 0x40000000: return ComplexObjectAddress(basePos + 30);
|
||||
case 0x80000000: return ComplexObjectAddress(basePos + 31);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
struct AllocationRoot {
|
||||
AllocationLink* first;
|
||||
};
|
||||
|
||||
// Hash data.
|
||||
static const int hashSize = 3677; // Prime number. Big enough?
|
||||
static AllocationRoot hashMap[hashSize] = { 0 };
|
||||
|
||||
static int allocationCount = 0; // Amount of allocations.
|
||||
static int allocationMemory = 0; // Memory allocated.
|
||||
|
||||
static int PeakMemoryUsage = 0;
|
||||
static int peakPointers = 0;
|
||||
|
||||
int CalculateHashIndex(const void* buffer) {
|
||||
int value = reinterpret_cast<int> (buffer);
|
||||
// Shift lower bits (alignment would kill coverage).
|
||||
value >>= 4;
|
||||
|
||||
// Create index.
|
||||
value %= hashSize;
|
||||
return value;
|
||||
}
|
||||
|
||||
MemClass* BitMapEntry::ComplexObjectAddress(int pos) {
|
||||
SetBit(pos, false);
|
||||
return &((static_cast<MemClass*>(Head()) + (pos / INT_SIZE)) [INT_SIZE - (pos % INT_SIZE + 1)]);
|
||||
void AddAllocation(AllocationUnit* allocation) {
|
||||
assert(allocation);
|
||||
|
||||
++allocationCount;
|
||||
allocationMemory += allocation->requestedSize;
|
||||
|
||||
AllocationLink* link = static_cast<AllocationLink*> (malloc(sizeof(AllocationLink)));
|
||||
link->allocationUnit = allocation;
|
||||
link->next = 0;
|
||||
|
||||
int hashIndex = CalculateHashIndex(allocation->dataPointer);
|
||||
if(hashMap[hashIndex].first == 0)
|
||||
hashMap[hashIndex].first = link;
|
||||
else {
|
||||
// Push front.
|
||||
link->next = hashMap[hashIndex].first;
|
||||
hashMap[hashIndex].first = link;
|
||||
}
|
||||
|
||||
if(allocationMemory > PeakMemoryUsage)
|
||||
PeakMemoryUsage = allocationMemory;
|
||||
if(allocationCount > peakPointers)
|
||||
peakPointers = allocationCount;
|
||||
}
|
||||
|
||||
void* BitMapEntry::Head(void) {
|
||||
return gMemManager.GetMemoryPoolList()[index];
|
||||
AllocationUnit* FindAllocation(void* pointer) {
|
||||
int hashIndex = CalculateHashIndex(pointer);
|
||||
AllocationLink* current = hashMap[hashIndex].first;
|
||||
|
||||
while(current) {
|
||||
if(current->allocationUnit->dataPointer == pointer)
|
||||
return current->allocationUnit;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
RemoveMessages();
|
||||
assert(!"Allocation not found. Uninitialized pointer?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* MemManager::Allocate(size_t size) {
|
||||
// None array.
|
||||
if(size == sizeof(MemClass)) {
|
||||
set<BitMapEntry*>::iterator freeMapI = _freeMapEntries.begin();
|
||||
if(freeMapI != _freeMapEntries.end()) {
|
||||
BitMapEntry* mapEntry = *freeMapI;
|
||||
return mapEntry->FirstFreeBlock(size);
|
||||
} else {
|
||||
AllocateChunkAndInitBitMap();
|
||||
_freeMapEntries.insert(&(_bitMapEntryList[_bitMapEntryList.size() - 1]));
|
||||
return _bitMapEntryList[_bitMapEntryList.size() - 1].FirstFreeBlock(size);
|
||||
}
|
||||
} else {
|
||||
// Array.
|
||||
if(_arrayMemoryList.empty()) {
|
||||
return AllocateArrayMemory(size);
|
||||
} else {
|
||||
map<void*, ArrayMemoryInfo>::iterator infoI = _arrayMemoryList.begin();
|
||||
map<void*, ArrayMemoryInfo>::iterator infoEndI = _arrayMemoryList.end();
|
||||
void RemoveAllocation(AllocationUnit* allocation) {
|
||||
if(allocationCount <= 0) {
|
||||
RemoveMessages();
|
||||
assert(allocationCount > 0);
|
||||
}
|
||||
|
||||
while(infoI != infoEndI) {
|
||||
ArrayMemoryInfo info = (*infoI).second;
|
||||
if(info.StartPosition != 0)
|
||||
// Only search the memory blocks where allocation
|
||||
// is done from first byte.
|
||||
continue;
|
||||
else {
|
||||
BitMapEntry* entry = &_bitMapEntryList[info.memPoolListIndex];
|
||||
if(entry->blocksAvailable < (size / sizeof(MemClass)))
|
||||
return AllocateArrayMemory(size);
|
||||
else {
|
||||
info.StartPosition = BIT_MAP_SIZE - entry->blocksAvailable;
|
||||
info.Size = size / sizeof(MemClass);
|
||||
MemClass* baseAddress = static_cast<MemClass*>(_memoryPoolList[info.memPoolListIndex]) + info.StartPosition;
|
||||
int hashIndex = CalculateHashIndex(allocation->dataPointer);
|
||||
|
||||
_arrayMemoryList[baseAddress] = info;
|
||||
SetMultipleBlockBits(&info, false);
|
||||
AllocationLink* current = hashMap[hashIndex].first;
|
||||
AllocationLink* previous = 0;
|
||||
|
||||
return baseAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
while(current) {
|
||||
if(current->allocationUnit == allocation) {
|
||||
// Remove.
|
||||
if(previous)
|
||||
previous->next = current->next;
|
||||
else
|
||||
hashMap[hashIndex].first = current->next;
|
||||
|
||||
--allocationCount;
|
||||
allocationMemory -= current->allocationUnit->requestedSize;
|
||||
|
||||
// Free memory.
|
||||
deleteAllocationUnit(current->allocationUnit);
|
||||
free(current);
|
||||
|
||||
return;
|
||||
}
|
||||
previous = current;
|
||||
current = current->next;
|
||||
}
|
||||
RemoveMessages();
|
||||
assert(!"Allocation not found. Uninitialized pointer?");
|
||||
}
|
||||
|
||||
void* MemManager::AllocateArrayMemory(size_t size) {
|
||||
void* chunkAddress = AllocateChunkAndInitBitMap();
|
||||
ArrayMemoryInfo info;
|
||||
info.memPoolListIndex = _memoryPoolList.size() - 1;
|
||||
info.StartPosition = 0;
|
||||
info.Size = size / sizeof(MemClass);
|
||||
_arrayMemoryList[chunkAddress] = info;
|
||||
SetMultipleBlockBits(&info, false);
|
||||
return chunkAddress;
|
||||
void DumpLeakReport(void) {
|
||||
if(allocationCount > 0) {
|
||||
DumpLeakSnapshot(true);
|
||||
} else {
|
||||
// Remove file.
|
||||
fclose(fopen(logFileName, "wt"));
|
||||
}
|
||||
}
|
||||
|
||||
void* MemManager::AllocateChunkAndInitBitMap(void) {
|
||||
BitMapEntry mapEntry;
|
||||
MemClass* memoryBeginAddress = reinterpret_cast<MemClass*>(new char[sizeof(MemClass) * BIT_MAP_SIZE]);
|
||||
_memoryPoolList.push_back(memoryBeginAddress);
|
||||
mapEntry.index = _memoryPoolList.size() - 1;
|
||||
_bitMapEntryList.push_back(mapEntry);
|
||||
return memoryBeginAddress;
|
||||
void TestIdentifiers(AllocationUnit* allocation) {
|
||||
for(int i = 0; i < numberPrefix; ++i) {
|
||||
if(allocation->prefixPointer[i] != memPrefix) {
|
||||
RemoveMessages();
|
||||
assert(!"Buffer prefix messed up!");
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < numberPostfix; ++i) {
|
||||
if(allocation->postfixPointer[i] != memPostfix) {
|
||||
RemoveMessages();
|
||||
assert(!"Buffer postfix messed up!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemManager::Free(void* object) {
|
||||
if(_arrayMemoryList.find(object) == _arrayMemoryList.end())
|
||||
// Simple block deletion.
|
||||
SetBlockBit(object, true);
|
||||
else {
|
||||
// Memory block deletion.
|
||||
ArrayMemoryInfo *info = &_arrayMemoryList[object];
|
||||
SetMultipleBlockBits(info, true);
|
||||
}
|
||||
// After deinitialization, dump leak report on every deallocation.
|
||||
struct InitializationTracker {
|
||||
static bool programExiting;
|
||||
|
||||
InitializationTracker(void) {
|
||||
programExiting = false;
|
||||
}
|
||||
|
||||
~InitializationTracker(void) {
|
||||
programExiting = true;
|
||||
DumpLeakReport();
|
||||
}
|
||||
};
|
||||
|
||||
bool InitializationTracker::programExiting = false;
|
||||
static InitializationTracker tracker;
|
||||
|
||||
void MarkLeakSnapshot(void) {
|
||||
if(allocationCount > 0) {
|
||||
int currentIndex = 0;
|
||||
for(int i = 0; i < hashSize; ++i) {
|
||||
AllocationLink* currentLink = hashMap[i].first;
|
||||
while(currentLink != 0) {
|
||||
currentLink->allocationUnit->markedSnapshot = true;
|
||||
currentLink = currentLink->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemManager::SetBlockBit(void* object, bool flag) {
|
||||
int i = _bitMapEntryList.size() - 1;
|
||||
for(; i >= 0; i--) {
|
||||
BitMapEntry* bitMap = &_bitMapEntryList[i];
|
||||
if((bitMap->Head() <= object) && (&(static_cast<MemClass*>(bitMap->Head()))[BIT_MAP_SIZE - 1] >= object)) {
|
||||
int position = static_cast<MemClass*>(object)- static_cast<MemClass*>(bitMap->Head());
|
||||
bitMap->SetBit(position, flag);
|
||||
flag ? bitMap->blocksAvailable++ : bitMap->blocksAvailable--;
|
||||
}
|
||||
}
|
||||
void DumpLeakSnapshot(bool fromStart) {
|
||||
if(allocationCount > 0) {
|
||||
FILE* fp = fopen(logFileName, "wt");
|
||||
if(fp == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fromStart)
|
||||
fprintf(fp, "(SNAPSHOT)\n\n");
|
||||
fprintf(fp, "Peak memory usage: %d bytes\n", PeakMemoryUsage);
|
||||
fprintf(fp, "Overall memory leaked: %d bytes\n", allocationMemory);
|
||||
fprintf(fp, "Pointers left: %d\n\n", allocationCount);
|
||||
|
||||
int currentIndex = 0;
|
||||
for(int i = 0; i < hashSize; ++i) {
|
||||
AllocationLink* currentLink = hashMap[i].first;
|
||||
while(currentLink != 0) {
|
||||
if(!currentLink->allocationUnit->markedSnapshot || fromStart) {
|
||||
//if(strcmp(currentLink->allocationUnit->allocatedFrom, "(???: line 0)") != 0)
|
||||
if(!strstr(currentLink->allocationUnit->allocatedFrom, "???")) {
|
||||
// Temp: show only over 2MB
|
||||
//if(currentLink->allocationUnit->requestedSize > 1*1024*1024) {
|
||||
fprintf(fp, "Allocation %d:\n", ++currentIndex);
|
||||
fprintf(fp, "\tAllocated from: %s\n", currentLink->allocationUnit->allocatedFrom);
|
||||
fprintf(fp, "\tAllocation size: %d bytes\n", currentLink->allocationUnit->requestedSize);
|
||||
if(currentLink->allocationUnit->arrayAllocated == nonArrayAllocation)
|
||||
fprintf(fp, "\tAllocated with new()\n");
|
||||
else
|
||||
fprintf(fp, "\tAllocated with new[]\n");
|
||||
|
||||
// To get the contents of some char array strings.
|
||||
#define MEMMANAGER_MAX_PRINT_SIZE 80
|
||||
int arraySize = currentLink->allocationUnit->requestedSize;
|
||||
if(currentLink->allocationUnit->arrayAllocated == arrayAllocation && arraySize < MEMMANAGER_MAX_PRINT_SIZE) {
|
||||
char* data = (char*)currentLink->allocationUnit->requestedSize;
|
||||
char databuf[MEMMANAGER_MAX_PRINT_SIZE + 2];
|
||||
bool noControlChars = true;
|
||||
int j;
|
||||
for(j = 0; j < arraySize; j++) {
|
||||
if(data[j] == '\n' || data[j] == '\r')
|
||||
databuf[j] = ' ';
|
||||
else
|
||||
databuf[j] = data[j];
|
||||
if(data[j] < 32 && data[j] != '\n' && data[j] != '\r') {
|
||||
if(data[j] != '\0') noControlChars = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
databuf[j] != '\0';
|
||||
if(noControlChars) {
|
||||
fprintf(fp, "\tData: \"%s\"\n", data);
|
||||
}
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
//}
|
||||
}
|
||||
}
|
||||
currentLink = currentLink->next;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void MemManager::SetMultipleBlockBits(ArrayMemoryInfo* info, bool flag) {
|
||||
BitMapEntry* mapEntry = &_bitMapEntryList[info->memPoolListIndex];
|
||||
mapEntry->SetMultipleBits(info->StartPosition, flag, info->Size);
|
||||
char debugAllocInfo[256 + 1] = { 0 };
|
||||
int debugAllocatedSinceInfo = -1;
|
||||
// Just a hack to add extra info to allocations.
|
||||
void DebugSetAllocationInfo(const char* allocationInfo) {
|
||||
if(allocationInfo == NULL)
|
||||
debugAllocInfo[0] = '\0';
|
||||
else
|
||||
strncpy(debugAllocInfo, allocationInfo, 256);
|
||||
debugAllocatedSinceInfo = 0;
|
||||
}
|
||||
|
||||
vector<void*>& MemManager::GetMemoryPoolList(void) {
|
||||
return _memoryPoolList;
|
||||
// Operator new implementation.
|
||||
void* operator new(size_t originalSize, const char* filename, int lineNumber, bool arrayAllocated) {
|
||||
// Handle 0-byte request. we must return a unique pointer
|
||||
// (or unique value actually).
|
||||
if(originalSize == 0)
|
||||
originalSize = 1;
|
||||
|
||||
// To 4-byte boundary (since our identifiers are unit32's).
|
||||
if(int foo = originalSize % 4)
|
||||
originalSize += 4 - foo;
|
||||
|
||||
// Make some room for prefix and postfix.
|
||||
size_t size = originalSize;
|
||||
size += numberPrefix * 4;
|
||||
size += numberPostfix * 4;
|
||||
|
||||
// Yes, Infinate loop really is the way to go :)
|
||||
while(true) {
|
||||
AllocationUnit* allocation = CreateAllocationUnit();
|
||||
void* buffer = malloc(size);
|
||||
|
||||
// Both have to succeed. We want to handle out-of-memory.
|
||||
if((buffer) && (allocation)) {
|
||||
char* info;
|
||||
if(debugAllocInfo[0] != '\0' && debugAllocatedSinceInfo >= 0) {
|
||||
info = static_cast<char*>(malloc(strlen(filename) + strlen(debugAllocInfo) + 60));
|
||||
if(info) {
|
||||
if(debugAllocatedSinceInfo == 0)
|
||||
sprintf(info, "(%s: line %d)\t Info: \"%s\"", filename, lineNumber, debugAllocInfo);
|
||||
else
|
||||
sprintf(info, "(%s: line %d)\n\tInfo: (\"%s\", %d allocs ago)", filename, lineNumber, debugAllocInfo, debugAllocatedSinceInfo);
|
||||
}
|
||||
} else {
|
||||
info = static_cast<char*> (malloc(strlen(filename) + 20));
|
||||
if(info) {
|
||||
sprintf(info, "(%s: line %d)", filename, lineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in allocation info.
|
||||
allocation->prefixPointer = static_cast<uint32*> (buffer);
|
||||
allocation->dataPointer = allocation->prefixPointer + numberPrefix;
|
||||
allocation->postfixPointer = allocation->dataPointer + (originalSize / 4);
|
||||
|
||||
allocation->allocatedFrom = info;
|
||||
if(arrayAllocated)
|
||||
allocation->arrayAllocated = arrayAllocation;
|
||||
else
|
||||
allocation->arrayAllocated = nonArrayAllocation;
|
||||
allocation->overallSize = size;
|
||||
allocation->requestedSize = originalSize;
|
||||
|
||||
// Fill in our identifiers.
|
||||
for(int i = 0; i < numberPrefix; ++i)
|
||||
allocation->prefixPointer[i] = memPrefix;
|
||||
for(int i = 0; i < int(originalSize / 4); ++i)
|
||||
allocation->dataPointer[i] = memNotUsed;
|
||||
for(int i = 0; i < numberPostfix; ++i)
|
||||
allocation->postfixPointer[i] = memPostfix;
|
||||
|
||||
AddAllocation(allocation);
|
||||
return allocation->dataPointer;
|
||||
}
|
||||
|
||||
// If only one of them succeeded, free it first.
|
||||
if(buffer)
|
||||
free(buffer);
|
||||
if(allocation)
|
||||
deleteAllocationUnit(allocation);
|
||||
|
||||
// Test error-handling functions.
|
||||
std::new_handler globalHandler = std::set_new_handler(0);
|
||||
std::set_new_handler(globalHandler);
|
||||
|
||||
// If we have one, try it. otherwise throw a bad allocation.
|
||||
// (And hope for someone to catch it).
|
||||
if(globalHandler)
|
||||
(*globalHandler) ();
|
||||
else
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
void operator delete(void* buffer, bool arrayDeleted) throw() {
|
||||
// Deleting null-pointer is legal.
|
||||
if(buffer == 0)
|
||||
return;
|
||||
|
||||
AllocationUnit* allocation = FindAllocation(buffer);
|
||||
if(!allocation) {
|
||||
RemoveMessages();
|
||||
assert(allocation);
|
||||
}
|
||||
|
||||
// Test out of bounds.
|
||||
TestIdentifiers(allocation);
|
||||
|
||||
// Test that the block was allocated by memory manager.
|
||||
// Test array operator mixing.
|
||||
if(allocation->arrayAllocated != arrayAllocation && allocation->arrayAllocated != nonArrayAllocation) {
|
||||
RemoveMessages();
|
||||
assert(!"Deleting block with invalid allocation type");
|
||||
} else {
|
||||
if((arrayDeleted && allocation->arrayAllocated == nonArrayAllocation) || (!arrayDeleted && allocation->arrayAllocated == arrayAllocation)) {
|
||||
RemoveMessages();
|
||||
assert(!"Mixed array and normal versions");
|
||||
}
|
||||
}
|
||||
RemoveAllocation(allocation);
|
||||
|
||||
// If quitting, dump report on each deallocation.
|
||||
if(InitializationTracker::programExiting == true)
|
||||
DumpLeakReport();
|
||||
}
|
||||
|
||||
void* operator new(size_t size, const char* filename, int lineNumber) throw(std::bad_alloc) {
|
||||
return operator new(size, filename, lineNumber, false);
|
||||
}
|
||||
void* operator new(size_t size) throw(std::bad_alloc) {
|
||||
return operator new(size, "???", 0, false);
|
||||
}
|
||||
void* operator new[](size_t size, const char* filename, int lineNumber) throw(std::bad_alloc) {
|
||||
return operator new(size, filename, lineNumber, true);
|
||||
}
|
||||
void* operator new[](size_t size) throw(std::bad_alloc) {
|
||||
return operator new(size, "???", 0 , true);
|
||||
}
|
||||
void operator delete(void* buffer) throw() {
|
||||
operator delete(buffer, false);
|
||||
}
|
||||
void operator delete[](void* buffer) throw() {
|
||||
operator delete(buffer, true);
|
||||
}
|
||||
|
||||
void MemManager::SetFailingPercentage(int percentage) {
|
||||
}
|
||||
|
||||
void MemManager::ValidatePointer(void* pointer) {
|
||||
AllocationUnit* allocation = FindAllocation(pointer);
|
||||
if(!allocation) {
|
||||
RemoveMessages();
|
||||
assert(allocation);
|
||||
return;
|
||||
}
|
||||
// Test out-of-bounds.
|
||||
TestIdentifiers(allocation);
|
||||
}
|
||||
|
||||
void MemManager::ValidateAllPointers(void) {
|
||||
for(int i = 0; i < hashSize; ++i) {
|
||||
AllocationLink* currentLink = hashMap[i].first;
|
||||
while(currentLink != 0) {
|
||||
if(currentLink)
|
||||
TestIdentifiers(currentLink->allocationUnit);
|
||||
|
||||
currentLink = currentLink->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MemManager::AmountOfMemoryAllocated(void* pointer, bool includeManagerExtra) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MemManager::AmountOfMemoryInUse(void* pointer) {
|
||||
int result = 0;
|
||||
|
||||
for(int i = 0; i < hashSize; ++i) {
|
||||
AllocationLink* currentLink = hashMap[i].first;
|
||||
while(currentLink != 0) {
|
||||
if(currentLink)
|
||||
result += currentLink->allocationUnit->requestedSize;
|
||||
currentLink = currentLink->next;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MemManager::LogStatistics(const char* filename) {
|
||||
}
|
||||
|
||||
void MemManager::LogUnusedPointers(const char* filename, float freePercentage) {
|
||||
}
|
||||
|
||||
int MemManager::AmountOfMemoryInUse(bool includeManagerExta) {
|
||||
return allocationMemory;
|
||||
}
|
||||
|
||||
int MemManager::AmountOfPeakMemoryInUse(bool includeManagerExtra) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MemManager::AmountOfMemoryAllocations(void) {
|
||||
return allocationCount;
|
||||
}
|
||||
|
||||
int MemManager::AmountOfPeakMemoryAllocations(void) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,88 +1,53 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <bitset>
|
||||
using namespace std;
|
||||
|
||||
const int BIT_MAP_SIZE = 1024;
|
||||
const int INT_SIZE = sizeof(int) * 8;
|
||||
const int BIT_MAP_ELEMENTS = BIT_MAP_SIZE / INT_SIZE;
|
||||
#ifndef INCLUDED_NEW
|
||||
#define INCLUDED_NEW
|
||||
#include <new>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Memory Allocation Pattern.
|
||||
* 11111111 11111111 11111111
|
||||
* 11111110 11111111 11111111
|
||||
* 11111100 11111111 11111111
|
||||
*
|
||||
* If all bits for the first section becomes zero go to next section.
|
||||
*
|
||||
* 00000000 11111111 11111111
|
||||
* 00000000 11111110 11111111
|
||||
* 00000000 11111100 11111111
|
||||
* 00000000 11111000 11111111
|
||||
*
|
||||
* The lookup inside the map becomes 0(1) for the first available free block.
|
||||
*/
|
||||
|
||||
class MemClass;
|
||||
|
||||
typedef struct BitMapEntry {
|
||||
int index;
|
||||
int blocksAvailable;
|
||||
int bitMap[BIT_MAP_SIZE];
|
||||
class MemManager {
|
||||
// Not implemented.
|
||||
MemManager(void);
|
||||
~MemManager(void);
|
||||
|
||||
public:
|
||||
BitMapEntry():blocksAvailable(BIT_MAP_SIZE) {
|
||||
// All blocks are free to begin with and bit value 1
|
||||
// in the map denotes available blocks.
|
||||
memset(bitMap, 0xff, BIT_MAP_SIZE / sizeof(char));
|
||||
}
|
||||
// Affect behavior.
|
||||
static void SetFailingPercentage(int percentage);
|
||||
|
||||
void SetBit(int position, bool flag);
|
||||
void SetMultipleBits(int position, bool flag, int count);
|
||||
void SetRangeOfInt(int* element, int msb, int lsb, bool flag);
|
||||
MemClass* FirstFreeBlock(size_t size);
|
||||
MemClass* ComplexObjectAddress(int pos);
|
||||
void* Head(void);
|
||||
} BitMapEntry;
|
||||
// Pointers.
|
||||
static void ValidatePointer(void* pointer);
|
||||
static void ValidateAllPointers(void);
|
||||
static int AmountOfMemoryAllocated(void* pointer, bool includeManagerExtra = false);
|
||||
static int AmountOfMemoryInUse(void* pointer);
|
||||
|
||||
typedef struct ArrayInfo {
|
||||
int memPoolListIndex;
|
||||
int StartPosition;
|
||||
int Size;
|
||||
} ArrayMemoryInfo;
|
||||
// Logging.
|
||||
static void LogStatistics(const char* filename);
|
||||
static void LogUnusedPointers(const char* filename, float freePercentage);
|
||||
|
||||
class IMemManager {
|
||||
public:
|
||||
virtual void* Allocate(size_t size) = 0;
|
||||
virtual void Free(void* object) = 0;
|
||||
// Memory statistics.
|
||||
static int AmountOfMemoryInUse(bool includeManagerExta = false);
|
||||
static int AmountOfPeakMemoryInUse(bool includeManagerExtra = false);
|
||||
static int AmountOfMemoryAllocations(void);
|
||||
static int AmountOfPeakMemoryAllocations(void);
|
||||
};
|
||||
|
||||
class MemManager : public IMemManager {
|
||||
public:
|
||||
MemManager(void) {}
|
||||
~MemManager(void) {}
|
||||
// Quick hack to get some extra information about allocations.
|
||||
void DebugSetAllocationInfo(const char* allocationInfo);
|
||||
void DumpLeakSnapshot(bool fromStart = false);
|
||||
void MarkLeakSnapshot(void);
|
||||
|
||||
void* Allocate(size_t size);
|
||||
void Free(void* object);
|
||||
vector<void*>& GetMemoryPoolList(void);
|
||||
// Global operators.
|
||||
void* operator new(size_t size, const char* filename, int lineNumber) throw(std::bad_alloc);
|
||||
void* operator new(size_t size) throw(std::bad_alloc);
|
||||
void* operator new[](size_t size, const char* filename, int lineNumber) throw(std::bad_alloc);
|
||||
void* operator new[](size_t size) throw(std::bad_alloc);
|
||||
void operator delete(void* buffer) throw();
|
||||
void operator delete[](void* buffer) throw();
|
||||
|
||||
private:
|
||||
void* AllocateArrayMemory(size_t size);
|
||||
void* AllocateChunkAndInitBitMap(void);
|
||||
void SetBlockBit(void* object, bool flag);
|
||||
void SetMultipleBlockBits(ArrayMemoryInfo* info, bool flag);
|
||||
|
||||
// The following lists will maintain one to one correspondace
|
||||
// and should be the same size.
|
||||
vector<void*> _memoryPoolList;
|
||||
vector<BitMapEntry> _bitMapEntryList;
|
||||
|
||||
set<BitMapEntry*> _freeMapEntries;
|
||||
map<void*, ArrayMemoryInfo> _arrayMemoryList;
|
||||
};
|
||||
// I don't think there are any compilers that don't define these, but just in case.
|
||||
#ifndef __FILE__
|
||||
#define __FILE__ "???"
|
||||
#endif
|
||||
#ifndef __LINE__
|
||||
#define __LINE__ 0
|
||||
#endif
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include "../System/Vec2.h"
|
||||
|
||||
NPC::NPC(LevelGen* mapArg) : Character(mapArg) {
|
||||
_walkInPath = false;
|
||||
_moving = false;
|
||||
_walkInPath = false;
|
||||
_moving = false;
|
||||
}
|
||||
|
||||
NPC::~NPC(void) {
|
||||
@ -12,44 +12,44 @@ NPC::~NPC(void) {
|
||||
}
|
||||
|
||||
void NPC::ForceMove(void) {
|
||||
tileX = x / AStarTile::FAKE_SIZE;
|
||||
tileY = y / AStarTile::FAKE_SIZE;
|
||||
tileX = x / AStarTile::FAKE_SIZE;
|
||||
tileY = y / AStarTile::FAKE_SIZE;
|
||||
}
|
||||
|
||||
void NPC::Update(void) {
|
||||
// Store the NPC's health.
|
||||
// int health = GetHealth(); // not referenced
|
||||
// Store the NPC's health.
|
||||
// int health = GetHealth(); // not referenced
|
||||
|
||||
Move();
|
||||
Move();
|
||||
|
||||
if(xVel > 0) directionFacing = FACING_RIGHT;
|
||||
else if(xVel < 0) directionFacing = FACING_LEFT;
|
||||
else if(yVel > 0) directionFacing = FACING_DOWN;
|
||||
else if(yVel < 0) directionFacing = FACING_UP;
|
||||
if(xVel > 0) directionFacing = FACING_RIGHT;
|
||||
else if(xVel < 0) directionFacing = FACING_LEFT;
|
||||
else if(yVel > 0) directionFacing = FACING_DOWN;
|
||||
else if(yVel < 0) directionFacing = FACING_UP;
|
||||
|
||||
_healthBar.SetProgress((float)GetHealth() / 100.0f);
|
||||
_healthBar.SetProgress((float)GetHealth() / 100.0f);
|
||||
}
|
||||
|
||||
void NPC::Move(void) {
|
||||
xVel = 0.0f;
|
||||
yVel = 0.0f;
|
||||
|
||||
|
||||
Character* player = map->GetPlayer();
|
||||
|
||||
|
||||
SDL_Rect selfRect;
|
||||
selfRect.x = x - 5;
|
||||
selfRect.y = y - 5;
|
||||
selfRect.w = w + 5;
|
||||
selfRect.h = h + 5;
|
||||
|
||||
|
||||
SDL_Rect playerRect;
|
||||
playerRect.x = player->GetX() - 5;
|
||||
playerRect.y = player->GetY() - 5;
|
||||
playerRect.w = player->GetWidth() + 5;
|
||||
playerRect.h = player->GetHeight() + 5;
|
||||
|
||||
|
||||
bool isNearPlayer = CheckCollisionRect(selfRect, playerRect);
|
||||
|
||||
|
||||
if(isNearPlayer) {
|
||||
if(!attackTimer.IsStarted()) {
|
||||
attackTimer.Start();
|
||||
@ -64,30 +64,30 @@ void NPC::Move(void) {
|
||||
attackTimer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Character::HealthBarScroll();
|
||||
|
||||
|
||||
if(!_walkInPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vec2 realPos(x, y);
|
||||
|
||||
|
||||
Vec2 realPos(x, y);
|
||||
|
||||
if(fabs((player->GetX() - x)) > 256 || fabs((player->GetY() - y)) > 256) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(isNearPlayer) {
|
||||
_walkInPath = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
float targetX = (float)(tileX * AStarTile::FAKE_SIZE);
|
||||
float targetY = (float)(tileY * AStarTile::FAKE_SIZE);
|
||||
|
||||
float dx = targetX - realPos.x;
|
||||
float dy = targetY - realPos.y;
|
||||
|
||||
|
||||
if(dx > 0.0f) {
|
||||
xVel = CHARACTER_SPEED;
|
||||
}
|
||||
@ -99,16 +99,16 @@ void NPC::Move(void) {
|
||||
}
|
||||
else if(dy < 0.0f) {
|
||||
yVel = -CHARACTER_SPEED;
|
||||
}
|
||||
|
||||
if(xVel != 0.0f || yVel != 0.0f) {
|
||||
}
|
||||
|
||||
if(xVel != 0.0f || yVel != 0.0f) {
|
||||
map->MoveIfPossible(this, xVel, yVel, false);
|
||||
}
|
||||
|
||||
|
||||
if(dx >= -CHARACTER_SPEED && dx <= CHARACTER_SPEED &&
|
||||
dy >= -CHARACTER_SPEED && dy <= CHARACTER_SPEED) {
|
||||
_target = _astar.GetSolutionNext();
|
||||
|
||||
|
||||
if(_target == NULL || _target == _lastTarget) {
|
||||
_walkInPath = false;
|
||||
} else {
|
||||
@ -122,30 +122,30 @@ void NPC::OnPlayerMove(Player* player) {
|
||||
if(fabs((player->GetX() - x)) > 256 || fabs((player->GetY() - y)) > 256) {
|
||||
return;
|
||||
}
|
||||
|
||||
AStarTile& start = map->GetAStarTile(x / AStarTile::FAKE_SIZE, y / AStarTile::FAKE_SIZE);
|
||||
AStarTile& goal = map->GetAStarTile(player->GetX() / AStarTile::FAKE_SIZE, player->GetY() / AStarTile::FAKE_SIZE);
|
||||
|
||||
_astar.SetStartAndGoalStates(start, goal);
|
||||
AStarTile& start = map->GetAStarTile(x / AStarTile::FAKE_SIZE, y / AStarTile::FAKE_SIZE);
|
||||
AStarTile& goal = map->GetAStarTile(player->GetX() / AStarTile::FAKE_SIZE, player->GetY() / AStarTile::FAKE_SIZE);
|
||||
|
||||
_walkInPath = false;
|
||||
_astar.SetStartAndGoalStates(start, goal);
|
||||
|
||||
while(true) {
|
||||
unsigned int state = _astar.SearchStep();
|
||||
if(state == AStarSearch<AStarTile>::SEARCH_STATE_SUCCEEDED) {
|
||||
_walkInPath = true;
|
||||
break;
|
||||
} else if(state != AStarSearch<AStarTile>::SEARCH_STATE_SEARCHING) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_walkInPath = false;
|
||||
|
||||
while(true) {
|
||||
unsigned int state = _astar.SearchStep();
|
||||
if(state == AStarSearch<AStarTile>::SEARCH_STATE_SUCCEEDED) {
|
||||
_walkInPath = true;
|
||||
break;
|
||||
} else if(state != AStarSearch<AStarTile>::SEARCH_STATE_SEARCHING) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(_walkInPath) {
|
||||
_lastTarget = _astar.GetSolutionEnd();
|
||||
|
||||
|
||||
_target = _astar.GetSolutionStart();
|
||||
_target = _astar.GetSolutionNext();
|
||||
|
||||
|
||||
if(_target == NULL) {
|
||||
_walkInPath = false;
|
||||
_target = NULL;
|
||||
|
@ -9,27 +9,27 @@ class Player;
|
||||
|
||||
class NPC : public Character {
|
||||
public:
|
||||
NPC(LevelGen* mapArg);
|
||||
~NPC(void);
|
||||
NPC(LevelGen* mapArg);
|
||||
~NPC(void);
|
||||
|
||||
void ForceMove(void);
|
||||
void ForceMove(void);
|
||||
void Update(void);
|
||||
|
||||
void OnPlayerMove(Player* player);
|
||||
|
||||
protected:
|
||||
void Move(void);
|
||||
void Move(void);
|
||||
void AttackPlayer(void);
|
||||
|
||||
private:
|
||||
bool _moving;
|
||||
bool _moving;
|
||||
|
||||
AStarSearch<AStarTile> _astar;
|
||||
bool _walkInPath;
|
||||
AStarTile* _target;
|
||||
AStarTile* _lastTarget;
|
||||
|
||||
|
||||
Timer _attackTimer;
|
||||
|
||||
|
||||
static const int ATTACK_FREQUENCY = 1000;
|
||||
};
|
||||
|
@ -9,72 +9,72 @@ ParticleEmitter::~ParticleEmitter(void) {
|
||||
}
|
||||
|
||||
void ParticleEmitter::SetXY(int xArg, int yArg) {
|
||||
x = xArg;
|
||||
y = yArg;
|
||||
x = xArg;
|
||||
y = yArg;
|
||||
}
|
||||
|
||||
void ParticleEmitter::ForceXY(int xArg, int yArg) {
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
m_particle[i].x = (float)xArg;
|
||||
m_particle[i].y = (float)yArg;
|
||||
}
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
m_particle[i].x = (float)xArg;
|
||||
m_particle[i].y = (float)yArg;
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleEmitter::SetParticleCount(int countArg) {
|
||||
_particleCount = countArg;
|
||||
m_particle.resize(_particleCount);
|
||||
_particleCount = countArg;
|
||||
m_particle.resize(_particleCount);
|
||||
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
m_particle[i].startTime = SDL_GetTicks();
|
||||
}
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
m_particle[i].startTime = SDL_GetTicks();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleEmitter::SetParticleSpeed(float speedArg) {
|
||||
_particleSpeed = speedArg;
|
||||
_particleSpeed = speedArg;
|
||||
}
|
||||
|
||||
void ParticleEmitter::SetParticleType(string typeArg) {
|
||||
if(!_particleTexture) {
|
||||
SDL_FreeSurface(_particleTexture);
|
||||
}
|
||||
if(!_particleTexture) {
|
||||
SDL_FreeSurface(_particleTexture);
|
||||
}
|
||||
|
||||
string textureFilename = "../../Data/Media/Images/Particles/" + typeArg + ".png";
|
||||
_particleTexture = LoadImageAlpha(textureFilename.c_str());
|
||||
string textureFilename = "../../Data/Media/Images/Particles/" + typeArg + ".png";
|
||||
_particleTexture = LoadImageAlpha(textureFilename.c_str());
|
||||
}
|
||||
|
||||
void ParticleEmitter::SetParticleLifetime(int lifetimeArg) {
|
||||
_particleLifetime = lifetimeArg;
|
||||
_particleLifetime = lifetimeArg;
|
||||
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
m_particle[i].lifetime = rand() % _particleLifetime + _particleLifetime / 4;
|
||||
}
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
m_particle[i].lifetime = rand() % _particleLifetime + _particleLifetime / 4;
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleEmitter::Render(void) {
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
ApplySurface((int)m_particle[i].x, (int)m_particle[i].y, _particleTexture, screen);
|
||||
}
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
ApplySurface((int)m_particle[i].x, (int)m_particle[i].y, _particleTexture, screen);
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleEmitter::Update(void) {
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
if((int)SDL_GetTicks() - m_particle[i].startTime > m_particle[i].lifetime) {
|
||||
// Reset the x and y coords.
|
||||
m_particle[i].x = (float)x;
|
||||
m_particle[i].y = (float)y;
|
||||
for(int i = 0; i < _particleCount; i++) {
|
||||
if((int)SDL_GetTicks() - m_particle[i].startTime > m_particle[i].lifetime) {
|
||||
// Reset the x and y coords.
|
||||
m_particle[i].x = (float)x;
|
||||
m_particle[i].y = (float)y;
|
||||
|
||||
m_particle[i].xVel = (float)(rand() % 360);
|
||||
m_particle[i].yVel = (float)(rand() % 360);
|
||||
m_particle[i].xVel = (float)(rand() % 360);
|
||||
m_particle[i].yVel = (float)(rand() % 360);
|
||||
|
||||
if(rand() % 2)
|
||||
m_particle[i].xVel = m_particle[i].xVel * -1.0f;
|
||||
if(rand() % 2)
|
||||
m_particle[i].yVel = m_particle[i].yVel * -1.0f;
|
||||
if(rand() % 2)
|
||||
m_particle[i].xVel = m_particle[i].xVel * -1.0f;
|
||||
if(rand() % 2)
|
||||
m_particle[i].yVel = m_particle[i].yVel * -1.0f;
|
||||
|
||||
m_particle[i].startTime = SDL_GetTicks();
|
||||
} else {
|
||||
m_particle[i].x += m_particle[i].xVel * _particleSpeed;
|
||||
m_particle[i].y += m_particle[i].yVel * _particleSpeed;
|
||||
}
|
||||
}
|
||||
m_particle[i].startTime = SDL_GetTicks();
|
||||
} else {
|
||||
m_particle[i].x += m_particle[i].xVel * _particleSpeed;
|
||||
m_particle[i].y += m_particle[i].yVel * _particleSpeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,493 +15,493 @@ using namespace std;
|
||||
// The search class. UserState is the users state space type.
|
||||
template<class UserState> class AStarSearch {
|
||||
public:
|
||||
enum {
|
||||
SEARCH_STATE_NOT_INITIALIZED,
|
||||
SEARCH_STATE_SEARCHING,
|
||||
SEARCH_STATE_SUCCEEDED,
|
||||
SEARCH_STATE_FAILED,
|
||||
SEARCH_STATE_OUT_OF_MEMORY,
|
||||
SEARCH_STATE_INVALID
|
||||
};
|
||||
enum {
|
||||
SEARCH_STATE_NOT_INITIALIZED,
|
||||
SEARCH_STATE_SEARCHING,
|
||||
SEARCH_STATE_SUCCEEDED,
|
||||
SEARCH_STATE_FAILED,
|
||||
SEARCH_STATE_OUT_OF_MEMORY,
|
||||
SEARCH_STATE_INVALID
|
||||
};
|
||||
|
||||
// A node representing a possible state in the search.
|
||||
// A node representing a possible state in the search.
|
||||
public:
|
||||
class Node {
|
||||
public:
|
||||
// Keep a record of successor nodes.
|
||||
Node* parent;
|
||||
// Used to view the search in reverse at the end.
|
||||
Node* child;
|
||||
class Node {
|
||||
public:
|
||||
// Keep a record of successor nodes.
|
||||
Node* parent;
|
||||
// Used to view the search in reverse at the end.
|
||||
Node* child;
|
||||
|
||||
float g; // Cost of this and it's predecessors.
|
||||
float h; // Heuristic estimate of the distance of the goal.
|
||||
float f; // Sum of cost and heuristic.
|
||||
float g; // Cost of this and it's predecessors.
|
||||
float h; // Heuristic estimate of the distance of the goal.
|
||||
float f; // Sum of cost and heuristic.
|
||||
|
||||
Node(UserState userState) : parent(0), child(0), g(0.0f), h(0.0f), f(0.0), _userState(userState) {}
|
||||
Node(UserState userState) : parent(0), child(0), g(0.0f), h(0.0f), f(0.0), _userState(userState) {}
|
||||
|
||||
UserState _userState;
|
||||
};
|
||||
UserState _userState;
|
||||
};
|
||||
|
||||
// Compare the f values of the two nodes.
|
||||
class HeapCompare_f {
|
||||
public:
|
||||
bool operator()(const Node* x, const Node* y) const {
|
||||
return x->f > y->f;
|
||||
}
|
||||
};
|
||||
// Compare the f values of the two nodes.
|
||||
class HeapCompare_f {
|
||||
public:
|
||||
bool operator()(const Node* x, const Node* y) const {
|
||||
return x->f > y->f;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
AStarSearch(void) :
|
||||
_state(SEARCH_STATE_NOT_INITIALIZED),
|
||||
_currentSolutionNode(NULL),
|
||||
_allocateNodeCount(0),
|
||||
_cancelRequest(false) {}
|
||||
AStarSearch(void) :
|
||||
_state(SEARCH_STATE_NOT_INITIALIZED),
|
||||
_currentSolutionNode(NULL),
|
||||
_allocateNodeCount(0),
|
||||
_cancelRequest(false) {}
|
||||
|
||||
~AStarSearch(void) {}
|
||||
~AStarSearch(void) {}
|
||||
|
||||
int GetState(void) { return _state; }
|
||||
int GetState(void) { return _state; }
|
||||
|
||||
// Cancel the search and free up the memory. -- This can be called at any time.
|
||||
void CancelSearch(void) { _cancelRequest = true; }
|
||||
// Cancel the search and free up the memory. -- This can be called at any time.
|
||||
void CancelSearch(void) { _cancelRequest = true; }
|
||||
|
||||
// Set the start/goal state.
|
||||
void SetStartAndGoalStates(UserState& start, UserState& goal) {
|
||||
_cancelRequest= false;
|
||||
// Set the start/goal state.
|
||||
void SetStartAndGoalStates(UserState& start, UserState& goal) {
|
||||
_cancelRequest= false;
|
||||
|
||||
_start = AllocateNode(start);
|
||||
_goal = AllocateNode(goal);
|
||||
_start = AllocateNode(start);
|
||||
_goal = AllocateNode(goal);
|
||||
|
||||
assert((_start != NULL && _goal != NULL));
|
||||
assert((_start != NULL && _goal != NULL));
|
||||
|
||||
_state = SEARCH_STATE_SEARCHING;
|
||||
_state = SEARCH_STATE_SEARCHING;
|
||||
|
||||
// Initialize the AStar specific parts of the start node.
|
||||
// You only need to fill out the state information.
|
||||
_start->g = 0;
|
||||
_start->h = _start->_userState.GoalDistanceEstimate(_goal->_userState);
|
||||
_start->f = _start->g + _start->h;
|
||||
_start->parent = 0;
|
||||
// Initialize the AStar specific parts of the start node.
|
||||
// You only need to fill out the state information.
|
||||
_start->g = 0;
|
||||
_start->h = _start->_userState.GoalDistanceEstimate(_goal->_userState);
|
||||
_start->f = _start->g + _start->h;
|
||||
_start->parent = 0;
|
||||
|
||||
// Push the start node onto the open list.
|
||||
_openList.push_back(_start); // Heap is now unsorted.
|
||||
// Push the start node onto the open list.
|
||||
_openList.push_back(_start); // Heap is now unsorted.
|
||||
|
||||
// Sort back element into the heap.
|
||||
push_heap(_openList.begin(), _openList.end(), HeapCompare_f());
|
||||
// Sort back element into the heap.
|
||||
push_heap(_openList.begin(), _openList.end(), HeapCompare_f());
|
||||
|
||||
// Initialize counter for the search steps.
|
||||
_steps = 0;
|
||||
}
|
||||
// Initialize counter for the search steps.
|
||||
_steps = 0;
|
||||
}
|
||||
|
||||
// Search one step.
|
||||
unsigned int SearchStep(void) {
|
||||
// Break if the search has not been initialized.
|
||||
assert((_state > SEARCH_STATE_NOT_INITIALIZED) && ( _state < SEARCH_STATE_INVALID));
|
||||
// Search one step.
|
||||
unsigned int SearchStep(void) {
|
||||
// Break if the search has not been initialized.
|
||||
assert((_state > SEARCH_STATE_NOT_INITIALIZED) && ( _state < SEARCH_STATE_INVALID));
|
||||
|
||||
// Ensure it is safe to do a seach step once the seach has succeeded.
|
||||
if((_state == SEARCH_STATE_SUCCEEDED) || (_state == SEARCH_STATE_FAILED)) { return false; }
|
||||
// Ensure it is safe to do a seach step once the seach has succeeded.
|
||||
if((_state == SEARCH_STATE_SUCCEEDED) || (_state == SEARCH_STATE_FAILED)) { return false; }
|
||||
|
||||
if(_openList.empty() || _cancelRequest) {
|
||||
// Then there is nothing left to search, so fail.
|
||||
FreeAllNodes();
|
||||
_state = SEARCH_STATE_FAILED;
|
||||
return _state;
|
||||
}
|
||||
if(_openList.empty() || _cancelRequest) {
|
||||
// Then there is nothing left to search, so fail.
|
||||
FreeAllNodes();
|
||||
_state = SEARCH_STATE_FAILED;
|
||||
return _state;
|
||||
}
|
||||
|
||||
_steps++;
|
||||
_steps++;
|
||||
|
||||
// Pop the best node. -- The one with the lowest f.
|
||||
Node* n = _openList.front(); // Get pointer to the node.
|
||||
pop_heap(_openList.begin(), _openList.end(), HeapCompare_f());
|
||||
_openList.pop_back();
|
||||
// Pop the best node. -- The one with the lowest f.
|
||||
Node* n = _openList.front(); // Get pointer to the node.
|
||||
pop_heap(_openList.begin(), _openList.end(), HeapCompare_f());
|
||||
_openList.pop_back();
|
||||
|
||||
// Check for the goal, once we pop that, we are done.
|
||||
if(n->_userState.IsGoal(_goal->_userState)) {
|
||||
// Copy the parent pointer of n, as we will use the passed in goal node.
|
||||
_goal->parent = n->parent;
|
||||
// Check for the goal, once we pop that, we are done.
|
||||
if(n->_userState.IsGoal(_goal->_userState)) {
|
||||
// Copy the parent pointer of n, as we will use the passed in goal node.
|
||||
_goal->parent = n->parent;
|
||||
|
||||
// If the goal was passed in at the start..
|
||||
if(false == n->_userState.IsSameState(_start->_userState)) {
|
||||
FreeNode(n);
|
||||
// If the goal was passed in at the start..
|
||||
if(false == n->_userState.IsSameState(_start->_userState)) {
|
||||
FreeNode(n);
|
||||
|
||||
// Set the child pointers in each node, apart from goal, as it has no child.
|
||||
Node* nodeChild = _goal;
|
||||
Node* nodeParent = _goal->parent;
|
||||
// Set the child pointers in each node, apart from goal, as it has no child.
|
||||
Node* nodeChild = _goal;
|
||||
Node* nodeParent = _goal->parent;
|
||||
|
||||
while(nodeChild != _start) {
|
||||
// Start is always the first node by definition.
|
||||
nodeParent->child = nodeChild;
|
||||
while(nodeChild != _start) {
|
||||
// Start is always the first node by definition.
|
||||
nodeParent->child = nodeChild;
|
||||
|
||||
nodeChild = nodeParent;
|
||||
nodeParent = nodeParent->parent;
|
||||
}
|
||||
}
|
||||
// Delete nodes that are not needed for the solution.
|
||||
FreeUnusedNodes();
|
||||
_state = SEARCH_STATE_SUCCEEDED;
|
||||
nodeChild = nodeParent;
|
||||
nodeParent = nodeParent->parent;
|
||||
}
|
||||
}
|
||||
// Delete nodes that are not needed for the solution.
|
||||
FreeUnusedNodes();
|
||||
_state = SEARCH_STATE_SUCCEEDED;
|
||||
|
||||
return _state;
|
||||
} else {
|
||||
// Not goal.
|
||||
return _state;
|
||||
} else {
|
||||
// Not goal.
|
||||
|
||||
/*
|
||||
* Generate the successors of this node.
|
||||
* The user helps us to do this, and we keep
|
||||
* the new nodes in _successors.
|
||||
*/
|
||||
_successors.clear(); // empty the vector of successor nodes to n.
|
||||
/*
|
||||
* Generate the successors of this node.
|
||||
* The user helps us to do this, and we keep
|
||||
* the new nodes in _successors.
|
||||
*/
|
||||
_successors.clear(); // empty the vector of successor nodes to n.
|
||||
|
||||
// The user provides this functions and uses AddSuccessor to add each
|
||||
// successor of node 'n' to _successors.
|
||||
bool ret = n->_userState.GetSuccessors(this/*, n->parent ? &n->parent->_userState : NULL*/);
|
||||
// The user provides this functions and uses AddSuccessor to add each
|
||||
// successor of node 'n' to _successors.
|
||||
bool ret = n->_userState.GetSuccessors(this/*, n->parent ? &n->parent->_userState : NULL*/);
|
||||
|
||||
if(!ret) {
|
||||
typename vector<Node*>::iterator successor;
|
||||
if(!ret) {
|
||||
typename vector<Node*>::iterator successor;
|
||||
|
||||
// Free the nodes that may have previously been added.
|
||||
for(successor = _successors.begin(); successor != _successors.end(); successor++) {
|
||||
FreeNode((*successor));
|
||||
}
|
||||
// Empty vector of successor nodes nodes to n.
|
||||
_successors.clear();
|
||||
// Free the nodes that may have previously been added.
|
||||
for(successor = _successors.begin(); successor != _successors.end(); successor++) {
|
||||
FreeNode((*successor));
|
||||
}
|
||||
// Empty vector of successor nodes nodes to n.
|
||||
_successors.clear();
|
||||
|
||||
// Free up everything else we allocated along the way.
|
||||
FreeAllNodes();
|
||||
// Free up everything else we allocated along the way.
|
||||
FreeAllNodes();
|
||||
|
||||
_state = SEARCH_STATE_OUT_OF_MEMORY;
|
||||
return _state;
|
||||
}
|
||||
// Now handle each successor to the current node..
|
||||
for(typename vector<Node*>::iterator successor = _successors.begin(); successor != _successors.end(); successor++) {
|
||||
// The g value for this successor.
|
||||
float newg = n->g + n->_userState.GetCost((*successor)->_userState);
|
||||
_state = SEARCH_STATE_OUT_OF_MEMORY;
|
||||
return _state;
|
||||
}
|
||||
// Now handle each successor to the current node..
|
||||
for(typename vector<Node*>::iterator successor = _successors.begin(); successor != _successors.end(); successor++) {
|
||||
// The g value for this successor.
|
||||
float newg = n->g + n->_userState.GetCost((*successor)->_userState);
|
||||
|
||||
/*
|
||||
* We need to see whether the node is on the open or closed
|
||||
* list. If it is, but the node that is already on them is better
|
||||
* (lower g) then we can forget about this successor.
|
||||
*
|
||||
* First linear search of open list to find node.
|
||||
*/
|
||||
typename vector<Node*>::iterator openlist_result;
|
||||
for(openlist_result = _openList.begin(); openlist_result != _openList.end(); openlist_result++) {
|
||||
if((*openlist_result)->_userState.IsSameState((*successor)->_userState)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(openlist_result != _openList.end()) {
|
||||
// We found this state open.
|
||||
if((*openlist_result)->g <= newg) {
|
||||
FreeNode((*successor));
|
||||
// The one on the open list is cheaper than this one.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
typename vector<Node*>::iterator closedlist_result;
|
||||
for(closedlist_result = _closedList.begin(); closedlist_result != _closedList.end(); closedlist_result++) {
|
||||
if((*closedlist_result)->_userState.IsSameState((*successor)->_userState)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(closedlist_result != _closedList.end()) {
|
||||
// We found this state closed.
|
||||
if((*closedlist_result)->g <= newg) {
|
||||
// The one on the closed list is cheaper than this one.
|
||||
FreeNode((*successor));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// This node is the best node so fat with this particular state.
|
||||
// So lets keep it, and set up its AStar specific data..
|
||||
(*successor)->parent = n;
|
||||
(*successor)->g = newg;
|
||||
(*successor)->h = (*successor)->_userState.GoalDistanceEstimate(_goal->_userState);
|
||||
(*successor)->f = (*successor)->g + (*successor)->h;
|
||||
/*
|
||||
* We need to see whether the node is on the open or closed
|
||||
* list. If it is, but the node that is already on them is better
|
||||
* (lower g) then we can forget about this successor.
|
||||
*
|
||||
* First linear search of open list to find node.
|
||||
*/
|
||||
typename vector<Node*>::iterator openlist_result;
|
||||
for(openlist_result = _openList.begin(); openlist_result != _openList.end(); openlist_result++) {
|
||||
if((*openlist_result)->_userState.IsSameState((*successor)->_userState)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(openlist_result != _openList.end()) {
|
||||
// We found this state open.
|
||||
if((*openlist_result)->g <= newg) {
|
||||
FreeNode((*successor));
|
||||
// The one on the open list is cheaper than this one.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
typename vector<Node*>::iterator closedlist_result;
|
||||
for(closedlist_result = _closedList.begin(); closedlist_result != _closedList.end(); closedlist_result++) {
|
||||
if((*closedlist_result)->_userState.IsSameState((*successor)->_userState)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(closedlist_result != _closedList.end()) {
|
||||
// We found this state closed.
|
||||
if((*closedlist_result)->g <= newg) {
|
||||
// The one on the closed list is cheaper than this one.
|
||||
FreeNode((*successor));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// This node is the best node so fat with this particular state.
|
||||
// So lets keep it, and set up its AStar specific data..
|
||||
(*successor)->parent = n;
|
||||
(*successor)->g = newg;
|
||||
(*successor)->h = (*successor)->_userState.GoalDistanceEstimate(_goal->_userState);
|
||||
(*successor)->f = (*successor)->g + (*successor)->h;
|
||||
|
||||
// Remove successor from closed if it was on it.
|
||||
if(closedlist_result != _closedList.end()) {
|
||||
// Remove it from the closed list.
|
||||
FreeNode((*closedlist_result));
|
||||
_closedList.erase(closedlist_result);
|
||||
// Remove successor from closed if it was on it.
|
||||
if(closedlist_result != _closedList.end()) {
|
||||
// Remove it from the closed list.
|
||||
FreeNode((*closedlist_result));
|
||||
_closedList.erase(closedlist_result);
|
||||
|
||||
// Now remake the heap!!
|
||||
make_heap(_openList.begin(), _openList.end(), HeapCompare_f());
|
||||
}
|
||||
// Now remake the heap!!
|
||||
make_heap(_openList.begin(), _openList.end(), HeapCompare_f());
|
||||
}
|
||||
|
||||
// The heap is now unsorted.
|
||||
_openList.push_back((*successor));
|
||||
// The heap is now unsorted.
|
||||
_openList.push_back((*successor));
|
||||
|
||||
// Sort back elements into the heap.
|
||||
push_heap(_openList.begin(), _openList.end(), HeapCompare_f());
|
||||
}
|
||||
// push n onto the closed list as it has now been expanded.
|
||||
_closedList.push_back(n);
|
||||
} // (Not goal, so expand)
|
||||
return _state; // Succeeded bool should be false at this point.
|
||||
}
|
||||
// Sort back elements into the heap.
|
||||
push_heap(_openList.begin(), _openList.end(), HeapCompare_f());
|
||||
}
|
||||
// push n onto the closed list as it has now been expanded.
|
||||
_closedList.push_back(n);
|
||||
} // (Not goal, so expand)
|
||||
return _state; // Succeeded bool should be false at this point.
|
||||
}
|
||||
|
||||
// Call this to add a successor to a list of
|
||||
// successors when expanding the seach frontier.
|
||||
bool AddSuccessor(UserState& state) {
|
||||
Node* node = AllocateNode(state);
|
||||
// Call this to add a successor to a list of
|
||||
// successors when expanding the seach frontier.
|
||||
bool AddSuccessor(UserState& state) {
|
||||
Node* node = AllocateNode(state);
|
||||
|
||||
if(node) {
|
||||
node->_userState = state;
|
||||
_successors.push_back(node);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(node) {
|
||||
node->_userState = state;
|
||||
_successors.push_back(node);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Free the solution nodes.
|
||||
// This is done to clean up all used nodes in memory when you are
|
||||
// done with the search.
|
||||
void FreeSolutionNodes(void) {
|
||||
Node* n = _start;
|
||||
// Free the solution nodes.
|
||||
// This is done to clean up all used nodes in memory when you are
|
||||
// done with the search.
|
||||
void FreeSolutionNodes(void) {
|
||||
Node* n = _start;
|
||||
|
||||
if(_start->child) {
|
||||
while(n != _goal) {
|
||||
Node* del = n;
|
||||
n = n->child;
|
||||
FreeNode(del);
|
||||
if(_start->child) {
|
||||
while(n != _goal) {
|
||||
Node* del = n;
|
||||
n = n->child;
|
||||
FreeNode(del);
|
||||
|
||||
del = NULL;
|
||||
}
|
||||
FreeNode(n); // Delete the goal.
|
||||
} else {
|
||||
// If the start node is the solution, we need to just
|
||||
// delete the start goal nodes.
|
||||
FreeNode(_start);
|
||||
FreeNode(_goal);
|
||||
}
|
||||
}
|
||||
del = NULL;
|
||||
}
|
||||
FreeNode(n); // Delete the goal.
|
||||
} else {
|
||||
// If the start node is the solution, we need to just
|
||||
// delete the start goal nodes.
|
||||
FreeNode(_start);
|
||||
FreeNode(_goal);
|
||||
}
|
||||
}
|
||||
|
||||
// -- Some methods for travelling through the solution. --
|
||||
// -- Some methods for travelling through the solution. --
|
||||
|
||||
// Get the start node.
|
||||
UserState* GetSolutionStart(void) {
|
||||
_currentSolutionNode = _start;
|
||||
if(_start) {
|
||||
return &_start->_userState;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// Get the start node.
|
||||
UserState* GetSolutionStart(void) {
|
||||
_currentSolutionNode = _start;
|
||||
if(_start) {
|
||||
return &_start->_userState;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next node.
|
||||
UserState* GetSolutionNext(void) {
|
||||
if(_currentSolutionNode) {
|
||||
if(_currentSolutionNode->child) {
|
||||
Node* child = _currentSolutionNode->child;
|
||||
_currentSolutionNode = _currentSolutionNode->child;
|
||||
// Get the next node.
|
||||
UserState* GetSolutionNext(void) {
|
||||
if(_currentSolutionNode) {
|
||||
if(_currentSolutionNode->child) {
|
||||
Node* child = _currentSolutionNode->child;
|
||||
_currentSolutionNode = _currentSolutionNode->child;
|
||||
|
||||
return &child->_userState;
|
||||
}
|
||||
}
|
||||
return &child->_userState;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the end node.
|
||||
UserState* GetSolutionEnd(void) {
|
||||
_currentSolutionNode = _goal;
|
||||
if(_goal) {
|
||||
return &_goal->_userState;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// Get the end node.
|
||||
UserState* GetSolutionEnd(void) {
|
||||
_currentSolutionNode = _goal;
|
||||
if(_goal) {
|
||||
return &_goal->_userState;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Step through the solution backwards.
|
||||
UserState* GetSolutionPrev(void) {
|
||||
if(_currentSolutionNode) {
|
||||
if(_currentSolutionNode->parent) {
|
||||
Node* parent = _currentSolutionNode->parent;
|
||||
// Step through the solution backwards.
|
||||
UserState* GetSolutionPrev(void) {
|
||||
if(_currentSolutionNode) {
|
||||
if(_currentSolutionNode->parent) {
|
||||
Node* parent = _currentSolutionNode->parent;
|
||||
|
||||
_currentSolutionNode = _currentSolutionNode->parent;
|
||||
_currentSolutionNode = _currentSolutionNode->parent;
|
||||
|
||||
return &parent->_userState;
|
||||
}
|
||||
}
|
||||
return &parent->_userState;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// It will be useful to be able to view the open
|
||||
// and closed lists at each step for debugging.
|
||||
UserState* GetOpenListStart(void) {
|
||||
float f, g, h;
|
||||
return GetOpenListStart(f, g, h);
|
||||
}
|
||||
// It will be useful to be able to view the open
|
||||
// and closed lists at each step for debugging.
|
||||
UserState* GetOpenListStart(void) {
|
||||
float f, g, h;
|
||||
return GetOpenListStart(f, g, h);
|
||||
}
|
||||
|
||||
UserState* GetOpenListStart(float& f, float& g, float& h) {
|
||||
iterDbgOpen = _openList.begin();
|
||||
if(iterDbgOpen != _openList.end()) {
|
||||
f = (*iterDbgOpen)->f;
|
||||
g = (*iterDbgOpen)->g;
|
||||
h = (*iterDbgOpen)->h;
|
||||
return &(*iterDbgOpen)->_userState;
|
||||
}
|
||||
UserState* GetOpenListStart(float& f, float& g, float& h) {
|
||||
iterDbgOpen = _openList.begin();
|
||||
if(iterDbgOpen != _openList.end()) {
|
||||
f = (*iterDbgOpen)->f;
|
||||
g = (*iterDbgOpen)->g;
|
||||
h = (*iterDbgOpen)->h;
|
||||
return &(*iterDbgOpen)->_userState;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UserState* GetOpenListNext(void) {
|
||||
float f, g, h;
|
||||
return GetOpenListNext(f, g, h);
|
||||
}
|
||||
UserState* GetOpenListNext(void) {
|
||||
float f, g, h;
|
||||
return GetOpenListNext(f, g, h);
|
||||
}
|
||||
|
||||
UserState* GetOpenListNext(float& f, float& g, float& h) {
|
||||
iterDbgOpen++;
|
||||
if(iterDbgOpen != _openList.end()) {
|
||||
f = (*iterDbgOpen)->f;
|
||||
g = (*iterDbgOpen)->g;
|
||||
h = (*iterDbgOpen)->h;
|
||||
return &(*iterDbgOpen)->_userState;
|
||||
}
|
||||
UserState* GetOpenListNext(float& f, float& g, float& h) {
|
||||
iterDbgOpen++;
|
||||
if(iterDbgOpen != _openList.end()) {
|
||||
f = (*iterDbgOpen)->f;
|
||||
g = (*iterDbgOpen)->g;
|
||||
h = (*iterDbgOpen)->h;
|
||||
return &(*iterDbgOpen)->_userState;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Closes states.
|
||||
UserState* GetClosedListStart(void) {
|
||||
float f, g, h;
|
||||
return GetClosedListStart(f, g, h);
|
||||
}
|
||||
// Closes states.
|
||||
UserState* GetClosedListStart(void) {
|
||||
float f, g, h;
|
||||
return GetClosedListStart(f, g, h);
|
||||
}
|
||||
|
||||
UserState* GetClosedListStart(float& f, float& g, float& h) {
|
||||
iterDbgClosed = _closedList.begin();
|
||||
if(iterDbgClosed != _closedList.begin()) {
|
||||
f = (*iterDbgClosed)->f;
|
||||
g = (*iterDbgClosed)->g;
|
||||
h = (*iterDbgClosed)->h;
|
||||
return &(iterDbgClosed)->_userState;
|
||||
}
|
||||
UserState* GetClosedListStart(float& f, float& g, float& h) {
|
||||
iterDbgClosed = _closedList.begin();
|
||||
if(iterDbgClosed != _closedList.begin()) {
|
||||
f = (*iterDbgClosed)->f;
|
||||
g = (*iterDbgClosed)->g;
|
||||
h = (*iterDbgClosed)->h;
|
||||
return &(iterDbgClosed)->_userState;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UserState* GetClosedListNext(void) {
|
||||
float f, g, h;
|
||||
return GetClosedListNext(f, g, h);
|
||||
}
|
||||
UserState* GetClosedListNext(void) {
|
||||
float f, g, h;
|
||||
return GetClosedListNext(f, g, h);
|
||||
}
|
||||
|
||||
UserState* GetClosedListNext(float& f, float& g, float& h) {
|
||||
iterDbgClosed++;
|
||||
if(iterDbgClosed != _closedList.end()) {
|
||||
f = (*iterDbgClosed)->f;
|
||||
g = (*iterDbgClosed)->g;
|
||||
h = (*iterDbgClosed)->h;
|
||||
return &(*iterDbgClosed)->_userState;
|
||||
}
|
||||
UserState* GetClosedListNext(float& f, float& g, float& h) {
|
||||
iterDbgClosed++;
|
||||
if(iterDbgClosed != _closedList.end()) {
|
||||
f = (*iterDbgClosed)->f;
|
||||
g = (*iterDbgClosed)->g;
|
||||
h = (*iterDbgClosed)->h;
|
||||
return &(*iterDbgClosed)->_userState;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the number of steps.
|
||||
int GetStepCount(void) {return _steps; }
|
||||
// Get the number of steps.
|
||||
int GetStepCount(void) {return _steps; }
|
||||
|
||||
private:
|
||||
// Called when a search fails or is cancelled to free up all unused memory.
|
||||
void FreeAllNodes(void) {
|
||||
// Iterate the open list and delete all nodes.
|
||||
typename vector<Node*>::iterator iterOpen = _openList.begin();
|
||||
// Called when a search fails or is cancelled to free up all unused memory.
|
||||
void FreeAllNodes(void) {
|
||||
// Iterate the open list and delete all nodes.
|
||||
typename vector<Node*>::iterator iterOpen = _openList.begin();
|
||||
|
||||
while(iterOpen != _openList.end()) {
|
||||
Node* n = (*iterOpen);
|
||||
FreeNode(n);
|
||||
while(iterOpen != _openList.end()) {
|
||||
Node* n = (*iterOpen);
|
||||
FreeNode(n);
|
||||
|
||||
iterOpen++;
|
||||
}
|
||||
iterOpen++;
|
||||
}
|
||||
|
||||
_openList.clear();
|
||||
_openList.clear();
|
||||
|
||||
// Iterate closed list and delete unused nodes.
|
||||
typename vector<Node*>::iterator iterClosed;
|
||||
// Iterate closed list and delete unused nodes.
|
||||
typename vector<Node*>::iterator iterClosed;
|
||||
|
||||
for(iterClosed = _closedList.begin(); iterClosed != _closedList.end(); iterClosed++) {
|
||||
Node* n = (*iterClosed);
|
||||
FreeNode(n);
|
||||
}
|
||||
for(iterClosed = _closedList.begin(); iterClosed != _closedList.end(); iterClosed++) {
|
||||
Node* n = (*iterClosed);
|
||||
FreeNode(n);
|
||||
}
|
||||
|
||||
_closedList.clear();
|
||||
_closedList.clear();
|
||||
|
||||
// Delete the goal.
|
||||
FreeNode(_goal);
|
||||
}
|
||||
// Delete the goal.
|
||||
FreeNode(_goal);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when the search ends. A lot of nodes may
|
||||
* be created that are still present when the search
|
||||
* ends. They will be deleted with this method.
|
||||
*/
|
||||
void FreeUnusedNodes(void) {
|
||||
// Iterate open list and delete unused nodes.
|
||||
typename vector<Node*>::iterator iterOpen = _openList.begin();
|
||||
/*
|
||||
* Called when the search ends. A lot of nodes may
|
||||
* be created that are still present when the search
|
||||
* ends. They will be deleted with this method.
|
||||
*/
|
||||
void FreeUnusedNodes(void) {
|
||||
// Iterate open list and delete unused nodes.
|
||||
typename vector<Node*>::iterator iterOpen = _openList.begin();
|
||||
|
||||
while(iterOpen != _openList.end()) {
|
||||
Node *n = (*iterOpen);
|
||||
while(iterOpen != _openList.end()) {
|
||||
Node *n = (*iterOpen);
|
||||
|
||||
if(!n->child) {
|
||||
FreeNode(n);
|
||||
n = NULL;
|
||||
}
|
||||
if(!n->child) {
|
||||
FreeNode(n);
|
||||
n = NULL;
|
||||
}
|
||||
|
||||
iterOpen++;
|
||||
}
|
||||
iterOpen++;
|
||||
}
|
||||
|
||||
_openList.clear();
|
||||
_openList.clear();
|
||||
|
||||
// Iterate closed list and delete all unused nodes.
|
||||
typename vector<Node*>::iterator iterClosed;
|
||||
// Iterate closed list and delete all unused nodes.
|
||||
typename vector<Node*>::iterator iterClosed;
|
||||
|
||||
for(iterClosed = _closedList.begin(); iterClosed != _closedList.end(); iterClosed++) {
|
||||
Node *n = (*iterClosed);
|
||||
for(iterClosed = _closedList.begin(); iterClosed != _closedList.end(); iterClosed++) {
|
||||
Node *n = (*iterClosed);
|
||||
|
||||
if(!n->child) {
|
||||
FreeNode(n);
|
||||
n = NULL;
|
||||
}
|
||||
}
|
||||
if(!n->child) {
|
||||
FreeNode(n);
|
||||
n = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_closedList.clear();
|
||||
_closedList.clear();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Node* AllocateNode(UserState& userState) {
|
||||
Node *p = new Node(userState);
|
||||
return p;
|
||||
}
|
||||
Node* AllocateNode(UserState& userState) {
|
||||
Node *p = new Node(userState);
|
||||
return p;
|
||||
}
|
||||
|
||||
void FreeNode(Node* node) {
|
||||
_allocateNodeCount--;
|
||||
delete node;
|
||||
}
|
||||
void FreeNode(Node* node) {
|
||||
_allocateNodeCount--;
|
||||
delete node;
|
||||
}
|
||||
|
||||
// Data.
|
||||
// Data.
|
||||
private:
|
||||
// Heap.
|
||||
vector<Node*> _openList;
|
||||
vector<Node*> _closedList;
|
||||
vector<Node*> _successors;
|
||||
// Heap.
|
||||
vector<Node*> _openList;
|
||||
vector<Node*> _closedList;
|
||||
vector<Node*> _successors;
|
||||
|
||||
// State.
|
||||
unsigned int _state;
|
||||
// State.
|
||||
unsigned int _state;
|
||||
|
||||
// Count steps.
|
||||
int _steps;
|
||||
// Count steps.
|
||||
int _steps;
|
||||
|
||||
// Start/Goal state pointers.
|
||||
Node* _start;
|
||||
Node* _goal;
|
||||
// Start/Goal state pointers.
|
||||
Node* _start;
|
||||
Node* _goal;
|
||||
|
||||
Node* _currentSolutionNode;
|
||||
Node* _currentSolutionNode;
|
||||
|
||||
// Debug
|
||||
typename vector<Node*>::iterator iterDbgOpen;
|
||||
typename vector<Node*>::iterator iterDbgClosed;
|
||||
// Debug
|
||||
typename vector<Node*>::iterator iterDbgOpen;
|
||||
typename vector<Node*>::iterator iterDbgClosed;
|
||||
|
||||
// Count memory allocations and free.
|
||||
int _allocateNodeCount;
|
||||
// Count memory allocations and free.
|
||||
int _allocateNodeCount;
|
||||
|
||||
bool _cancelRequest;
|
||||
bool _cancelRequest;
|
||||
};
|
||||
|
@ -13,5 +13,5 @@ void Spells::CastSpell() {
|
||||
}
|
||||
|
||||
void Spells::Render(void) {
|
||||
//_particle->Render();
|
||||
//_particle->Render();
|
||||
}
|
||||
|
@ -5,18 +5,18 @@
|
||||
|
||||
class Spells {
|
||||
public:
|
||||
Spells(void);
|
||||
~Spells(void);
|
||||
Spells(void);
|
||||
~Spells(void);
|
||||
|
||||
enum {
|
||||
FIREBALL,
|
||||
ICE
|
||||
};
|
||||
enum {
|
||||
FIREBALL,
|
||||
ICE
|
||||
};
|
||||
|
||||
void CastSpell(/*Player* player*/);
|
||||
void Render(void);
|
||||
void CastSpell(/*Player* player*/);
|
||||
void Render(void);
|
||||
|
||||
private:
|
||||
Timer* _timeBetweenCast;
|
||||
ParticleEmitter* _particle;
|
||||
Timer* _timeBetweenCast;
|
||||
ParticleEmitter* _particle;
|
||||
};
|
||||
|
@ -5,190 +5,190 @@
|
||||
#include "../UI/EventHistory.h"
|
||||
|
||||
WorldManager::WorldManager(LevelGen* level) {
|
||||
_level = level;
|
||||
_level = level;
|
||||
}
|
||||
|
||||
WorldManager::~WorldManager(void) {
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
delete npc;
|
||||
}
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
delete npc;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldManager::Update(void) {
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
npc->Update();
|
||||
}
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
npc->Update();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldManager::Render(void) {
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
npc->Render();
|
||||
}
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
npc->Render();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldManager::AddNPC(NPC* npc) {
|
||||
_npcs.push_back(npc);
|
||||
_npcs.push_back(npc);
|
||||
}
|
||||
|
||||
void WorldManager::RemoveNPC(int index) {
|
||||
int npcsIndex = 0;
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
if(npcsIndex == index) {
|
||||
_npcs.erase(i);
|
||||
delete npc;
|
||||
}
|
||||
npcsIndex++;
|
||||
}
|
||||
int npcsIndex = 0;
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
if(npcsIndex == index) {
|
||||
_npcs.erase(i);
|
||||
delete npc;
|
||||
}
|
||||
npcsIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
NPC* WorldManager::GetNPC(int index) {
|
||||
int npcsIndex = 0;
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
if(npcsIndex == index) {
|
||||
return npc;
|
||||
}
|
||||
npcsIndex++;
|
||||
}
|
||||
return NULL;
|
||||
int npcsIndex = 0;
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
if(npcsIndex == index) {
|
||||
return npc;
|
||||
}
|
||||
npcsIndex++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NPC* WorldManager::GetNPCAt(int xArg, int yArg) {
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
if(xArg >= npc->GetX() && xArg <= (npc->GetX() + npc->GetWidth()) &&
|
||||
yArg >= npc->GetY() && yArg <= (npc->GetY() + npc->GetHeight())) {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
if(xArg >= npc->GetX() && xArg <= (npc->GetX() + npc->GetWidth()) &&
|
||||
yArg >= npc->GetY() && yArg <= (npc->GetY() + npc->GetHeight())) {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void WorldManager::CreateNPC(int x, int y) {
|
||||
NPC* npc = new NPC(_level);
|
||||
npc->SetXY(x, y);
|
||||
NPC* npc = new NPC(_level);
|
||||
npc->SetXY(x, y);
|
||||
npc->ForceMove();
|
||||
npc->LoadSprites("../Data/Media/Images/Characters/template.png", 40,45);
|
||||
_npcs.push_back(npc);
|
||||
npc->LoadSprites("../Data/Media/Images/Characters/template.png", 40,45);
|
||||
_npcs.push_back(npc);
|
||||
}
|
||||
|
||||
bool WorldManager::CheckCollision(const SDL_Rect& charRect, Character* exclude) {
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
NPC* npc = (*i);
|
||||
|
||||
if(npc == exclude) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(npc == exclude) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SDL_Rect npcRect;
|
||||
npcRect.x = npc->GetX();
|
||||
npcRect.y = npc->GetY()/* + (npc->GetHeight() / 4) * 3*/;
|
||||
npcRect.w = npc->GetWidth();
|
||||
npcRect.h = npc->GetHeight()/* / 4*/;
|
||||
|
||||
if(CheckCollisionRect(npcRect, charRect)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if(CheckCollisionRect(npcRect, charRect)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WorldManager::OnPlayerAttack(Player* player) {
|
||||
int playerX = (int)(player->GetX() / 32.0f);
|
||||
int playerY = (int)(player->GetY() / 32.0f);
|
||||
int playerDir = player->GetDirectionFacing();
|
||||
int playerX = (int)(player->GetX() / 32.0f);
|
||||
int playerY = (int)(player->GetY() / 32.0f);
|
||||
int playerDir = player->GetDirectionFacing();
|
||||
|
||||
std::list<NPC*>::iterator i = _npcs.begin();
|
||||
std::list<NPC*>::iterator i = _npcs.begin();
|
||||
|
||||
while(i != _npcs.end()) {
|
||||
NPC* npc = (*i);
|
||||
while(i != _npcs.end()) {
|
||||
NPC* npc = (*i);
|
||||
|
||||
int npcX = (int)(npc->GetX() / 32.0f);
|
||||
int npcY = (int)(npc->GetY() / 32.0f);
|
||||
int npcX = (int)(npc->GetX() / 32.0f);
|
||||
int npcY = (int)(npc->GetY() / 32.0f);
|
||||
|
||||
int diffX = npcX - playerX;
|
||||
int diffY = npcY - playerY;
|
||||
int diffX = npcX - playerX;
|
||||
int diffY = npcY - playerY;
|
||||
|
||||
// Not in player's line of sight.
|
||||
if(diffX != 0 && diffY != 0) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
// Not in player's line of sight.
|
||||
if(diffX != 0 && diffY != 0) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Distance is greater than 2.
|
||||
if(abs(diffX) > 2 || abs(diffY) > 2) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
// Distance is greater than 2.
|
||||
if(abs(diffX) > 2 || abs(diffY) > 2) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Player not facing the npc.
|
||||
if((diffX < 0 && playerDir != Character::FACING_LEFT) ||
|
||||
(diffX > 0 && playerDir != Character::FACING_RIGHT) ||
|
||||
(diffY < 0 && playerDir != Character::FACING_UP) ||
|
||||
(diffY > 0 && playerDir != Character::FACING_DOWN))
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
// Player not facing the npc.
|
||||
if((diffX < 0 && playerDir != Character::FACING_LEFT) ||
|
||||
(diffX > 0 && playerDir != Character::FACING_RIGHT) ||
|
||||
(diffY < 0 && playerDir != Character::FACING_UP) ||
|
||||
(diffY > 0 && playerDir != Character::FACING_DOWN))
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
npc->SetHealth(npc->GetHealth() - 20);
|
||||
npc->OnAttack();
|
||||
npc->SetHealth(npc->GetHealth() - 20);
|
||||
npc->OnAttack();
|
||||
|
||||
if(npc->GetHealth() <= 0) {
|
||||
if(npc->GetHealth() <= 0) {
|
||||
|
||||
// Please note:
|
||||
// Naked dudes are known to be sensitive to spicy food.
|
||||
// Please note:
|
||||
// Naked dudes are known to be sensitive to spicy food.
|
||||
|
||||
std::string waysOfDeath[] = {
|
||||
"Choked Naked Dude!",
|
||||
"Stabbed Naked Dude!",
|
||||
"Urinated Acid on Naked Dude!",
|
||||
"Killed Naked Dude with a dildo!",
|
||||
"Poured Tabasco on Naked Dude!",
|
||||
"Threw Acid on Naked Dude!",
|
||||
"Slapped Naked Dude with Dead Fish!",
|
||||
"Killed Naked Dude with a Pistol!",
|
||||
"Ate Naked Dude's brain!",
|
||||
"Slaughtered Naked Dude!",
|
||||
"Roasted Naked Dude!",
|
||||
"Pepper Sprayed Naked Dude!",
|
||||
"Stoned Naked Dude!",
|
||||
"Slayed Naked Dude with a Katana!",
|
||||
"Threw Chili Peppers on Naked Dude!",
|
||||
"Used Karate on Naked Dude!",
|
||||
"Beat the shit out of Naked Dude!",
|
||||
"FUS RO DAH!"
|
||||
};
|
||||
std::string waysOfDeath[] = {
|
||||
"Choked Naked Dude!",
|
||||
"Stabbed Naked Dude!",
|
||||
"Urinated Acid on Naked Dude!",
|
||||
"Killed Naked Dude with a dildo!",
|
||||
"Poured Tabasco on Naked Dude!",
|
||||
"Threw Acid on Naked Dude!",
|
||||
"Slapped Naked Dude with Dead Fish!",
|
||||
"Killed Naked Dude with a Pistol!",
|
||||
"Ate Naked Dude's brain!",
|
||||
"Slaughtered Naked Dude!",
|
||||
"Roasted Naked Dude!",
|
||||
"Pepper Sprayed Naked Dude!",
|
||||
"Stoned Naked Dude!",
|
||||
"Slayed Naked Dude with a Katana!",
|
||||
"Threw Chili Peppers on Naked Dude!",
|
||||
"Used Karate on Naked Dude!",
|
||||
"Beat the shit out of Naked Dude!",
|
||||
"FUS RO DAH!"
|
||||
};
|
||||
|
||||
eventHistory->LogEvent(waysOfDeath[rand() % (sizeof(waysOfDeath)/sizeof(std::string))]);
|
||||
eventHistory->LogEvent(waysOfDeath[rand() % (sizeof(waysOfDeath)/sizeof(std::string))]);
|
||||
|
||||
int expGain = 3 + (rand() % 2);
|
||||
player->SetExp(player->GetExp() + expGain);
|
||||
int expGain = 3 + (rand() % 2);
|
||||
player->SetExp(player->GetExp() + expGain);
|
||||
|
||||
i = _npcs.erase(i);
|
||||
delete npc;
|
||||
i = _npcs.erase(i);
|
||||
delete npc;
|
||||
|
||||
if(_npcs.empty()) {
|
||||
_level->New();
|
||||
if(_npcs.empty()) {
|
||||
_level->New();
|
||||
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
_level->FindSpawnPoint(spawnX, spawnY, player->GetWidth(),player->GetHeight());
|
||||
player->SetXY(spawnX, spawnY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
_level->FindSpawnPoint(spawnX, spawnY, player->GetWidth(),player->GetHeight());
|
||||
player->SetXY(spawnX, spawnY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldManager::OnPlayerMove(Player* player) {
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
(*i)->OnPlayerMove(player);
|
||||
}
|
||||
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||
(*i)->OnPlayerMove(player);
|
||||
}
|
||||
}
|
||||
|
@ -10,26 +10,26 @@ class LevelGen;
|
||||
|
||||
class WorldManager {
|
||||
public:
|
||||
WorldManager(LevelGen* level);
|
||||
~WorldManager(void);
|
||||
WorldManager(LevelGen* level);
|
||||
~WorldManager(void);
|
||||
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
|
||||
void AddNPC(NPC* npc);
|
||||
void RemoveNPC(int index);
|
||||
NPC* GetNPC(int index);
|
||||
NPC* GetNPCAt(int xArg, int yArg);
|
||||
void CreateNPC(int x, int y);
|
||||
void AddNPC(NPC* npc);
|
||||
void RemoveNPC(int index);
|
||||
NPC* GetNPC(int index);
|
||||
NPC* GetNPCAt(int xArg, int yArg);
|
||||
void CreateNPC(int x, int y);
|
||||
|
||||
bool CheckCollision(const SDL_Rect& charRect, Character* exclude);
|
||||
bool CheckCollision(const SDL_Rect& charRect, Character* exclude);
|
||||
|
||||
int GetNPCCount() { return _npcs.size(); }
|
||||
int GetNPCCount() { return _npcs.size(); }
|
||||
|
||||
void OnPlayerAttack(Player* player);
|
||||
void OnPlayerMove(Player* player);
|
||||
void OnPlayerAttack(Player* player);
|
||||
void OnPlayerMove(Player* player);
|
||||
|
||||
private:
|
||||
LevelGen* _level;
|
||||
std::list<NPC*> _npcs;
|
||||
LevelGen* _level;
|
||||
std::list<NPC*> _npcs;
|
||||
};
|
||||
|
@ -24,7 +24,7 @@ bool AStarTile::GetSuccessors(AStarSearch<AStarTile>* search) {
|
||||
if(!_level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(x > 0) {
|
||||
AStarTile& successor = _level->GetAStarTile(x - 1, y);
|
||||
if(successor._passable) {
|
||||
|
@ -15,42 +15,42 @@ LevelGen::~LevelGen(void) {
|
||||
|
||||
void LevelGen::New(void) {
|
||||
Unload();
|
||||
|
||||
|
||||
_world = WorldManager(this);
|
||||
|
||||
for(x = 0; x < TILE_ARRAY_WIDTH; x++) {
|
||||
for(y = 0; y < TILE_ARRAY_HEIGHT; y++) {
|
||||
_tile[x][y].SetTileTextureName("grass");
|
||||
|
||||
|
||||
stringstream tilePath;
|
||||
tilePath << "../Data/Media/Images/Tiles/" << _tile[x][y].GetTileTextureName() << ".png";
|
||||
|
||||
|
||||
_tile[x][y].SetTileTexture(_tileTextures.Add(tilePath.str()));
|
||||
_tile[x][y].SetTileSolidity(false);
|
||||
_tile[x][y].SetTileXY(x * TILE_WIDTH, y * TILE_HEIGHT);
|
||||
_tile[x][y].SetEntitySolidity(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// procedural generation
|
||||
DoMagic();
|
||||
DoMagic();
|
||||
|
||||
// pathfinding
|
||||
UpdateAStarTiles();
|
||||
}
|
||||
|
||||
void LevelGen::Load(const string& filename) {
|
||||
Unload();
|
||||
Unload();
|
||||
|
||||
_currentMap = filename;
|
||||
string fullMapPath = "../Data/Media/Maps/" + filename;
|
||||
_currentMap = filename;
|
||||
string fullMapPath = "../Data/Media/Maps/" + filename;
|
||||
|
||||
Serialiser serialiser;
|
||||
serialiser.Load(fullMapPath);
|
||||
Inflate(&serialiser);
|
||||
|
||||
_world = WorldManager(this);
|
||||
|
||||
|
||||
GenerateEnemies();
|
||||
|
||||
UpdateAStarTiles();
|
||||
@ -59,32 +59,32 @@ void LevelGen::Load(const string& filename) {
|
||||
void LevelGen::Save(const string& filename) {
|
||||
Serialiser serialiser;
|
||||
Deflate(&serialiser);
|
||||
|
||||
|
||||
_currentMap = filename;
|
||||
string fullMapPath = "../Data/Media/Maps/" + filename;
|
||||
|
||||
string fullMapPath = "../Data/Media/Maps/" + filename;
|
||||
|
||||
serialiser.Save(fullMapPath);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LevelGen::Update(void) {
|
||||
_world.Update();
|
||||
// Update the map so we can render when camera moves.
|
||||
_world.Update();
|
||||
// Update the map so we can render when camera moves.
|
||||
}
|
||||
|
||||
void LevelGen::Render(void) {
|
||||
for(int i = 0; i < TILE_ARRAY_WIDTH; i++) {
|
||||
for(int j = 0; j < TILE_ARRAY_HEIGHT; j++) {
|
||||
_tile[i][j].Render();
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < TILE_ARRAY_WIDTH; i++) {
|
||||
for(int j = 0; j < TILE_ARRAY_HEIGHT; j++) {
|
||||
_tile[i][j].Render();
|
||||
}
|
||||
}
|
||||
|
||||
_world.Render();
|
||||
_world.Render();
|
||||
}
|
||||
|
||||
void LevelGen::Unload(void) {
|
||||
_tileTextures.Unload();
|
||||
_entityTextures.Unload();
|
||||
_tileTextures.Unload();
|
||||
_entityTextures.Unload();
|
||||
for(int x = 0; x < TILE_ARRAY_WIDTH; x++) {
|
||||
for(int y = 0; y < TILE_ARRAY_HEIGHT; y++) {
|
||||
_tile[x][y] = MapTile();
|
||||
@ -100,75 +100,75 @@ void LevelGen::DoMagic(void) {
|
||||
GenerateEntities("barrel2", 100);
|
||||
GenerateEntities("stone", 55);
|
||||
GenerateEntities("stone2", 55);
|
||||
GenerateEntities("chest", 120);
|
||||
GenerateEntities("chest2", 170);
|
||||
GenerateEntities("chest", 120);
|
||||
GenerateEntities("chest2", 170);
|
||||
GenerateEntities("chest3", 270);
|
||||
MakeWalkingPaths();
|
||||
GenerateEnemies();
|
||||
}
|
||||
|
||||
void LevelGen::GenerateEntities(const string& name, int frequency) {
|
||||
int nextEntityGen = 1 + (rand() % frequency);
|
||||
std::string filename = "../Data/Media/Images/Entities/" + name + ".png";
|
||||
int nextEntityGen = 1 + (rand() % frequency);
|
||||
std::string filename = "../Data/Media/Images/Entities/" + name + ".png";
|
||||
|
||||
for(int x = 0; x < (TILE_ARRAY_WIDTH - 1); x++) {
|
||||
for(int y = 0; y < (TILE_ARRAY_HEIGHT - 1); y++) {
|
||||
nextEntityGen--;
|
||||
if(!_tile[x][y].GetTileSolidity() && !_tile[x][y].GetEntitySolitity() && nextEntityGen <= 0) {
|
||||
_tile[x][y].SetEntityTextureName(name);
|
||||
for(int x = 0; x < (TILE_ARRAY_WIDTH - 1); x++) {
|
||||
for(int y = 0; y < (TILE_ARRAY_HEIGHT - 1); y++) {
|
||||
nextEntityGen--;
|
||||
if(!_tile[x][y].GetTileSolidity() && !_tile[x][y].GetEntitySolitity() && nextEntityGen <= 0) {
|
||||
_tile[x][y].SetEntityTextureName(name);
|
||||
_tile[x][y].SetEntityTexture(_entityTextures.AddAlpha(filename));
|
||||
|
||||
_tile[x][y].SetEntityXY(_tile[x][y].GetTileX() + TILE_WIDTH / 2 - _tile[x][y].GetEntityWidth() / 2,
|
||||
_tile[x][y].GetTileY() + TILE_HEIGHT / 2 - _tile[x][y].GetEntityHeight() / 2);
|
||||
_tile[x][y].SetEntityXY(_tile[x][y].GetTileX() + TILE_WIDTH / 2 - _tile[x][y].GetEntityWidth() / 2,
|
||||
_tile[x][y].GetTileY() + TILE_HEIGHT / 2 - _tile[x][y].GetEntityHeight() / 2);
|
||||
|
||||
_tile[x][y].SetEntitySolidity(true);
|
||||
_tile[x][y].SetEntitySolidity(true);
|
||||
|
||||
nextEntityGen = 1 + (rand() % frequency);
|
||||
}
|
||||
}
|
||||
}
|
||||
nextEntityGen = 1 + (rand() % frequency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LevelGen::MakeWalkingPaths(void) {
|
||||
int lastOpenY = rand() % 5;
|
||||
int lastOpenY = rand() % 5;
|
||||
|
||||
for(int x = 0; x < TILE_ARRAY_WIDTH; x++) {
|
||||
bool pathFound = false;
|
||||
for(int x = 0; x < TILE_ARRAY_WIDTH; x++) {
|
||||
bool pathFound = false;
|
||||
|
||||
for(int y = 0; y < TILE_ARRAY_HEIGHT; y++) {
|
||||
if(!_tile[x][y].GetEntitySolitity()) {
|
||||
pathFound = true;
|
||||
break;
|
||||
} else {
|
||||
lastOpenY = y;
|
||||
}
|
||||
}
|
||||
for(int y = 0; y < TILE_ARRAY_HEIGHT; y++) {
|
||||
if(!_tile[x][y].GetEntitySolitity()) {
|
||||
pathFound = true;
|
||||
break;
|
||||
} else {
|
||||
lastOpenY = y;
|
||||
}
|
||||
}
|
||||
|
||||
if(!pathFound) {
|
||||
_tile[x][lastOpenY].SetEntityTexture(NULL);
|
||||
_tile[x][lastOpenY].SetEntitySolidity(false);
|
||||
}
|
||||
}
|
||||
if(!pathFound) {
|
||||
_tile[x][lastOpenY].SetEntityTexture(NULL);
|
||||
_tile[x][lastOpenY].SetEntitySolidity(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LevelGen::FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight) {
|
||||
xArg = rand() % ((TILE_ARRAY_WIDTH - 1) * TILE_WIDTH);
|
||||
yArg = rand() % ((TILE_ARRAY_HEIGHT - 1) * TILE_HEIGHT);
|
||||
|
||||
xArg = rand() % ((TILE_ARRAY_WIDTH - 1) * TILE_WIDTH);
|
||||
yArg = rand() % ((TILE_ARRAY_HEIGHT - 1) * TILE_HEIGHT);
|
||||
|
||||
if((xArg + objWidth + 1) > SCREEN_WIDTH) {
|
||||
xArg = SCREEN_WIDTH - objWidth - 1;
|
||||
}
|
||||
|
||||
|
||||
if((yArg + objHeight + 1) > SCREEN_HEIGHT) {
|
||||
yArg = SCREEN_HEIGHT - objHeight - 1;
|
||||
}
|
||||
|
||||
|
||||
SDL_Rect objRect;
|
||||
objRect.x = xArg;
|
||||
objRect.y = yArg;
|
||||
objRect.w = objWidth;
|
||||
objRect.h = objHeight;
|
||||
|
||||
|
||||
NPC* npc = _world.GetNPCAt(xArg, yArg);
|
||||
if(npc) {
|
||||
SDL_Rect npcRect;
|
||||
@ -176,13 +176,13 @@ void LevelGen::FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight)
|
||||
npcRect.y = npc->GetY();
|
||||
npcRect.w = npc->GetWidth();
|
||||
npcRect.h = npc->GetHeight();
|
||||
|
||||
|
||||
if(CheckCollisionRect(npcRect, objRect)) {
|
||||
FindSpawnPoint(xArg, yArg, objWidth, objHeight);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(int i = 0; i < TILE_ARRAY_WIDTH; i++) {
|
||||
for(int j = 0; j < TILE_ARRAY_HEIGHT; j++) {
|
||||
if(_tile[i][j].GetEntitySolitity()) {
|
||||
@ -190,8 +190,8 @@ void LevelGen::FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight)
|
||||
entityRect.x = _tile[i][j].GetEntityX();
|
||||
entityRect.y = _tile[i][j].GetEntityY();
|
||||
entityRect.w = _tile[i][j].GetEntityWidth();
|
||||
entityRect.h = _tile[i][j].GetEntityHeight();
|
||||
|
||||
entityRect.h = _tile[i][j].GetEntityHeight();
|
||||
|
||||
if(CheckCollisionRect(entityRect, objRect)) {
|
||||
FindSpawnPoint(xArg, yArg, objWidth, objHeight);
|
||||
return;
|
||||
@ -203,12 +203,12 @@ void LevelGen::FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight)
|
||||
|
||||
void LevelGen::GenerateEnemies(void) {
|
||||
int npcsToGen = (_player->GetLevel() * 2) + (rand() % 4);
|
||||
|
||||
|
||||
for(int i = 0; i < npcsToGen; i++) {
|
||||
int spawnX;
|
||||
int spawnY;
|
||||
FindSpawnPoint(spawnX, spawnY, 40,45);
|
||||
|
||||
|
||||
_world.CreateNPC(spawnX, spawnY);
|
||||
}
|
||||
}
|
||||
@ -217,62 +217,62 @@ void LevelGen::MoveIfPossible(Character* character, float xVel, float yVel, bool
|
||||
if(xVel == 0.0f && yVel == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
float targetX = character->GetX() + xVel;
|
||||
float targetY = character->GetY() + yVel;
|
||||
|
||||
if(targetX < 0 || targetX > (SCREEN_WIDTH - character->GetWidth()) ||
|
||||
|
||||
if(targetX < 0 || targetX > (SCREEN_WIDTH - character->GetWidth()) ||
|
||||
targetY < 0 || targetY > (SCREEN_HEIGHT - character->GetHeight())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int targetTileX = targetX / TILE_WIDTH;
|
||||
int targetTileY = targetY / TILE_HEIGHT;
|
||||
|
||||
|
||||
if(_tile[targetTileX][targetTileY].GetTileSolidity()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SDL_Rect charRect;
|
||||
charRect.x = targetX;
|
||||
charRect.y = targetY + (character->GetHeight() / 4) * 3;
|
||||
charRect.w = character->GetWidth();
|
||||
charRect.h = character->GetHeight() / 4;
|
||||
|
||||
|
||||
for(int i = 0; i < TILE_ARRAY_WIDTH; i++) {
|
||||
for(int j = 0; j < TILE_ARRAY_HEIGHT; j++) {
|
||||
if(!_tile[i][j].GetEntitySolitity()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
SDL_Rect entityRect;
|
||||
entityRect.x = _tile[i][j].GetEntityX();
|
||||
entityRect.y = _tile[i][j].GetEntityY();
|
||||
entityRect.w = _tile[i][j].GetEntityWidth();
|
||||
entityRect.h = _tile[i][j].GetEntityHeight();
|
||||
|
||||
|
||||
if(CheckCollisionRect(entityRect, charRect)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(_world.CheckCollision(charRect, character)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(!isPlayer) {
|
||||
SDL_Rect playerRect;
|
||||
playerRect.x = _player->GetX();
|
||||
playerRect.y = _player->GetY();
|
||||
playerRect.w = _player->GetWidth();
|
||||
playerRect.h = _player->GetHeight();
|
||||
|
||||
|
||||
if(CheckCollisionRect(playerRect, charRect)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
character->SetXY(targetX, targetY);
|
||||
}
|
||||
|
||||
@ -288,13 +288,13 @@ bool LevelGen::AStarTilePassable(int xArg, int yArg) {
|
||||
if(!_tile[i][j].GetEntitySolitity()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
SDL_Rect entityRect;
|
||||
entityRect.x = _tile[i][j].GetEntityX();
|
||||
entityRect.y = _tile[i][j].GetEntityY();
|
||||
entityRect.w = _tile[i][j].GetEntityWidth();
|
||||
entityRect.h = _tile[i][j].GetEntityHeight();
|
||||
|
||||
|
||||
if(CheckCollisionRect(tileRect, entityRect)) {
|
||||
return false;
|
||||
}
|
||||
@ -338,7 +338,7 @@ void LevelGen::Deflate(Serialiser* serialiser) {
|
||||
|
||||
void LevelGen::Inflate(Serialiser* serialiser) {
|
||||
serialiser->FirstElement("map");
|
||||
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
|
||||
@ -360,7 +360,7 @@ void LevelGen::Inflate(Serialiser* serialiser) {
|
||||
_tile[x][y].SetTileXY(x * TILE_WIDTH, y * TILE_HEIGHT);
|
||||
}
|
||||
|
||||
string entityTextureName = _tile[x][y].GetEntityTextureName();
|
||||
string entityTextureName = _tile[x][y].GetEntityTextureName();
|
||||
if(entityTextureName != "null") {
|
||||
_tile[x][y].SetEntityTexture(_entityTextures.AddAlpha("../Data/Media/Images/Entities/" + entityTextureName + ".png"));
|
||||
_tile[x][y].SetEntityXY(_tile[x][y].GetTileX() + TILE_WIDTH / 2 - _tile[x][y].GetEntityWidth() / 2,
|
||||
@ -371,45 +371,45 @@ void LevelGen::Inflate(Serialiser* serialiser) {
|
||||
}
|
||||
|
||||
string LevelGen::GetCurrentMap(void) {
|
||||
return _currentMap;
|
||||
return _currentMap;
|
||||
}
|
||||
|
||||
bool LevelGen::GetTileSolidity(int xArg, int yArg) {
|
||||
return _tile[xArg + 1][yArg + 1].GetTileSolidity();
|
||||
return _tile[xArg + 1][yArg + 1].GetTileSolidity();
|
||||
}
|
||||
|
||||
int LevelGen::GetTileX(int xArg, int yArg) {
|
||||
return _tile[xArg + 1][yArg + 1].GetTileX();
|
||||
return _tile[xArg + 1][yArg + 1].GetTileX();
|
||||
}
|
||||
|
||||
int LevelGen::GetTileY(int xArg, int yArg) {
|
||||
return _tile[xArg + 1][yArg + 1].GetTileY();
|
||||
return _tile[xArg + 1][yArg + 1].GetTileY();
|
||||
}
|
||||
|
||||
bool LevelGen::GetEntitySolidity(int xArg, int yArg) {
|
||||
if(xArg > x || yArg > y || yArg < 0 || yArg < 0) {
|
||||
return false;
|
||||
}
|
||||
if(xArg > x || yArg > y || yArg < 0 || yArg < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return _tile[xArg + 1][yArg + 1].GetEntitySolitity();
|
||||
return _tile[xArg + 1][yArg + 1].GetEntitySolitity();
|
||||
}
|
||||
|
||||
int LevelGen::GetEntityX(int xArg, int yArg) {
|
||||
return _tile[xArg + 1][yArg + 1].GetEntityX();
|
||||
return _tile[xArg + 1][yArg + 1].GetEntityX();
|
||||
}
|
||||
|
||||
int LevelGen::GetEntityY(int xArg, int yArg) {
|
||||
return _tile[xArg + 1][yArg + 1].GetEntityY();
|
||||
return _tile[xArg + 1][yArg + 1].GetEntityY();
|
||||
}
|
||||
|
||||
int LevelGen::GetEntityWidth(int xArg, int yArg) {
|
||||
return _tile[xArg + 1][yArg + 1].GetEntityWidth();
|
||||
return _tile[xArg + 1][yArg + 1].GetEntityWidth();
|
||||
}
|
||||
|
||||
int LevelGen::GetEntityHeight(int xArg, int yArg) {
|
||||
return _tile[xArg + 1][yArg + 1].GetEntityHeight();
|
||||
return _tile[xArg + 1][yArg + 1].GetEntityHeight();
|
||||
}
|
||||
|
||||
AStarTile& LevelGen::GetAStarTile(int xArg, int yArg) {
|
||||
return _astarTile[xArg][yArg];
|
||||
}
|
||||
}
|
||||
|
@ -24,39 +24,39 @@ class Player;
|
||||
|
||||
class LevelGen : public Serialisable {
|
||||
public:
|
||||
LevelGen(void);
|
||||
~LevelGen(void);
|
||||
LevelGen(void);
|
||||
~LevelGen(void);
|
||||
|
||||
void New(void);
|
||||
void Load(const string& filename);
|
||||
void Save(const string& filename);
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
|
||||
|
||||
void FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight);
|
||||
void MoveIfPossible(Character* character, float xVel, float yVel, bool isPlayer = false);
|
||||
|
||||
bool GetTileSolidity(int xArg, int yArg);
|
||||
int GetTileX(int xArg, int yArg);
|
||||
int GetTileY(int xArg, int yArg);
|
||||
|
||||
bool GetEntitySolidity(int xArg, int yArg);
|
||||
int GetEntityX(int xArg, int yArg);
|
||||
int GetEntityY(int xArg, int yArg);
|
||||
int GetEntityWidth(int xArg, int yArg);
|
||||
int GetEntityHeight(int xArg, int yArg);
|
||||
bool GetTileSolidity(int xArg, int yArg);
|
||||
int GetTileX(int xArg, int yArg);
|
||||
int GetTileY(int xArg, int yArg);
|
||||
|
||||
int GetTileZLevel(int xArg, int yArg);
|
||||
bool GetEntitySolidity(int xArg, int yArg);
|
||||
int GetEntityX(int xArg, int yArg);
|
||||
int GetEntityY(int xArg, int yArg);
|
||||
int GetEntityWidth(int xArg, int yArg);
|
||||
int GetEntityHeight(int xArg, int yArg);
|
||||
|
||||
int GetTileZLevel(int xArg, int yArg);
|
||||
|
||||
AStarTile& GetAStarTile(int xArg, int yArg);
|
||||
|
||||
string GetCurrentMap(void);
|
||||
string GetCurrentMap(void);
|
||||
|
||||
WorldManager& GetWorld(void) { return _world; }
|
||||
WorldManager& GetWorld(void) { return _world; }
|
||||
|
||||
void SetPlayer(Player* player) { _player = player; }
|
||||
void SetPlayer(Player* player) { _player = player; }
|
||||
Player* GetPlayer() { return _player; }
|
||||
|
||||
|
||||
static const int TILE_ARRAY_WIDTH = (SCREEN_WIDTH / TILE_WIDTH) + 1;
|
||||
static const int TILE_ARRAY_HEIGHT = (SCREEN_HEIGHT / TILE_HEIGHT) + 1;
|
||||
static const int ASTAR_ARRAY_WIDTH = TILE_ARRAY_WIDTH * (TILE_WIDTH / AStarTile::FAKE_SIZE);
|
||||
@ -85,6 +85,6 @@ private:
|
||||
TextureManager _entityTextures;
|
||||
|
||||
WorldManager _world;
|
||||
|
||||
|
||||
Player* _player;
|
||||
};
|
||||
|
@ -30,7 +30,7 @@ bool MapElement::GetSolidity(void) {
|
||||
|
||||
void MapElement::SetXY(int xArg, int yArg) {
|
||||
x = xArg,
|
||||
y = yArg;
|
||||
y = yArg;
|
||||
}
|
||||
|
||||
int MapElement::GetX(void) { return x; }
|
||||
@ -39,4 +39,4 @@ int MapElement::GetWidth(void) { return _texture->w; }
|
||||
int MapElement::GetHeight(void) { return _texture->h; }
|
||||
|
||||
void MapElement::SetTextureName(string name) { _textureName = name; }
|
||||
string MapElement::GetTextureName(void) { return _textureName; }
|
||||
string MapElement::GetTextureName(void) { return _textureName; }
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
int GetY(void);
|
||||
int GetWidth(void);
|
||||
int GetHeight(void);
|
||||
|
||||
|
||||
void SetTextureName(string path);
|
||||
string GetTextureName(void);
|
||||
|
||||
|
@ -39,4 +39,4 @@ void MapTile::Inflate(Serialiser* serialiser) {
|
||||
|
||||
_entity.SetTextureName(entityTexture);
|
||||
_entity.SetSolidity(solidEntity);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
MapTile(void) { }
|
||||
~MapTile(void) { }
|
||||
|
||||
void Render(void) { _tile.Render(), _entity.Render(); }
|
||||
void Render(void) { _tile.Render(), _entity.Render(); }
|
||||
|
||||
void Deflate(Serialiser* serialiser);
|
||||
void Inflate(Serialiser* serialiser);
|
||||
@ -34,19 +34,19 @@ public:
|
||||
int GetTileX(void) { return _tile.GetX(); }
|
||||
int GetTileY(void) { return _tile.GetY(); }
|
||||
|
||||
// Entity Mutators.
|
||||
void SetEntityTexture(SDL_Surface* arg) { _entity.SetTexture(arg); }
|
||||
void SetEntityTextureName(string path) { _entity.SetTextureName(path); }
|
||||
void SetEntityXY(int xArg, int yArg) { _entity.SetXY(xArg, yArg); }
|
||||
void SetEntitySolidity(bool arg) { _entity.SetSolidity(arg); }
|
||||
bool GetEntitySolitity(void) { return _entity.GetSolidity(); }
|
||||
// Entity Mutators.
|
||||
void SetEntityTexture(SDL_Surface* arg) { _entity.SetTexture(arg); }
|
||||
void SetEntityTextureName(string path) { _entity.SetTextureName(path); }
|
||||
void SetEntityXY(int xArg, int yArg) { _entity.SetXY(xArg, yArg); }
|
||||
void SetEntitySolidity(bool arg) { _entity.SetSolidity(arg); }
|
||||
bool GetEntitySolitity(void) { return _entity.GetSolidity(); }
|
||||
|
||||
// Entity Mutators.
|
||||
int GetEntityX(void) { return _entity.GetX(); }
|
||||
int GetEntityY(void) { return _entity.GetY(); }
|
||||
int GetEntityWidth(void) { return _entity.GetWidth(); }
|
||||
int GetEntityHeight(void) { return _entity.GetHeight(); }
|
||||
string GetEntityTextureName(void) { return _entity.GetTextureName(); }
|
||||
// Entity Mutators.
|
||||
int GetEntityX(void) { return _entity.GetX(); }
|
||||
int GetEntityY(void) { return _entity.GetY(); }
|
||||
int GetEntityWidth(void) { return _entity.GetWidth(); }
|
||||
int GetEntityHeight(void) { return _entity.GetHeight(); }
|
||||
string GetEntityTextureName(void) { return _entity.GetTextureName(); }
|
||||
|
||||
private:
|
||||
MapElement _tile;
|
||||
|
@ -34,13 +34,13 @@ Debug::Debug(bool logToFile) {
|
||||
|
||||
Debug::~Debug(void) {
|
||||
time_t timestamp;
|
||||
|
||||
|
||||
// We only need to close the log if it is open.
|
||||
if(_logFile) {
|
||||
// Give it a closing timestamp.
|
||||
timestamp = time(NULL);
|
||||
_logFile << endl << "Log Closed: " << ctime(×tamp) << endl;
|
||||
|
||||
|
||||
// Close the log file.
|
||||
_logFile.close();
|
||||
}
|
||||
@ -73,11 +73,11 @@ void Debug::message(const char *msg, ...) {
|
||||
if(outLen >= sizeof(outBuf)) {
|
||||
outLen = sizeof(outBuf);
|
||||
}
|
||||
|
||||
|
||||
if(_logFile) {
|
||||
_logFile << outBuf << endl;
|
||||
}
|
||||
|
||||
|
||||
cerr << outBuf << endl;
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,9 @@ public:
|
||||
void message(const char *msg, ...);
|
||||
static bool openLog(bool logToFile);
|
||||
static void closeLog(void);
|
||||
|
||||
|
||||
static Debug *logger;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::ofstream _logFile;
|
||||
};
|
||||
|
@ -31,6 +31,9 @@ bool CreateInput(void) {
|
||||
|
||||
memcpy(keyboard.keys, tempKeys, sizeof(char) * keyboard.keycount);
|
||||
mouse.buttons = SDL_GetMouseState(&mouse.dx, &mouse.dy);
|
||||
if(&keyboard > 0 || &mouse > 0){
|
||||
Debug::logger->message("Input device registered");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -79,4 +82,5 @@ bool MouseStillUp(int button) { return(!_curr_mouse(button) && !_old_mouse(b
|
||||
void DestroyInput(void) {
|
||||
free(keyboard.keys);
|
||||
free(keyboard.oldKeys);
|
||||
Debug::logger->message("Input device destroyed");
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "../System/Debug.h"
|
||||
|
||||
typedef struct mouse_s {
|
||||
int dx, dy;
|
||||
int oldx, oldy;
|
||||
@ -21,23 +23,23 @@ typedef struct input_s {
|
||||
keyboard_t keyboard;
|
||||
} input_t;
|
||||
|
||||
bool CreateInput(void);
|
||||
void UpdateInput(void);
|
||||
bool CreateInput(void);
|
||||
void UpdateInput(void);
|
||||
|
||||
char GetKey(void);
|
||||
char GetKey(void);
|
||||
|
||||
unsigned int GetX(void);
|
||||
unsigned int GetY(void);
|
||||
unsigned int GetOldX(void);
|
||||
unsigned int GetOldY(void);
|
||||
unsigned int GetMods(void);
|
||||
bool KeyDown(int index);
|
||||
bool KeyStillDown(int index);
|
||||
bool KeyUp(int index);
|
||||
bool KeyStillUp(int index);
|
||||
bool MouseDown(int button);
|
||||
bool MouseStillDown(int button);
|
||||
bool MouseUp(int button);
|
||||
bool MouseStillUp(int button);
|
||||
unsigned int GetX(void);
|
||||
unsigned int GetY(void);
|
||||
unsigned int GetOldX(void);
|
||||
unsigned int GetOldY(void);
|
||||
unsigned int GetMods(void);
|
||||
bool KeyDown(int index);
|
||||
bool KeyStillDown(int index);
|
||||
bool KeyUp(int index);
|
||||
bool KeyStillUp(int index);
|
||||
bool MouseDown(int button);
|
||||
bool MouseStillDown(int button);
|
||||
bool MouseUp(int button);
|
||||
bool MouseStillUp(int button);
|
||||
|
||||
void DestroyInput(void);
|
||||
void DestroyInput(void);
|
||||
|
@ -3,36 +3,36 @@
|
||||
|
||||
class MathBox {
|
||||
public:
|
||||
// A templated max function that returns none other than the max of two values.
|
||||
template<typename T>
|
||||
static T Max(T value1, T value2) {
|
||||
return value1 > value2 ? value1 : value2;
|
||||
}
|
||||
// A templated max function that returns none other than the max of two values.
|
||||
template<typename T>
|
||||
static T Max(T value1, T value2) {
|
||||
return value1 > value2 ? value1 : value2;
|
||||
}
|
||||
|
||||
// A templated min function that returns none other than the min of two values.
|
||||
template<typename T>
|
||||
static T Min(T value1, T value2) {
|
||||
return value1 < value2 ? value1 : value2;
|
||||
}
|
||||
// A templated min function that returns none other than the min of two values.
|
||||
template<typename T>
|
||||
static T Min(T value1, T value2) {
|
||||
return value1 < value2 ? value1 : value2;
|
||||
}
|
||||
|
||||
// Linear interpolation between two values.
|
||||
template<typename T>
|
||||
static T Lerp(T value1, T value2, float amount) {
|
||||
return T(value1 + ((T)(value2 - value1) * amount));
|
||||
}
|
||||
// Linear interpolation between two values.
|
||||
template<typename T>
|
||||
static T Lerp(T value1, T value2, float amount) {
|
||||
return T(value1 + ((T)(value2 - value1) * amount));
|
||||
}
|
||||
|
||||
// Clamp an integer to a specified range.
|
||||
static int Clamp(int value, int min, int max) {
|
||||
return Max(min, Min(max, value));
|
||||
}
|
||||
// Clamp an integer to a specified range.
|
||||
static int Clamp(int value, int min, int max) {
|
||||
return Max(min, Min(max, value));
|
||||
}
|
||||
|
||||
// Clamp a float to a specified range.
|
||||
static float Clamp(float value, float min, float max) {
|
||||
return Max(min, Min(max, value));
|
||||
}
|
||||
// Clamp a float to a specified range.
|
||||
static float Clamp(float value, float min, float max) {
|
||||
return Max(min, Min(max, value));
|
||||
}
|
||||
|
||||
// Clamp a double-precision to a specified range.
|
||||
static double Clamp(double value, double min, double max) {
|
||||
return Max(min, Min(max, value));
|
||||
}
|
||||
// Clamp a double-precision to a specified range.
|
||||
static double Clamp(double value, double min, double max) {
|
||||
return Max(min, Min(max, value));
|
||||
}
|
||||
};
|
||||
|
@ -24,7 +24,7 @@ void Serialiser::StepOut(void) {
|
||||
}
|
||||
|
||||
TiXmlElement* parentElement = _parentElements.back();
|
||||
|
||||
|
||||
// This happens when stepping out of root.
|
||||
if(parentElement == _currentElement) {
|
||||
return;
|
||||
@ -55,7 +55,7 @@ bool Serialiser::FirstElement(const string& name) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(oldElement) {
|
||||
// Save the old element as parent.
|
||||
_parentElements.push_back(oldElement);
|
||||
@ -78,7 +78,7 @@ bool Serialiser::NextElement(const string& name) {
|
||||
if(!_currentElement) {
|
||||
// Restore the old element if new one was not found.
|
||||
_currentElement = oldElement;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ void Serialiser::WriteMembers(void) {
|
||||
//Debug::logger->message("WriteMembers()");
|
||||
|
||||
std::stringstream sstream;
|
||||
|
||||
|
||||
for(list<SerialiserMember>::iterator i = _members.begin(); i != _members.end(); ++i) {
|
||||
TiXmlText* text = NULL;
|
||||
|
||||
@ -146,7 +146,7 @@ void Serialiser::WriteMembers(void) {
|
||||
void Serialiser::ReadMembers(void) {
|
||||
for(list<SerialiserMember>::iterator i = _members.begin(); i != _members.end(); ++i) {
|
||||
TiXmlElement* element = _currentElement->FirstChildElement(i->_name.c_str());
|
||||
|
||||
|
||||
if(!element) {
|
||||
continue;
|
||||
}
|
||||
|
@ -22,134 +22,134 @@ Vec2::Vec2(const Vec2i ©) : x(copy.x), y(copy.y) {
|
||||
}
|
||||
|
||||
float Vec2::Length(void) {
|
||||
return sqrt(LengthSquared());
|
||||
return sqrt(LengthSquared());
|
||||
}
|
||||
|
||||
float Vec2::LengthSquared(void) {
|
||||
return (x * x) + (y * y);
|
||||
return (x * x) + (y * y);
|
||||
}
|
||||
|
||||
// Static.
|
||||
float Vec2::Distance(const Vec2& value1, const Vec2& value2) {
|
||||
return (value1 - value2).Length();
|
||||
return (value1 - value2).Length();
|
||||
}
|
||||
|
||||
// Static.
|
||||
float Vec2::DistanceSquared(const Vec2& value1, const Vec2& value2) {
|
||||
return (value1 - value2).LengthSquared();
|
||||
return (value1 - value2).LengthSquared();
|
||||
}
|
||||
|
||||
// Static.
|
||||
float Vec2::Dot(const Vec2& value1, const Vec2& value2) {
|
||||
return (value1.x * value2.x) - (value1.y * value2.y);
|
||||
return (value1.x * value2.x) - (value1.y * value2.y);
|
||||
}
|
||||
|
||||
// Static.
|
||||
float Vec2::Cross(const Vec2& value1, Vec2& value2) {
|
||||
return (value1.x * value2.y) - (value1.y * value2.x);
|
||||
return (value1.x * value2.y) - (value1.y * value2.x);
|
||||
}
|
||||
|
||||
void Vec2::Normalize(void) {
|
||||
float len = Length();
|
||||
if(len < 1e-7f) {
|
||||
if(y > x)
|
||||
*this = UnitY;
|
||||
else
|
||||
*this = UnitX;
|
||||
} else {
|
||||
*this = *this / len;
|
||||
}
|
||||
float len = Length();
|
||||
if(len < 1e-7f) {
|
||||
if(y > x)
|
||||
*this = UnitY;
|
||||
else
|
||||
*this = UnitX;
|
||||
} else {
|
||||
*this = *this / len;
|
||||
}
|
||||
}
|
||||
|
||||
// Static.
|
||||
Vec2 Vec2::Normalize(const Vec2& value) {
|
||||
Vec2 retVal(value);
|
||||
retVal.Normalize();
|
||||
return retVal;
|
||||
Vec2 retVal(value);
|
||||
retVal.Normalize();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// Static.
|
||||
Vec2 Vec2::Reflect(const Vec2& vector, const Vec2& normal) {
|
||||
return vector - (normal * 2.0f * Dot(vector, normal));
|
||||
return vector - (normal * 2.0f * Dot(vector, normal));
|
||||
}
|
||||
|
||||
// Static.
|
||||
Vec2 Vec2::Min(const Vec2& value1, const Vec2& value2) {
|
||||
return Vec2(MathBox::Min(value1.x, value2.x), MathBox::Min(value1.y, value2.y));
|
||||
return Vec2(MathBox::Min(value1.x, value2.x), MathBox::Min(value1.y, value2.y));
|
||||
}
|
||||
|
||||
// Static.
|
||||
Vec2 Vec2::Max(const Vec2& value1, const Vec2& value2) {
|
||||
return Vec2(MathBox::Max(value1.x, value2.x), MathBox::Max(value1.y, value2.y));
|
||||
return Vec2(MathBox::Max(value1.x, value2.x), MathBox::Max(value1.y, value2.y));
|
||||
}
|
||||
|
||||
// Static.
|
||||
Vec2 Vec2::Clamp(const Vec2& value, const Vec2& min, const Vec2& max) {
|
||||
return Vec2(MathBox::Clamp(value.x, min.x, max.x), MathBox::Clamp(value.y, min.y, max.y));
|
||||
return Vec2(MathBox::Clamp(value.x, min.x, max.x), MathBox::Clamp(value.y, min.y, max.y));
|
||||
}
|
||||
|
||||
// Static.
|
||||
Vec2 Vec2::Lerp(const Vec2& value1, const Vec2& value2, float amount) {
|
||||
return Vec2(MathBox::Lerp(value1.x, value2.x, amount), MathBox::Lerp(value1.y, value2.y, amount));
|
||||
return Vec2(MathBox::Lerp(value1.x, value2.x, amount), MathBox::Lerp(value1.y, value2.y, amount));
|
||||
}
|
||||
|
||||
// Static.
|
||||
Vec2 Vec2::Negate(const Vec2& value) {
|
||||
return -value;
|
||||
return -value;
|
||||
}
|
||||
|
||||
// Static.
|
||||
Vec2 Vec2::Rotate(const Vec2& value, const float radians) {
|
||||
float c = cos(radians);
|
||||
float s = sin(radians);
|
||||
return Vec2(value.x * c - value.y * s, value.y * c + value.x * s);
|
||||
float c = cos(radians);
|
||||
float s = sin(radians);
|
||||
return Vec2(value.x * c - value.y * s, value.y * c + value.x * s);
|
||||
}
|
||||
|
||||
// Overload some operators..
|
||||
bool Vec2::operator==(const Vec2& v) const {
|
||||
return x == v.x && y == v.y;
|
||||
return x == v.x && y == v.y;
|
||||
}
|
||||
|
||||
bool Vec2::operator!=(const Vec2& v) const {
|
||||
return !(*this == v);
|
||||
return !(*this == v);
|
||||
}
|
||||
|
||||
Vec2 Vec2::operator-(void) const {
|
||||
return Vec2::Zero - *this;
|
||||
return Vec2::Zero - *this;
|
||||
}
|
||||
|
||||
Vec2 Vec2::operator-(const Vec2& v) const {
|
||||
return Vec2(x - v.x, y - v.y);
|
||||
return Vec2(x - v.x, y - v.y);
|
||||
}
|
||||
|
||||
Vec2 Vec2::operator+(const Vec2& v) const {
|
||||
return Vec2(x + v.x, y + v.y);
|
||||
return Vec2(x + v.x, y + v.y);
|
||||
}
|
||||
|
||||
Vec2 Vec2::operator/(float divider) const {
|
||||
return Vec2(x / divider, y / divider);
|
||||
return Vec2(x / divider, y / divider);
|
||||
}
|
||||
|
||||
Vec2 Vec2::operator*(float scaleFactor) const {
|
||||
return Vec2(x * scaleFactor, y * scaleFactor);
|
||||
return Vec2(x * scaleFactor, y * scaleFactor);
|
||||
}
|
||||
|
||||
Vec2& Vec2::operator+=(const Vec2& v) {
|
||||
x += v.x, y += v.y;
|
||||
return *this;
|
||||
x += v.x, y += v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2& Vec2::operator-=(const Vec2& v) {
|
||||
x -= v.x, y -= v.y;
|
||||
return *this;
|
||||
x -= v.x, y -= v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2& Vec2::operator*=(float scaleFactor) {
|
||||
x *= scaleFactor, y *= scaleFactor;
|
||||
return *this;
|
||||
x *= scaleFactor, y *= scaleFactor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2& Vec2::operator/=(float scaleFactor) {
|
||||
x /= scaleFactor, y /= scaleFactor;
|
||||
return *this;
|
||||
x /= scaleFactor, y /= scaleFactor;
|
||||
return *this;
|
||||
}
|
||||
|
@ -6,98 +6,98 @@
|
||||
|
||||
// A handy structure for passing around 2D integer coords.
|
||||
struct Vec2i {
|
||||
int x, y;
|
||||
Vec2i(int xArg, int yArg) : x(xArg), y(yArg) {}
|
||||
Vec2i(void) : x(0), y(0) {}
|
||||
int x, y;
|
||||
Vec2i(int xArg, int yArg) : x(xArg), y(yArg) {}
|
||||
Vec2i(void) : x(0), y(0) {}
|
||||
};
|
||||
|
||||
struct Vec2 {
|
||||
// Initialize a zero-length vector (0, 0).
|
||||
Vec2(void);
|
||||
// Initialize a vector to a set dimension.
|
||||
Vec2(float xArg, float yArg);
|
||||
// Initialize a vector to a uniform dimension
|
||||
Vec2(float value);
|
||||
// Copy from the Vec2i to be converted into a Vec2
|
||||
Vec2(const Vec2i& copy);
|
||||
// Initialize a zero-length vector (0, 0).
|
||||
Vec2(void);
|
||||
// Initialize a vector to a set dimension.
|
||||
Vec2(float xArg, float yArg);
|
||||
// Initialize a vector to a uniform dimension
|
||||
Vec2(float value);
|
||||
// Copy from the Vec2i to be converted into a Vec2
|
||||
Vec2(const Vec2i& copy);
|
||||
|
||||
// A reference to a zero-length vector (0, 0)
|
||||
static Vec2 Zero;
|
||||
// A reference to a zero-length vector (0, 0)
|
||||
static Vec2 Zero;
|
||||
|
||||
// A reference to a (1, 1) vector.
|
||||
static Vec2 One;
|
||||
// A reference to a (1, 1) vector.
|
||||
static Vec2 One;
|
||||
|
||||
// A reference to a (1, 0) vecor.
|
||||
static Vec2 UnitX;
|
||||
// A reference to a (1, 0) vecor.
|
||||
static Vec2 UnitX;
|
||||
|
||||
// A reference to a (0, 1) vector.
|
||||
static Vec2 UnitY;
|
||||
// A reference to a (0, 1) vector.
|
||||
static Vec2 UnitY;
|
||||
|
||||
// Get the absolute magnitude of the vector. -- Uses a square root.
|
||||
float Length(void);
|
||||
// Get the absolute magnitude of the vector. -- Uses a square root.
|
||||
float Length(void);
|
||||
|
||||
// Get the squared magnitude of the vector -- Just in case we only care about comparison.
|
||||
float LengthSquared(void);
|
||||
// Get the squared magnitude of the vector -- Just in case we only care about comparison.
|
||||
float LengthSquared(void);
|
||||
|
||||
// Get absolute distance between two points. -- Uses a square root.
|
||||
static float Distance(const Vec2& value1, const Vec2& value2);
|
||||
// Get absolute distance between two points. -- Uses a square root.
|
||||
static float Distance(const Vec2& value1, const Vec2& value2);
|
||||
|
||||
// In case we only care about comparison..
|
||||
static float DistanceSquared(const Vec2& value1, const Vec2& value2);
|
||||
// In case we only care about comparison..
|
||||
static float DistanceSquared(const Vec2& value1, const Vec2& value2);
|
||||
|
||||
// Get the dot product of two vectors.
|
||||
static float Dot(const Vec2& value1, const Vec2& value2);
|
||||
// Get the dot product of two vectors.
|
||||
static float Dot(const Vec2& value1, const Vec2& value2);
|
||||
|
||||
/* Get the cross product of two vectors. Note that the \b mathmatical
|
||||
* definition of a cross product results in another vector oeroendicular
|
||||
* to the two inputs, but since both of our vectors are 2D, the returned
|
||||
* vector will always have x and y components of 0. This this function
|
||||
* returns what would be the z component vector.
|
||||
*/
|
||||
static float Cross(const Vec2& value1, Vec2& value2);
|
||||
/* Get the cross product of two vectors. Note that the \b mathmatical
|
||||
* definition of a cross product results in another vector oeroendicular
|
||||
* to the two inputs, but since both of our vectors are 2D, the returned
|
||||
* vector will always have x and y components of 0. This this function
|
||||
* returns what would be the z component vector.
|
||||
*/
|
||||
static float Cross(const Vec2& value1, Vec2& value2);
|
||||
|
||||
// Normalize a vector in place.
|
||||
void Normalize(void);
|
||||
// Normalize a vector in place.
|
||||
void Normalize(void);
|
||||
|
||||
// Get the normalized value for a Vec2 without affecting the original.
|
||||
static Vec2 Normalize(const Vec2& value);
|
||||
// Get the normalized value for a Vec2 without affecting the original.
|
||||
static Vec2 Normalize(const Vec2& value);
|
||||
|
||||
// Reflect the vector around another.
|
||||
static Vec2 Reflect(const Vec2& vector, const Vec2& normal);
|
||||
// Reflect the vector around another.
|
||||
static Vec2 Reflect(const Vec2& vector, const Vec2& normal);
|
||||
|
||||
// Get a new vector from the minimum x and y.
|
||||
static Vec2 Min(const Vec2& value1, const Vec2& value2);
|
||||
// Get a new vector from the minimum x and y.
|
||||
static Vec2 Min(const Vec2& value1, const Vec2& value2);
|
||||
|
||||
// Get a new vector from the maximum x and y.
|
||||
static Vec2 Max(const Vec2& value1, const Vec2& value2);
|
||||
// Get a new vector from the maximum x and y.
|
||||
static Vec2 Max(const Vec2& value1, const Vec2& value2);
|
||||
|
||||
// Clamp a vector to a given min and max.
|
||||
static Vec2 Clamp(const Vec2& value, const Vec2& min, const Vec2& max);
|
||||
// Clamp a vector to a given min and max.
|
||||
static Vec2 Clamp(const Vec2& value, const Vec2& min, const Vec2& max);
|
||||
|
||||
// Perform a linear interplolation between two vectors.
|
||||
static Vec2 Lerp(const Vec2& value1, const Vec2& value2, float amount);
|
||||
// Perform a linear interplolation between two vectors.
|
||||
static Vec2 Lerp(const Vec2& value1, const Vec2& value2, float amount);
|
||||
|
||||
// Get a negated vector.
|
||||
static Vec2 Negate(const Vec2& value);
|
||||
// Get a negated vector.
|
||||
static Vec2 Negate(const Vec2& value);
|
||||
|
||||
static Vec2 Rotate(const Vec2& value, const float radians);
|
||||
static Vec2 Rotate(const Vec2& value, const float radians);
|
||||
|
||||
bool operator==(const Vec2& v) const;
|
||||
bool operator!=(const Vec2& v) const;
|
||||
bool operator==(const Vec2& v) const;
|
||||
bool operator!=(const Vec2& v) const;
|
||||
|
||||
Vec2 operator-(void) const;
|
||||
Vec2 operator-(const Vec2& v) const;
|
||||
Vec2 operator+(const Vec2& v) const;
|
||||
Vec2 operator/(float divider) const;
|
||||
Vec2 operator*(float scaleFactor) const;
|
||||
Vec2 operator-(void) const;
|
||||
Vec2 operator-(const Vec2& v) const;
|
||||
Vec2 operator+(const Vec2& v) const;
|
||||
Vec2 operator/(float divider) const;
|
||||
Vec2 operator*(float scaleFactor) const;
|
||||
|
||||
Vec2& operator+=(const Vec2& v);
|
||||
Vec2& operator-=(const Vec2& v);
|
||||
Vec2& operator*=(float f);
|
||||
Vec2& operator/=(float f);
|
||||
Vec2& operator+=(const Vec2& v);
|
||||
Vec2& operator-=(const Vec2& v);
|
||||
Vec2& operator*=(float f);
|
||||
Vec2& operator/=(float f);
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
typedef std::vector<Vec2> Vector2List;
|
||||
|
@ -21,10 +21,10 @@ void Bar::SetWidthHeight(int wArg, int hArg) {
|
||||
if(width == wArg && height == hArg) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
width = wArg;
|
||||
height = hArg;
|
||||
|
||||
|
||||
_bgRect.SetWidthHeight(width, height);
|
||||
|
||||
SetProgress(_progress);
|
||||
@ -48,7 +48,7 @@ void Bar::SetForegroundRGB(SDL_Color colour) {
|
||||
|
||||
void Bar::SetProgress(float progress) {
|
||||
_progress = progress;
|
||||
|
||||
|
||||
_fgRect.SetWidthHeight((int)(progress * width), height);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
private:
|
||||
Rect _bgRect; // background
|
||||
Rect _fgRect; // foreground
|
||||
|
||||
|
||||
float _progress;
|
||||
|
||||
int x;
|
||||
|
@ -84,7 +84,7 @@ bool Button::CheckMouseOver(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Button::SetHighlighted(bool highlighted) {
|
||||
void Button::SetHighlighted(bool highlighted) {
|
||||
if(_highlighted != highlighted) {
|
||||
if(highlighted) {
|
||||
_button.SetRGB(_highlightColour);
|
||||
|
@ -15,9 +15,9 @@ EventHistory::EventHistory(void) {
|
||||
_titleText.SetXY(_bgx + BOX_WIDTH/2, _bgy + 5);
|
||||
_titleText.SetTextBlended("Unuk Log", small, 0, 255, 255);
|
||||
_titleText.SetXY(_titleText.GetX() - _titleText.GetWidth()/2, _titleText.GetY());
|
||||
|
||||
|
||||
_text.SetXY(_bgx + 5, _bgy + 30);
|
||||
|
||||
|
||||
_visible = false;
|
||||
}
|
||||
|
||||
@ -42,9 +42,9 @@ void EventHistory::LogEvent(const std::string& evtText) {
|
||||
void EventHistory::Render(void) {
|
||||
if(_visible && (_timeToVanish.GetTicks() >= 5000)) {
|
||||
_timeToVanish.Stop();
|
||||
|
||||
|
||||
_events.erase(_events.begin());
|
||||
|
||||
|
||||
if(_events.empty()) {
|
||||
_visible = false;
|
||||
} else {
|
||||
@ -56,18 +56,18 @@ void EventHistory::Render(void) {
|
||||
if(!_visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
roundedBoxRGBA(screen,
|
||||
_bgx, _bgy,
|
||||
_bgx + BOX_WIDTH, _bgy + BOX_HEIGHT,
|
||||
8,
|
||||
0, 0, 0, 128);
|
||||
|
||||
_bgx, _bgy,
|
||||
_bgx + BOX_WIDTH, _bgy + BOX_HEIGHT,
|
||||
8,
|
||||
0, 0, 0, 128);
|
||||
|
||||
roundedRectangleRGBA(screen,
|
||||
_bgx, _bgy,
|
||||
_bgx + BOX_WIDTH, _bgy + BOX_HEIGHT,
|
||||
8,
|
||||
0, 255, 255, 255);
|
||||
_bgx, _bgy,
|
||||
_bgx + BOX_WIDTH, _bgy + BOX_HEIGHT,
|
||||
8,
|
||||
0, 255, 255, 255);
|
||||
|
||||
_titleText.RenderLiteral();
|
||||
_text.RenderLiteral();
|
||||
@ -80,6 +80,6 @@ void EventHistory::BakeText(void) {
|
||||
textStr.append("\n");
|
||||
}
|
||||
|
||||
_text.SetTextBlended(textStr, small, 255, 255, 255);
|
||||
_text.SetTextBlended(textStr, small, 255, 255, 255);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
private:
|
||||
void BakeText(void);
|
||||
|
||||
|
||||
std::list<std::string> _events;
|
||||
Text _titleText;
|
||||
Text _text;
|
||||
|
@ -71,22 +71,22 @@ ingameMenuNavVal_t IngameMenu::HandleInput(void) {
|
||||
_buttons.SelectPrevious();
|
||||
} else if(event.key.keysym.sym == SDLK_RETURN) {
|
||||
switch(_buttons.GetSelectedButton()) {
|
||||
case 0: return ingameMenuResume;
|
||||
case 1: return ingameMenuSaveGame;
|
||||
case 2: return ingameMenuLoadGame;
|
||||
case 3: return ingameMenuOptions;
|
||||
case 4: return ingameMenuMainMenu;
|
||||
case 0: return ingameMenuResume;
|
||||
case 1: return ingameMenuSaveGame;
|
||||
case 2: return ingameMenuLoadGame;
|
||||
case 3: return ingameMenuOptions;
|
||||
case 4: return ingameMenuMainMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(event.type == SDL_MOUSEBUTTONUP) {
|
||||
if(event.button.button == SDL_BUTTON_LEFT) {
|
||||
switch(_buttons.CheckMouseOver()) {
|
||||
case 0: return ingameMenuResume;
|
||||
case 1: return ingameMenuSaveGame;
|
||||
case 2: return ingameMenuLoadGame;
|
||||
case 3: return ingameMenuOptions;
|
||||
case 4: return ingameMenuMainMenu;
|
||||
case 0: return ingameMenuResume;
|
||||
case 1: return ingameMenuSaveGame;
|
||||
case 2: return ingameMenuLoadGame;
|
||||
case 3: return ingameMenuOptions;
|
||||
case 4: return ingameMenuMainMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,4 +96,4 @@ ingameMenuNavVal_t IngameMenu::HandleInput(void) {
|
||||
|
||||
void IngameMenu::Render(void) {
|
||||
_buttons.RenderLiteral();
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ MainMenu::MainMenu(void) {
|
||||
btnExit->SetText("Exit");
|
||||
btnExit->SetHighlightRGB(255, 128, 0);
|
||||
btnExit->SetHighlighted(false);
|
||||
btnExit->SetXY(100, 300);
|
||||
btnExit->SetXY(100, 300);
|
||||
|
||||
grpMain.AddButton(btnNewGame);
|
||||
grpMain.AddButton(btnLoadGame);
|
||||
@ -116,15 +116,15 @@ mainMenuNavVal_t MainMenu::Run(void) {
|
||||
} else if(event.key.keysym.sym == SDLK_RETURN) {
|
||||
if(btnNewGameActive) {
|
||||
switch(grpNewGame.GetSelectedButton()) {
|
||||
case 0: return mainMenuNewGame; break;
|
||||
case 1: btnNewGameActive = false; break;
|
||||
case 0: return mainMenuNewGame; break;
|
||||
case 1: btnNewGameActive = false; break;
|
||||
}
|
||||
} else {
|
||||
switch(grpMain.GetSelectedButton()) {
|
||||
case 0: btnNewGameActive = !btnNewGameActive; break;
|
||||
case 1: return mainMenuLoadGame;
|
||||
case 2: return mainMenuOptions;
|
||||
case 3: return mainMenuExitGame;
|
||||
case 0: btnNewGameActive = !btnNewGameActive; break;
|
||||
case 1: return mainMenuLoadGame;
|
||||
case 2: return mainMenuOptions;
|
||||
case 3: return mainMenuExitGame;
|
||||
}
|
||||
}
|
||||
} else if(event.key.keysym.sym == SDLK_ESCAPE) {
|
||||
@ -134,16 +134,16 @@ mainMenuNavVal_t MainMenu::Run(void) {
|
||||
else if(event.type == SDL_MOUSEBUTTONUP) {
|
||||
if(event.button.button == SDL_BUTTON_LEFT) {
|
||||
switch(grpMain.CheckMouseOver()) {
|
||||
case 0: btnNewGameActive = !btnNewGameActive; break;
|
||||
case 1: return mainMenuLoadGame;
|
||||
case 2: return mainMenuOptions;
|
||||
case 3: return mainMenuExitGame;
|
||||
case 0: btnNewGameActive = !btnNewGameActive; break;
|
||||
case 1: return mainMenuLoadGame;
|
||||
case 2: return mainMenuOptions;
|
||||
case 3: return mainMenuExitGame;
|
||||
}
|
||||
|
||||
if(btnNewGameActive) {
|
||||
switch(grpNewGame.CheckMouseOver()) {
|
||||
case 0: return mainMenuNewGame; break;
|
||||
case 1: btnNewGameActive = false; break;
|
||||
case 0: return mainMenuNewGame; break;
|
||||
case 1: btnNewGameActive = false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
private:
|
||||
void Render(void);
|
||||
|
||||
LevelGen _background;
|
||||
LevelGen _background;
|
||||
|
||||
Text lblMenu;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
SavegameMenu::SavegameMenu(void) {
|
||||
_title.SetXY(BOX_SPACING_X, 25);
|
||||
_title.SetTextBlended("Choose Savegame: ", vlarge, 0, 255, 255);
|
||||
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
std::stringstream capText;
|
||||
if(i != 3) {
|
||||
@ -16,16 +16,16 @@ SavegameMenu::SavegameMenu(void) {
|
||||
} else {
|
||||
capText << "Cancel";
|
||||
}
|
||||
|
||||
|
||||
_captions[i].SetXY(BOX_SPACING_X + BOX_WIDTH/2,
|
||||
BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT) + BOX_HEIGHT/2);
|
||||
|
||||
|
||||
_captions[i].SetTextBlended(capText.str(), large, 0, 255, 255);
|
||||
|
||||
|
||||
_captions[i].SetXY(_captions[i].GetX() - _captions[i].GetWidth()/2,
|
||||
_captions[i].GetY() - _captions[i].GetHeight()/2);
|
||||
}
|
||||
|
||||
|
||||
_selection = 0;
|
||||
}
|
||||
|
||||
@ -34,11 +34,11 @@ SavegameMenu::~SavegameMenu(void) {
|
||||
|
||||
savegameMenuNavVal_t SavegameMenu::Run(void) {
|
||||
SDL_FillRect(screen, NULL, 0);
|
||||
|
||||
|
||||
while(true) {
|
||||
Render();
|
||||
SDL_Flip(screen);
|
||||
|
||||
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
@ -62,18 +62,18 @@ savegameMenuNavVal_t SavegameMenu::Run(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return savegameMenuCancel;
|
||||
}
|
||||
|
||||
void SavegameMenu::Render(void) {
|
||||
_title.RenderLiteral();
|
||||
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
int borderRed;
|
||||
int borderGreen;
|
||||
int borderBlue;
|
||||
|
||||
|
||||
if(i == _selection) {
|
||||
borderRed = 255;
|
||||
borderGreen = 128;
|
||||
@ -83,19 +83,19 @@ void SavegameMenu::Render(void) {
|
||||
borderGreen = 255;
|
||||
borderBlue = 255;
|
||||
}
|
||||
|
||||
|
||||
roundedBoxRGBA(screen,
|
||||
BOX_SPACING_X, BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT),
|
||||
BOX_SPACING_X + BOX_WIDTH, BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT) + BOX_HEIGHT,
|
||||
5,
|
||||
0, 0, 128, 255);
|
||||
|
||||
BOX_SPACING_X, BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT),
|
||||
BOX_SPACING_X + BOX_WIDTH, BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT) + BOX_HEIGHT,
|
||||
5,
|
||||
0, 0, 128, 255);
|
||||
|
||||
roundedRectangleRGBA(screen,
|
||||
BOX_SPACING_X, BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT),
|
||||
BOX_SPACING_X + BOX_WIDTH, BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT) + BOX_HEIGHT,
|
||||
5,
|
||||
borderRed, borderGreen, borderBlue, 255);
|
||||
|
||||
BOX_SPACING_X, BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT),
|
||||
BOX_SPACING_X + BOX_WIDTH, BOXES_OFFSET_Y + (i * BOX_SPACING_Y) + (i * BOX_HEIGHT) + BOX_HEIGHT,
|
||||
5,
|
||||
borderRed, borderGreen, borderBlue, 255);
|
||||
|
||||
_captions[i].RenderLiteral();
|
||||
}
|
||||
}
|
||||
|
@ -9,20 +9,20 @@ class SavegameMenu
|
||||
public:
|
||||
SavegameMenu(void);
|
||||
~SavegameMenu(void);
|
||||
|
||||
|
||||
savegameMenuNavVal_t Run(void);
|
||||
|
||||
|
||||
int GetSelection(void) { return _selection; }
|
||||
|
||||
|
||||
private:
|
||||
void Render(void);
|
||||
|
||||
|
||||
Text _title;
|
||||
Text _captions[4];
|
||||
int _selection;
|
||||
|
||||
|
||||
static const int BOX_WIDTH = 400;
|
||||
static const int BOX_HEIGHT = 100;
|
||||
static const int BOX_HEIGHT = 100;
|
||||
static const int BOX_SPACING_X = 25;
|
||||
static const int BOX_SPACING_Y = 25;
|
||||
static const int BOXES_OFFSET_Y = 100;
|
||||
|
@ -88,7 +88,7 @@ int Text::SetTextBlended(string textArg, textSizes_t size, SDL_Color colour,bool
|
||||
if(wordWrap) {
|
||||
finalTextContents = DoWordWrap(font, finalTextContents);
|
||||
}
|
||||
|
||||
|
||||
std::list<std::string> lines;
|
||||
std::string line;
|
||||
for(int i = 0; i < (int)finalTextContents.size(); i++) {
|
||||
@ -115,7 +115,7 @@ int Text::SetTextBlended(string textArg, textSizes_t size, SDL_Color colour,bool
|
||||
w = linePixelWidth;
|
||||
}
|
||||
|
||||
h += linePixelHeight + lineSpacing;
|
||||
h += linePixelHeight + lineSpacing;
|
||||
|
||||
_lines.push_back(lineSurf);
|
||||
}
|
||||
@ -183,7 +183,7 @@ int Text::SetTextShaded(string textArg, textSizes_t size, SDL_Color colour, SDL_
|
||||
w = linePixelWidth;
|
||||
}
|
||||
|
||||
h += linePixelHeight + lineSpacing;
|
||||
h += linePixelHeight + lineSpacing;
|
||||
|
||||
_lines.push_back(lineSurf);
|
||||
}
|
||||
@ -201,8 +201,8 @@ void Text::Render(void) {
|
||||
int yOffset = 0;
|
||||
for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
|
||||
SDL_Surface* lineSurf = *it;
|
||||
ApplySurface(x, y + yOffset, lineSurf, screen);
|
||||
yOffset += lineSurf->h + lineSpacing;
|
||||
ApplySurface(x, y + yOffset, lineSurf, screen);
|
||||
yOffset += lineSurf->h + lineSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,8 +210,8 @@ void Text::Render(int xArg, int yArg) {
|
||||
int yOffset = 0;
|
||||
for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
|
||||
SDL_Surface* lineSurf = *it;
|
||||
ApplySurface(x + xArg, y + yArg + yOffset, lineSurf, screen);
|
||||
yOffset += lineSurf->h + lineSpacing;
|
||||
ApplySurface(x + xArg, y + yArg + yOffset, lineSurf, screen);
|
||||
yOffset += lineSurf->h + lineSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,8 +219,8 @@ void Text::RenderLiteral(void) {
|
||||
int yOffset = 0;
|
||||
for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
|
||||
SDL_Surface* lineSurf = *it;
|
||||
ApplySurfaceLiteral(x, y + yOffset, lineSurf, screen);
|
||||
yOffset += lineSurf->h + lineSpacing;
|
||||
ApplySurfaceLiteral(x, y + yOffset, lineSurf, screen);
|
||||
yOffset += lineSurf->h + lineSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,8 +228,8 @@ void Text::RenderLiteral(int xArg, int yArg) {
|
||||
int yOffset = 0;
|
||||
for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
|
||||
SDL_Surface* lineSurf = *it;
|
||||
ApplySurfaceLiteral(x + xArg, y + yArg + yOffset, lineSurf, screen);
|
||||
yOffset += lineSurf->h + lineSpacing;
|
||||
ApplySurfaceLiteral(x + xArg, y + yArg + yOffset, lineSurf, screen);
|
||||
yOffset += lineSurf->h + lineSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ std::string Text::DoWordWrap(TTF_Font* fontArg, const std::string& textArg) {
|
||||
word = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
// delete[] tokenizedText;
|
||||
// delete[] tokenizedText;
|
||||
|
||||
return wrappedText;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user