Long-Starlight-Snake-Game/GameConfiguration.hpp

289 lines
8.1 KiB
C++

#include "SynEngine.hpp"
class GameConfiguration
{
private:
sf::Vector2i windowDimensions;
sf::Color backgroundColor;
sf::Texture spriteSheet;
std::string spriteSheetPath;
sf::Vector2i spriteSheetCellSize;
sf::IntRect spriteSheetRect;
sf::Vector2i gridSize;
sf::Vector2i gridOffset;
float spriteSizeMultiplier;
float audioVolume;
bool fullscreen;
int tickPerSec;
template <class T> T Clamp(T &, T = 0.0, T = 1.0);
void NormalizeVector2f(sf::Vector2f &);
void LoadDefaultValues();
void LoadValuesFromFile(std::string);
void WriteValuesToFile(std::string);
void CalculateCommonValues();
std::istringstream GetNextNonCommentLine(std::istream &);
bool LoadSpriteSheet(std::string);
bool IsFileExists(std::string);
public:
GameConfiguration();
GameConfiguration(std::string = std::string());
bool IsFullscreen();
float GetSpriteSizeMultiplier();
float GetAudioVolume();
int GetTickPerSec();
sf::Color GetBackgroundColor();
sf::Vector2i GetScreenDimensions();
sf::Vector2i GetGridSize();
sf::Vector2i GetGridOffset();
sf::Vector2i GetSpriteCellSize();
sf::IntRect GetSpriteRect(unsigned int);
sf::Sprite GetSprite(unsigned int, sf::Vector2f = sf::Vector2f(0, 0), float = 0.0);
~GameConfiguration();
};
GameConfiguration::GameConfiguration()
{
LoadDefaultValues();
CalculateCommonValues();
}
GameConfiguration::GameConfiguration(std::string configurationPath)
{
if(!configurationPath.empty())
if(IsFileExists(configurationPath))
LoadValuesFromFile(configurationPath);
else
{
LoadDefaultValues();
WriteValuesToFile(configurationPath);
}
else
LoadDefaultValues();
CalculateCommonValues();
}
void GameConfiguration::CalculateCommonValues()
{
float offset;
sf::Vector2i gridDimensions = sf::Vector2i
(
gridSize.x * spriteSheetCellSize.x,
gridSize.y * spriteSheetCellSize.y
);
sf::Vector2f canvasSizeMultiplierRatio = sf::Vector2f
(
(float)windowDimensions.x / (float)gridDimensions.x,
(float)windowDimensions.y / (float)gridDimensions.y
);
if(canvasSizeMultiplierRatio.x < canvasSizeMultiplierRatio.y)
{
spriteSizeMultiplier = canvasSizeMultiplierRatio.x;
offset = gridDimensions.y * spriteSizeMultiplier - windowDimensions.y;
if(offset < 0) offset = -offset;
offset /= 2;
gridOffset = sf::Vector2i(0, offset);
}
else
{
spriteSizeMultiplier = canvasSizeMultiplierRatio.y;
offset = gridDimensions.x * spriteSizeMultiplier - windowDimensions.x;
if(offset < 0) offset = -offset;
offset /= 2;
gridOffset = sf::Vector2i(offset, 0);
}
// Center Origin Offset
gridOffset.x += spriteSheetCellSize.x / 2;
gridOffset.y += spriteSheetCellSize.y / 2;
spriteSheetRect = sf::IntRect(sf::Vector2i(0, 0), spriteSheetCellSize);
}
void GameConfiguration::NormalizeVector2f(sf::Vector2f &vector)
{
float magnitude = sqrt(vector.x * vector.x + vector.y * vector.y);
vector.x /= magnitude;
vector.y /= magnitude;
}
template <class T> T GameConfiguration::Clamp(T &value, T min, T max)
{
if(value < min) value = min;
else if(value > max) value = max;
return value;
}
bool GameConfiguration::IsFileExists(std::string path)
{
std::fstream file(path);
return file.good();
}
void GameConfiguration::LoadValuesFromFile(std::string path)
{
std::ifstream confFile(path);
std::istream &stream = confFile;
char coma; // This looks so stupid there has to be a better way
int bgColor[3];
GetNextNonCommentLine(stream) >> gridSize.x >> coma >> gridSize.y;
GetNextNonCommentLine(stream) >> tickPerSec;
GetNextNonCommentLine(stream) >> windowDimensions.x >> coma >> windowDimensions.y;
LoadSpriteSheet(GetNextNonCommentLine(stream).str());
GetNextNonCommentLine(stream) >> spriteSheetCellSize.x >> coma >> spriteSheetCellSize.y;
GetNextNonCommentLine(stream) >> audioVolume;
GetNextNonCommentLine(stream) >> fullscreen;
GetNextNonCommentLine(stream) >> bgColor[0] >> coma >> bgColor[1] >> coma >> bgColor[2];
Clamp(audioVolume);
Clamp(gridSize.x, 5, 100);
Clamp(gridSize.y, 5, 100);
backgroundColor.r = Clamp(bgColor[0], 0, 255);
backgroundColor.g = Clamp(bgColor[1], 0, 255);
backgroundColor.b = Clamp(bgColor[2], 0, 255);
if(fullscreen)
{
sf::VideoMode desktop = sf::VideoMode::getDesktopMode();
windowDimensions = sf::Vector2i(desktop.width, desktop.height);
}
confFile.close();
}
std::istringstream GameConfiguration::GetNextNonCommentLine(std::istream &stream)
{
std::string line;
while (std::getline(stream, line) && !stream.eof())
switch (line[0])
{
case '#': case '\n': case ' ': case NULL: break;
default:
return std::istringstream(line);
}
return std::istringstream();
}
void GameConfiguration::WriteValuesToFile(std::string path)
{
std::ofstream confFile(path);
confFile << "# Grid Size (x, y) (5 - 100)\n";
confFile << gridSize.x << ", " << gridSize.y << "\n\n";
confFile << "# Tick per Sec (1 - 60)\n";
confFile << tickPerSec << "\n\n";
confFile << "# Window Dimensions (x, y)\n";
confFile << "# If fullscreen set to 1 this will be skipped\n";
confFile << windowDimensions.x << ", " << windowDimensions.y << "\n\n";
confFile << "# Sprite Sheet Path\n";
confFile << spriteSheetPath << "\n\n";
confFile << "# Sprite Sheet Cell Size (x, y)\n";
confFile << spriteSheetCellSize.x << ", " << spriteSheetCellSize.y << "\n\n";
confFile << "# Audio Volume (0.0 - 1.0)\n";
confFile << audioVolume << "\n\n";
confFile << "# Fullscreen 1 = on, 0 = off\n";
confFile << fullscreen << "\n\n";
confFile << "# Background Color (r, g, b) (0 - 255)\n";
confFile << (int)backgroundColor.r << ", " << (int)backgroundColor.g << ", " << (int)backgroundColor.b << "\n";
confFile.close();
}
void GameConfiguration::LoadDefaultValues()
{
windowDimensions = sf::Vector2i(800, 600);
backgroundColor = sf::Color::White;
gridSize = sf::Vector2i(10, 10);
LoadSpriteSheet("Data\\SpriteSheet.png");
spriteSheetCellSize = sf::Vector2i(64, 64);
spriteSizeMultiplier = 1.0;
tickPerSec = 4;
fullscreen = false;
audioVolume = 1.0;
}
bool GameConfiguration::LoadSpriteSheet(std::string path)
{
spriteSheetPath = path;
return spriteSheet.loadFromFile(path);
}
sf::Sprite GameConfiguration::GetSprite(unsigned int index, sf::Vector2f position, float rotation)
{
sf::Sprite sprite;
sprite.setTexture(spriteSheet);
sprite.setTextureRect(GetSpriteRect(index));
sprite.setPosition(position);
sprite.setRotation(rotation);
sprite.setOrigin(spriteSheetCellSize.x / 2, spriteSheetCellSize.y / 2);
sprite.setScale(spriteSizeMultiplier, spriteSizeMultiplier);
return sprite;
}
sf::IntRect GameConfiguration::GetSpriteRect(unsigned int index)
{
int offset = spriteSheetRect.width * index;
int xSize = spriteSheet.getSize().x;
spriteSheetRect.left = offset % xSize;
spriteSheetRect.top = offset / xSize * spriteSheetCellSize.y;
return spriteSheetRect;
}
int GameConfiguration::GetTickPerSec()
{
return tickPerSec;
}
bool GameConfiguration::IsFullscreen()
{
return fullscreen;
}
sf::Vector2i GameConfiguration::GetGridSize()
{
return gridSize;
}
sf::Vector2i GameConfiguration::GetGridOffset()
{
return gridOffset;
}
sf::Vector2i GameConfiguration::GetSpriteCellSize()
{
return spriteSheetCellSize;
}
sf::Vector2i GameConfiguration::GetScreenDimensions()
{
return windowDimensions;
}
sf::Color GameConfiguration::GetBackgroundColor()
{
return backgroundColor;
}
float GameConfiguration::GetSpriteSizeMultiplier()
{
return spriteSizeMultiplier;
}
float GameConfiguration::GetAudioVolume()
{
return audioVolume;
}
GameConfiguration::~GameConfiguration()
{
}