implemented sound system and score
This commit is contained in:
parent
78779cccb9
commit
27d074401a
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -11,6 +11,6 @@ struct Fruit
|
||||||
sf::Vector2u gridPos{};
|
sf::Vector2u gridPos{};
|
||||||
Color color{};
|
Color color{};
|
||||||
|
|
||||||
sf::Vector2f windowPos(float gridSize_in);
|
sf::Vector2f windowPos(float gridSize_in) const;
|
||||||
void respawn(const std::vector<SnakeNode>& body_in, sf::Vector2u gridCount_in);
|
void respawn(const std::vector<SnakeNode>& body_in, sf::Vector2u gridCount_in);
|
||||||
};
|
};
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Util.h>
|
#include "Util.h"
|
||||||
#include <Player.h>
|
#include "Player.h"
|
||||||
#include <Fruit.h>
|
#include "Fruit.h"
|
||||||
#include <GameConfig.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>
|
||||||
|
|
||||||
|
enum class GameState
|
||||||
|
{
|
||||||
|
playing,
|
||||||
|
lose,
|
||||||
|
win
|
||||||
|
};
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
|
|
@ -51,6 +58,16 @@ private:
|
||||||
sf::Text score;
|
sf::Text score;
|
||||||
|
|
||||||
sf::SoundBuffer failSoundBuffer;
|
sf::SoundBuffer failSoundBuffer;
|
||||||
|
sf::SoundBuffer winSoundBuffer;
|
||||||
|
sf::SoundBuffer bgMusicBuffer;
|
||||||
|
sf::SoundBuffer eatSoundBuffer;
|
||||||
|
sf::SoundBuffer moveSoundBuffer;
|
||||||
|
|
||||||
|
sf::Sound failSound;
|
||||||
|
sf::Sound winSound;
|
||||||
|
sf::Sound bgMusic;
|
||||||
|
sf::Sound eatSound;
|
||||||
|
sf::Sound moveSound;
|
||||||
|
|
||||||
sf::RectangleShape tempRect;
|
sf::RectangleShape tempRect;
|
||||||
|
|
||||||
|
|
@ -62,6 +79,8 @@ private:
|
||||||
sf::Vector2u gridCount;
|
sf::Vector2u gridCount;
|
||||||
|
|
||||||
size_t frameCount{};
|
size_t frameCount{};
|
||||||
|
size_t fruitEaten{};
|
||||||
|
GameState state{GameState::playing};
|
||||||
bool useImgui;
|
bool useImgui;
|
||||||
bool fail{};
|
bool fail{};
|
||||||
bool win{};
|
bool win{};
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,5 @@ struct GameConfig
|
||||||
Color playerHeadColor;
|
Color playerHeadColor;
|
||||||
Color playerBodyColor;
|
Color playerBodyColor;
|
||||||
sf::Vector2u headGridStartPos;
|
sf::Vector2u headGridStartPos;
|
||||||
unsigned int gridSize;
|
float gridSize;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Random.h>
|
#include "Random.h"
|
||||||
#include <Color.h>
|
#include "Color.h"
|
||||||
#include <Math-util.h>
|
#include "Math-util.h"
|
||||||
|
|
@ -5,7 +5,7 @@ cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
if [ -z "$1" ] || [ $# -eq 0 ]
|
if [ -z "$1" ] || [ $# -eq 0 ]
|
||||||
then
|
then
|
||||||
./third-party/premake5/premake5 --config=Debug ecc
|
../third-party/premake5/premake5 --config=Debug ecc
|
||||||
else
|
else
|
||||||
./third-party/premake5/premake5 --config=$1 ecc
|
../third-party/premake5/premake5 --config=$1 ecc
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Fruit::Fruit(sf::Vector2i gridPos_in, const sf::Color& color_in)
|
||||||
, color(color_in)
|
, color(color_in)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
sf::Vector2f Fruit::windowPos(float gridSize_in)
|
sf::Vector2f Fruit::windowPos(float gridSize_in) const
|
||||||
{
|
{
|
||||||
return {gridPos.x * gridSize_in, gridPos.y * gridSize_in};
|
return {gridPos.x * gridSize_in, gridPos.y * gridSize_in};
|
||||||
}
|
}
|
||||||
|
|
@ -16,16 +16,17 @@ void Fruit::respawn(const std::vector<SnakeNode>& body_in, sf::Vector2u gridCoun
|
||||||
{
|
{
|
||||||
unsigned int tempX;
|
unsigned int tempX;
|
||||||
unsigned int tempY;
|
unsigned int tempY;
|
||||||
bool valid = false;
|
bool valid;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
valid = true;
|
||||||
tempX = Random::get(0, gridCount_in.x - 1);
|
tempX = Random::get(0, gridCount_in.x - 1);
|
||||||
tempY = Random::get(0, gridCount_in.y - 1);
|
tempY = Random::get(0, gridCount_in.y - 1);
|
||||||
for (const auto& node : body_in)
|
for (const auto& node : body_in)
|
||||||
{
|
{
|
||||||
if (node.gridPos.x != tempX and node.gridPos.y != tempY)
|
if (node.gridPos.x == tempX and node.gridPos.y == tempY)
|
||||||
{
|
{
|
||||||
valid = true;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!valid);
|
} while (!valid);
|
||||||
|
|
|
||||||
136
src/Game.cpp
136
src/Game.cpp
|
|
@ -10,12 +10,15 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
Game::Game(bool useImgui_in)
|
Game::Game(bool useImgui_in)
|
||||||
: config()
|
: config()
|
||||||
, window({sf::VideoMode({1920u, 1080u}), "project-snake"})
|
, window({sf::VideoMode({1920u, 1080u}), "project-snake"})
|
||||||
, font("assets/fonts/ChakraPetch-Regular.ttf")
|
|
||||||
, score(font)
|
, score(font)
|
||||||
|
, failSound(failSoundBuffer)
|
||||||
|
, winSound(winSoundBuffer)
|
||||||
|
, bgMusic(bgMusicBuffer)
|
||||||
|
, eatSound(eatSoundBuffer)
|
||||||
|
, moveSound(moveSoundBuffer)
|
||||||
, useImgui(useImgui_in)
|
, useImgui(useImgui_in)
|
||||||
{
|
{
|
||||||
if (!ImGui::SFML::Init(window))
|
if (!ImGui::SFML::Init(window))
|
||||||
|
|
@ -31,8 +34,8 @@ Game::Game(bool useImgui_in)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gridCount.x = window.getSize().x / config.gridSize;
|
gridCount.x = window.getSize().x / static_cast<unsigned int>(config.gridSize);
|
||||||
gridCount.y = window.getSize().y / config.gridSize;
|
gridCount.y = window.getSize().y / static_cast<unsigned int>(config.gridSize);
|
||||||
|
|
||||||
player.body.reserve(100);
|
player.body.reserve(100);
|
||||||
player.body.emplace_back(config.headGridStartPos);
|
player.body.emplace_back(config.headGridStartPos);
|
||||||
|
|
@ -40,6 +43,51 @@ Game::Game(bool useImgui_in)
|
||||||
fruit.gridPos = {5, 5};
|
fruit.gridPos = {5, 5};
|
||||||
fruit.color = sf::Color::Red;
|
fruit.color = sf::Color::Red;
|
||||||
|
|
||||||
|
if (!font.openFromFile("assets/fonts/ChakraPetch-Regular.ttf"))
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Failed to load font!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failSoundBuffer.loadFromFile("assets/sounds/lose.ogg"))
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!winSoundBuffer.loadFromFile("assets/sounds/win.ogg"))
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bgMusicBuffer.loadFromFile("assets/sounds/bgMusic.wav"))
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eatSoundBuffer.loadFromFile("assets/sounds/eat.wav"))
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!moveSoundBuffer.loadFromFile("assets/sounds/move.wav"))
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
failSound.setVolume(10.f);
|
||||||
|
winSound.setVolume(10.f);
|
||||||
|
bgMusic.setVolume(10.f);
|
||||||
|
eatSound.setVolume(10.f);
|
||||||
|
moveSound.setVolume(10.f);
|
||||||
|
|
||||||
|
bgMusic.setLooping(true);
|
||||||
|
bgMusic.play();
|
||||||
|
|
||||||
//uncomment to quickly test player movement
|
//uncomment to quickly test player movement
|
||||||
/*
|
/*
|
||||||
player.body.emplace_back(sf::Vector2i{config.headGridStartPos.x - 1, config.headGridStartPos.y});
|
player.body.emplace_back(sf::Vector2i{config.headGridStartPos.x - 1, config.headGridStartPos.y});
|
||||||
|
|
@ -48,14 +96,13 @@ Game::Game(bool useImgui_in)
|
||||||
player.body.emplace_back(sf::Vector2i{config.headGridStartPos.x - 4, config.headGridStartPos.y});
|
player.body.emplace_back(sf::Vector2i{config.headGridStartPos.x - 4, config.headGridStartPos.y});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tempRect.setSize(sf::Vector2f{(float)config.gridSize, (float)config.gridSize});
|
tempRect.setSize(sf::Vector2f{(config.gridSize), config.gridSize});
|
||||||
tempRect.setOutlineThickness(-5);
|
tempRect.setOutlineThickness(-5);
|
||||||
tempRect.setOutlineColor(sf::Color::Black);
|
tempRect.setOutlineColor(sf::Color::Black);
|
||||||
|
|
||||||
score.setPosition({10, static_cast<float>(window.getSize().y - 40)});
|
score.setPosition({10, static_cast<float>(window.getSize().y - 40)});
|
||||||
|
|
||||||
window.setFramerateLimit(config.framerate);
|
window.setFramerateLimit(config.framerate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Game::parseConfigFile()
|
bool Game::parseConfigFile()
|
||||||
|
|
@ -74,31 +121,37 @@ bool Game::parseConfigFile()
|
||||||
if (inputBuff == "framerate")
|
if (inputBuff == "framerate")
|
||||||
{
|
{
|
||||||
configFile >> config.framerate;
|
configFile >> config.framerate;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputBuff == "tickRate")
|
if (inputBuff == "tickRate")
|
||||||
{
|
{
|
||||||
configFile >> config.tickRate;
|
configFile >> config.tickRate;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputBuff == "playerHeadColor")
|
if (inputBuff == "playerHeadColor")
|
||||||
{
|
{
|
||||||
configFile >> config.playerHeadColor.r >> config.playerHeadColor.g >> config.playerHeadColor.b;
|
configFile >> config.playerHeadColor.r >> config.playerHeadColor.g >> config.playerHeadColor.b;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputBuff == "playerBodyColor")
|
if (inputBuff == "playerBodyColor")
|
||||||
{
|
{
|
||||||
configFile >> config.playerBodyColor.r >> config.playerBodyColor.g >> config.playerBodyColor.b;
|
configFile >> config.playerBodyColor.r >> config.playerBodyColor.g >> config.playerBodyColor.b;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputBuff == "headGridStartPos")
|
if (inputBuff == "headGridStartPos")
|
||||||
{
|
{
|
||||||
configFile >> config.headGridStartPos.x >> config.headGridStartPos.y;
|
configFile >> config.headGridStartPos.x >> config.headGridStartPos.y;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputBuff == "gridSize")
|
if (inputBuff == "gridSize")
|
||||||
{
|
{
|
||||||
configFile >> config.gridSize;
|
configFile >> config.gridSize;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,7 +244,8 @@ void Game::collision()
|
||||||
{
|
{
|
||||||
if (player.head().gridPos == player.body.at(i).gridPos)
|
if (player.head().gridPos == player.body.at(i).gridPos)
|
||||||
{
|
{
|
||||||
fail = true;
|
state = GameState::lose;
|
||||||
|
failSound.play();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -201,13 +255,14 @@ void Game::collision()
|
||||||
player.body.emplace_back(player.body.back().previousGridPos);
|
player.body.emplace_back(player.body.back().previousGridPos);
|
||||||
if (player.body.size() != (gridCount.x * gridCount.y))
|
if (player.body.size() != (gridCount.x * gridCount.y))
|
||||||
{
|
{
|
||||||
//play sound
|
eatSound.play();
|
||||||
|
player.score += 100;
|
||||||
fruit.respawn(player.body, gridCount);
|
fruit.respawn(player.body, gridCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//play win sound
|
state = GameState::win;
|
||||||
|
winSound.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,13 +292,16 @@ void Game::movement()
|
||||||
|
|
||||||
if (frameCount % config.tickRate != 0) return;
|
if (frameCount % config.tickRate != 0) return;
|
||||||
|
|
||||||
|
moveSound.play();
|
||||||
|
|
||||||
SnakeNode& head = player.head();
|
SnakeNode& head = player.head();
|
||||||
switch (player.inputBuffer)
|
switch (player.inputBuffer)
|
||||||
{
|
{
|
||||||
case Direction::up:
|
case Direction::up:
|
||||||
if (head.gridPos.y == 0)
|
if (head.gridPos.y == 0)
|
||||||
{
|
{
|
||||||
fail = true;
|
state = GameState::lose;
|
||||||
|
failSound.play();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,7 +314,8 @@ void Game::movement()
|
||||||
case Direction::down:
|
case Direction::down:
|
||||||
if (head.gridPos.y == gridCount.y - 1)
|
if (head.gridPos.y == gridCount.y - 1)
|
||||||
{
|
{
|
||||||
fail = true;
|
state = GameState::lose;
|
||||||
|
failSound.play();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,7 +328,8 @@ void Game::movement()
|
||||||
case Direction::left:
|
case Direction::left:
|
||||||
if (head.gridPos.x == 0)
|
if (head.gridPos.x == 0)
|
||||||
{
|
{
|
||||||
fail = true;
|
state = GameState::lose;
|
||||||
|
failSound.play();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,7 +342,8 @@ void Game::movement()
|
||||||
case Direction::right:
|
case Direction::right:
|
||||||
if (head.gridPos.x == gridCount.x -1)
|
if (head.gridPos.x == gridCount.x -1)
|
||||||
{
|
{
|
||||||
fail = true;
|
state = GameState::lose;
|
||||||
|
failSound.play();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,12 +395,12 @@ void Game::render()
|
||||||
for (auto& node : player.body)
|
for (auto& node : player.body)
|
||||||
{
|
{
|
||||||
tempRect.setFillColor(node.color.sfml());
|
tempRect.setFillColor(node.color.sfml());
|
||||||
tempRect.setPosition(node.windowPos((float)config.gridSize));
|
tempRect.setPosition(node.windowPos(config.gridSize));
|
||||||
window.draw(tempRect);
|
window.draw(tempRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
tempRect.setFillColor(fruit.color.sfml());
|
tempRect.setFillColor(fruit.color.sfml());
|
||||||
tempRect.setPosition(fruit.windowPos((float)config.gridSize));
|
tempRect.setPosition(fruit.windowPos(config.gridSize));
|
||||||
window.draw(tempRect);
|
window.draw(tempRect);
|
||||||
|
|
||||||
score.setString("Score: " + std::to_string(player.score));
|
score.setString("Score: " + std::to_string(player.score));
|
||||||
|
|
@ -353,11 +414,12 @@ void Game::render()
|
||||||
|
|
||||||
void Game::soundSystem()
|
void Game::soundSystem()
|
||||||
{
|
{
|
||||||
|
if (state != GameState::playing)
|
||||||
}
|
|
||||||
|
|
||||||
void Game::scoreSystem()
|
|
||||||
{
|
{
|
||||||
|
bgMusic.stop();
|
||||||
|
eatSound.stop();
|
||||||
|
moveSound.stop();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,22 +427,30 @@ void Game::resetGame()
|
||||||
{
|
{
|
||||||
player.body.clear();
|
player.body.clear();
|
||||||
player.body.emplace_back(config.headGridStartPos);
|
player.body.emplace_back(config.headGridStartPos);
|
||||||
fail = false;
|
|
||||||
player.facing = Direction::up;
|
player.facing = Direction::up;
|
||||||
|
|
||||||
|
fruit.respawn(player.body, gridCount);
|
||||||
|
|
||||||
|
state = GameState::playing;
|
||||||
|
bgMusic.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::failState()
|
void Game::failState()
|
||||||
{
|
{
|
||||||
// if (failSound.getStatus() == sf::Sound::Status::Stopped)
|
if (failSound.getStatus() == sf::Sound::Status::Stopped)
|
||||||
// {
|
{
|
||||||
// resetGame();
|
resetGame();
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::winState()
|
void Game::winState()
|
||||||
{
|
{
|
||||||
|
if (winSound.getStatus() == sf::Sound::Status::Stopped)
|
||||||
|
{
|
||||||
|
resetGame();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::run()
|
void Game::run()
|
||||||
|
|
@ -393,21 +463,19 @@ void Game::run()
|
||||||
|
|
||||||
input();
|
input();
|
||||||
|
|
||||||
if (!fail and !win)
|
if (state == GameState::playing)
|
||||||
{
|
{
|
||||||
movement();
|
movement();
|
||||||
|
|
||||||
collision();
|
collision();
|
||||||
|
|
||||||
soundSystem();
|
soundSystem();
|
||||||
|
|
||||||
scoreSystem();
|
|
||||||
}
|
}
|
||||||
else if (fail)
|
else if (state == GameState::lose)
|
||||||
{
|
{
|
||||||
failState();
|
failState();
|
||||||
}
|
}
|
||||||
else if (win)
|
else if (state == GameState::win)
|
||||||
{
|
{
|
||||||
winState();
|
winState();
|
||||||
}
|
}
|
||||||
|
|
@ -420,3 +488,7 @@ void Game::run()
|
||||||
|
|
||||||
ImGui::SFML::Shutdown();
|
ImGui::SFML::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
@ -5,7 +5,7 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
// parse command-line arguments
|
// parse command-line arguments
|
||||||
bool useImgui{true};
|
bool useImgui{true};
|
||||||
for (int i = 0; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (!strcmp(argv[i], "--noImgui"))
|
if (!strcmp(argv[i], "--noImgui"))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue