parent
de9b81cf26
commit
a3d6742d98
|
|
@ -1,4 +1,11 @@
|
|||
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
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Util.h>
|
||||
|
||||
#include <Player.h>
|
||||
#include <GameConfig.h>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <imgui-SFML.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
|
||||
{
|
||||
public:
|
||||
|
|
@ -38,6 +16,8 @@ public:
|
|||
|
||||
void run();
|
||||
|
||||
bool init();
|
||||
|
||||
private:
|
||||
void imgui();
|
||||
|
||||
|
|
@ -57,19 +37,26 @@ private:
|
|||
|
||||
void scoreSystem();
|
||||
|
||||
void failState();
|
||||
|
||||
|
||||
private:
|
||||
GameConfig config;
|
||||
sf::Clock clock;
|
||||
sf::RenderWindow window;
|
||||
sf::Font font;
|
||||
sf::Text lives;
|
||||
sf::Text score;
|
||||
|
||||
Player player;
|
||||
sf::SoundBuffer failSoundBuffer;
|
||||
|
||||
// mostly used for imgui
|
||||
int framerate{};
|
||||
float volume{};
|
||||
sf::RectangleShape tempRect;
|
||||
|
||||
//sf::Sound failSound;
|
||||
|
||||
Player player{};
|
||||
|
||||
size_t frameCount{};
|
||||
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};
|
||||
};
|
||||
162
src/Game.cpp
162
src/Game.cpp
|
|
@ -12,22 +12,36 @@
|
|||
|
||||
|
||||
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")
|
||||
, lives(font)
|
||||
, score(font)
|
||||
, volume(10)
|
||||
, 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)});
|
||||
score.setPosition({10, static_cast<float>(window.getSize().y - 80)});
|
||||
tempRect.setSize({config.gridSize, config.gridSize});
|
||||
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;
|
||||
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;
|
||||
|
|
@ -131,18 +173,83 @@ void Game::input()
|
|||
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
ImGui::SetNextWindowCollapsed(false, ImGuiCond_Once);
|
||||
ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once);
|
||||
ImGui::SetNextWindowSize({490,375}, ImGuiCond_Once);
|
||||
ImGui::SetNextWindowPos({26,29}, ImGuiCond_Once);
|
||||
if(!ImGui::Begin("menu"))
|
||||
|
|
@ -156,7 +263,7 @@ void Game::imgui()
|
|||
ImGui::Text("R: reset game");
|
||||
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();
|
||||
|
||||
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));
|
||||
|
||||
window.draw(lives);
|
||||
window.draw(score);
|
||||
|
||||
ImGui::SFML::Render(window);
|
||||
|
|
@ -195,21 +307,39 @@ void Game::resetGame()
|
|||
|
||||
}
|
||||
|
||||
void Game::failState()
|
||||
{
|
||||
// if (failSound.getStatus() == sf::Sound::Status::Stopped)
|
||||
// {
|
||||
// resetGame();
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
void Game::run()
|
||||
{
|
||||
while(window.isOpen())
|
||||
{
|
||||
ImGui::SFML::Update(window, clock.restart());
|
||||
|
||||
frameCount++;
|
||||
|
||||
input();
|
||||
|
||||
movement();
|
||||
if (!fail)
|
||||
{
|
||||
movement();
|
||||
|
||||
collision();
|
||||
collision();
|
||||
|
||||
soundSystem();
|
||||
soundSystem();
|
||||
|
||||
scoreSystem();
|
||||
scoreSystem();
|
||||
}
|
||||
else
|
||||
{
|
||||
failState();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Game game(useImgui);
|
||||
|
||||
game.run();
|
||||
|
|
|
|||
Loading…
Reference in New Issue