parent
de9b81cf26
commit
a3d6742d98
|
|
@ -1,4 +1,11 @@
|
||||||
framerate 60
|
framerate 60
|
||||||
|
|
||||||
playerColor 1 1 1
|
tickRate 60
|
||||||
|
|
||||||
|
playerHeadColor 1 1 1
|
||||||
|
|
||||||
|
playerBodyColor 1 1 1
|
||||||
|
|
||||||
|
headGridStartPos 10 10
|
||||||
|
|
||||||
|
gridSize 50
|
||||||
|
|
@ -1,36 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <Util.h>
|
#include <Util.h>
|
||||||
|
#include <Player.h>
|
||||||
|
#include <GameConfig.h>
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <SFML/Audio.hpp>
|
#include <SFML/Audio.hpp>
|
||||||
#include <imgui-SFML.h>
|
#include <imgui-SFML.h>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
|
|
||||||
class SnakeNode
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Player
|
|
||||||
{
|
|
||||||
Player() = default;
|
|
||||||
Player(sf::Vector2i gridPos_in);
|
|
||||||
|
|
||||||
sf::Vector2i gridPos{};
|
|
||||||
sf::Vector2i previousGridPos{};
|
|
||||||
sf::Vector2f windowPos{};
|
|
||||||
int score{};
|
|
||||||
int lives{3};
|
|
||||||
bool left{false};
|
|
||||||
bool right{false};
|
|
||||||
bool up{false};
|
|
||||||
bool down{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -38,6 +16,8 @@ public:
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
bool init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void imgui();
|
void imgui();
|
||||||
|
|
||||||
|
|
@ -57,19 +37,26 @@ private:
|
||||||
|
|
||||||
void scoreSystem();
|
void scoreSystem();
|
||||||
|
|
||||||
|
void failState();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
GameConfig config;
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
sf::RenderWindow window;
|
sf::RenderWindow window;
|
||||||
sf::Font font;
|
sf::Font font;
|
||||||
sf::Text lives;
|
|
||||||
sf::Text score;
|
sf::Text score;
|
||||||
|
|
||||||
Player player;
|
sf::SoundBuffer failSoundBuffer;
|
||||||
|
|
||||||
// mostly used for imgui
|
sf::RectangleShape tempRect;
|
||||||
int framerate{};
|
|
||||||
float volume{};
|
//sf::Sound failSound;
|
||||||
|
|
||||||
|
Player player{};
|
||||||
|
|
||||||
|
size_t frameCount{};
|
||||||
bool useImgui;
|
bool useImgui;
|
||||||
static constexpr unsigned int numPhysicsUpdates{4};
|
bool fail;
|
||||||
|
bool running{true};
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <Util.h>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
struct GameConfig
|
||||||
|
{
|
||||||
|
float volume{10};
|
||||||
|
int tickRate{};
|
||||||
|
int framerate{};
|
||||||
|
Color playerHeadColor;
|
||||||
|
Color playerBodyColor;
|
||||||
|
sf::Vector2i headGridStartPos;
|
||||||
|
float gridSize;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include <Util.h>
|
||||||
|
|
||||||
|
enum class Direction
|
||||||
|
{
|
||||||
|
up,
|
||||||
|
down,
|
||||||
|
left,
|
||||||
|
right
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SnakeNode
|
||||||
|
{
|
||||||
|
SnakeNode(sf::Vector2i gridPos_in, sf::Color color_in = sf::Color::White);
|
||||||
|
sf::Vector2f windowPos{};
|
||||||
|
sf::Vector2i gridPos{};
|
||||||
|
sf::Vector2i previousGridPos{};
|
||||||
|
Color color{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Player
|
||||||
|
{
|
||||||
|
Player() = default;
|
||||||
|
|
||||||
|
SnakeNode& head();
|
||||||
|
|
||||||
|
std::vector<SnakeNode> body;
|
||||||
|
|
||||||
|
int score{};
|
||||||
|
Direction facing{Direction::up};
|
||||||
|
Direction inputBuffer{};
|
||||||
|
bool left{false};
|
||||||
|
bool right{false};
|
||||||
|
bool up{false};
|
||||||
|
bool down{false};
|
||||||
|
};
|
||||||
154
src/Game.cpp
154
src/Game.cpp
|
|
@ -12,22 +12,36 @@
|
||||||
|
|
||||||
|
|
||||||
Game::Game(bool useImgui_in)
|
Game::Game(bool useImgui_in)
|
||||||
: window({sf::VideoMode({ 1920u, 1080u }), "project-breakout"})
|
: config()
|
||||||
|
, window({sf::VideoMode({ 1920u, 1080u }), "project-snake"})
|
||||||
, font("assets/fonts/ChakraPetch-Regular.ttf")
|
, font("assets/fonts/ChakraPetch-Regular.ttf")
|
||||||
, lives(font)
|
|
||||||
, score(font)
|
, score(font)
|
||||||
, volume(10)
|
|
||||||
, useImgui(useImgui_in)
|
, useImgui(useImgui_in)
|
||||||
{
|
{
|
||||||
|
if (!ImGui::SFML::Init(window))
|
||||||
|
{
|
||||||
|
std::cout << "ERROR: Could not open window\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ImGui::SFML::Init(window)) return;
|
if (!parseConfigFile())
|
||||||
|
{
|
||||||
|
std::cout << "ERROR: Could not parse config file\n";
|
||||||
|
window.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!parseConfigFile()) return;
|
player.body.reserve(100);
|
||||||
|
player.body.emplace_back(config.headGridStartPos);
|
||||||
|
player.head().windowPos.x = player.head().gridPos.x * config.gridSize;
|
||||||
|
player.head().windowPos.y = player.head().gridPos.y * config.gridSize;
|
||||||
|
|
||||||
lives.setPosition({10, static_cast<float>(window.getSize().y - 40)});
|
tempRect.setSize({config.gridSize, config.gridSize});
|
||||||
score.setPosition({10, static_cast<float>(window.getSize().y - 80)});
|
tempRect.setOutlineThickness(5);
|
||||||
|
|
||||||
window.setFramerateLimit(framerate);
|
score.setPosition({10, static_cast<float>(window.getSize().y - 40)});
|
||||||
|
|
||||||
|
window.setFramerateLimit(config.framerate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,7 +58,35 @@ bool Game::parseConfigFile()
|
||||||
std::string inputBuff;
|
std::string inputBuff;
|
||||||
while(configFile >> inputBuff)
|
while(configFile >> inputBuff)
|
||||||
{
|
{
|
||||||
|
if (inputBuff == "framerate")
|
||||||
|
{
|
||||||
|
configFile >> config.framerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputBuff == "tickRate")
|
||||||
|
{
|
||||||
|
configFile >> config.tickRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputBuff == "playerHeadColor")
|
||||||
|
{
|
||||||
|
configFile >> config.playerHeadColor.r >> config.playerHeadColor.g >> config.playerHeadColor.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputBuff == "playerBodyColor")
|
||||||
|
{
|
||||||
|
configFile >> config.playerBodyColor.r >> config.playerBodyColor.g >> config.playerBodyColor.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputBuff == "headGridStartPos")
|
||||||
|
{
|
||||||
|
configFile >> config.headGridStartPos.x >> config.headGridStartPos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputBuff == "gridSize")
|
||||||
|
{
|
||||||
|
configFile >> config.gridSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -131,18 +173,83 @@ void Game::input()
|
||||||
|
|
||||||
void Game::collision()
|
void Game::collision()
|
||||||
{
|
{
|
||||||
|
const size_t limit = player.body.size();
|
||||||
|
for (size_t i = 1; i < limit; i++)
|
||||||
|
{
|
||||||
|
if (player.head().gridPos == player.body.at(i).gridPos)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
//failSound.play();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::movement()
|
void Game::movement()
|
||||||
{
|
{
|
||||||
|
if (player.left and !player.right and (player.facing == Direction::up or player.facing == Direction::down))
|
||||||
|
{
|
||||||
|
player.inputBuffer = Direction::left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.right and !player.left and (player.facing == Direction::up or player.facing == Direction::down))
|
||||||
|
{
|
||||||
|
player.inputBuffer = Direction::right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.up and !player.down and (player.facing == Direction::left or player.facing == Direction::right))
|
||||||
|
{
|
||||||
|
player.inputBuffer = Direction::up;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.down and !player.up and (player.facing == Direction::left or player.facing == Direction::right))
|
||||||
|
{
|
||||||
|
player.inputBuffer = Direction::down;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frameCount % config.tickRate != 0) return;
|
||||||
|
|
||||||
|
switch (player.inputBuffer)
|
||||||
|
{
|
||||||
|
case Direction::up:
|
||||||
|
player.head().previousGridPos = player.head().gridPos;
|
||||||
|
player.head().gridPos += sf::Vector2i{ 0, -1 };
|
||||||
|
player.facing = Direction::up;
|
||||||
|
// std::cout << "up\n";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Direction::down:
|
||||||
|
player.head().previousGridPos = player.head().gridPos;
|
||||||
|
player.head().gridPos += sf::Vector2i{ 0, 1 };
|
||||||
|
player.facing = Direction::down;
|
||||||
|
// std::cout << "down\n";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Direction::left:
|
||||||
|
player.head().previousGridPos = player.head().gridPos;
|
||||||
|
player.head().gridPos += sf::Vector2i{ -1, 0 };
|
||||||
|
player.facing = Direction::left;
|
||||||
|
// std::cout << "left\n";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Direction::right:
|
||||||
|
player.head().previousGridPos = player.head().gridPos;
|
||||||
|
player.head().gridPos += sf::Vector2i{ 1, 0 };
|
||||||
|
player.facing = Direction::right;
|
||||||
|
// std::cout << "right\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.head().windowPos.x = player.head().gridPos.x * config.gridSize;
|
||||||
|
player.head().windowPos.y = player.head().gridPos.y * config.gridSize;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::imgui()
|
void Game::imgui()
|
||||||
{
|
{
|
||||||
ImGui::SetNextWindowCollapsed(false, ImGuiCond_Once);
|
ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once);
|
||||||
ImGui::SetNextWindowSize({490,375}, ImGuiCond_Once);
|
ImGui::SetNextWindowSize({490,375}, ImGuiCond_Once);
|
||||||
ImGui::SetNextWindowPos({26,29}, ImGuiCond_Once);
|
ImGui::SetNextWindowPos({26,29}, ImGuiCond_Once);
|
||||||
if(!ImGui::Begin("menu"))
|
if(!ImGui::Begin("menu"))
|
||||||
|
|
@ -156,7 +263,7 @@ void Game::imgui()
|
||||||
ImGui::Text("R: reset game");
|
ImGui::Text("R: reset game");
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
|
|
||||||
if (ImGui::SliderFloat("Game Volume", &volume, 0, 100, "%.1f"))
|
if (ImGui::SliderFloat("Game Volume", &config.volume, 0, 100, "%.1f"))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -169,10 +276,15 @@ void Game::render()
|
||||||
{
|
{
|
||||||
window.clear();
|
window.clear();
|
||||||
|
|
||||||
lives.setString("Lives: " + std::to_string(player.lives));
|
for (auto& node : player.body)
|
||||||
|
{
|
||||||
|
tempRect.setFillColor(node.color.sfml());
|
||||||
|
tempRect.setPosition(node.windowPos);
|
||||||
|
window.draw(tempRect);
|
||||||
|
}
|
||||||
|
|
||||||
score.setString("Score: " + std::to_string(player.score));
|
score.setString("Score: " + std::to_string(player.score));
|
||||||
|
|
||||||
window.draw(lives);
|
|
||||||
window.draw(score);
|
window.draw(score);
|
||||||
|
|
||||||
ImGui::SFML::Render(window);
|
ImGui::SFML::Render(window);
|
||||||
|
|
@ -195,14 +307,27 @@ void Game::resetGame()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::failState()
|
||||||
|
{
|
||||||
|
// if (failSound.getStatus() == sf::Sound::Status::Stopped)
|
||||||
|
// {
|
||||||
|
// resetGame();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
void Game::run()
|
void Game::run()
|
||||||
{
|
{
|
||||||
while(window.isOpen())
|
while(window.isOpen())
|
||||||
{
|
{
|
||||||
ImGui::SFML::Update(window, clock.restart());
|
ImGui::SFML::Update(window, clock.restart());
|
||||||
|
|
||||||
|
frameCount++;
|
||||||
|
|
||||||
input();
|
input();
|
||||||
|
|
||||||
|
if (!fail)
|
||||||
|
{
|
||||||
movement();
|
movement();
|
||||||
|
|
||||||
collision();
|
collision();
|
||||||
|
|
@ -210,6 +335,11 @@ void Game::run()
|
||||||
soundSystem();
|
soundSystem();
|
||||||
|
|
||||||
scoreSystem();
|
scoreSystem();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
failState();
|
||||||
|
}
|
||||||
|
|
||||||
imgui();
|
imgui();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <Player.h>
|
||||||
|
|
||||||
|
SnakeNode::SnakeNode(sf::Vector2i gridPos_in, sf::Color color_in)
|
||||||
|
: gridPos(gridPos_in)
|
||||||
|
, color(color_in)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
SnakeNode& Player::head()
|
||||||
|
{
|
||||||
|
return body[0];
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,6 @@ int main(int argc, char* argv[])
|
||||||
useImgui = false;
|
useImgui = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Game game(useImgui);
|
Game game(useImgui);
|
||||||
|
|
||||||
game.run();
|
game.run();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue