Basic Movements

Basic Movement
Interface classes renamed
Fixed few bugs
This commit is contained in:
Syntriax 2020-06-09 20:12:26 +03:00
parent 3b8affae37
commit 8341d82660
9 changed files with 255 additions and 23 deletions

View File

@ -1,6 +1,6 @@
#include "SynEngine.hpp"
class Cell : public Drawable
class Cell : public IDrawable
{
private:
unsigned int spriteIndex;

View File

@ -1,39 +1,68 @@
#include "SynEngine.hpp"
class GameConfiguration;
class Grid;
class GameManager
{
private:
static GameConfiguration *config;
static unsigned lastInputDirection;
static sf::Vector2i lastInputVector;
static Grid *grid;
public:
static Timer timer;
static void KeyPress(sf::Keyboard::Key);
static void SetConfig(GameConfiguration &);
static GameConfiguration *GetConfig();
static void SetGrid(Grid &);
static Grid &GetGrid();
static sf::Vector2i GetInputVector();
static unsigned GetInputDirection();
};
GameConfiguration *GameManager::config = NULL;
Grid *GameManager::grid = NULL;
unsigned GameManager::lastInputDirection = 0;
sf::Vector2i GameManager::lastInputVector = sf::Vector2i(1, 0);
void GameManager::KeyPress(sf::Keyboard::Key keycode)
{
switch (keycode)
{
case sf::Keyboard::Key::Right: case sf::Keyboard::Key::D: GameManager::lastInputDirection = 0; break;
case sf::Keyboard::Key::Down: case sf::Keyboard::Key::S: GameManager::lastInputDirection = 1; break;
case sf::Keyboard::Key::Left: case sf::Keyboard::Key::A: GameManager::lastInputDirection = 2; break;
case sf::Keyboard::Key::Up: case sf::Keyboard::Key::W: GameManager::lastInputDirection = 3; break;
case sf::Keyboard::Key::Up: case sf::Keyboard::Key::W: GameManager::lastInputDirection = 3; GameManager::lastInputVector = sf::Vector2i(0, 1); break;
case sf::Keyboard::Key::Left: case sf::Keyboard::Key::A: GameManager::lastInputDirection = 2; GameManager::lastInputVector = sf::Vector2i(-1, 0); break;
case sf::Keyboard::Key::Down: case sf::Keyboard::Key::S: GameManager::lastInputDirection = 1; GameManager::lastInputVector = sf::Vector2i(0, -1); break;
case sf::Keyboard::Key::Right: case sf::Keyboard::Key::D: GameManager::lastInputDirection = 0; GameManager::lastInputVector = sf::Vector2i(1, 0); break;
}
}
sf::Vector2i GameManager::GetInputVector()
{
return GameManager::lastInputVector;
}
unsigned GameManager::GetInputDirection()
{
return GameManager::lastInputDirection;
}
void GameManager::SetConfig(GameConfiguration &config)
{
GameManager::config = &config;
}
GameConfiguration *GameManager::GetConfig()
{
return GameManager::config;
}
void GameManager::SetGrid(Grid &grid)
{
GameManager::grid = &grid;
}
Grid &GameManager::GetGrid()
{
return *GameManager::grid;
}

View File

@ -1,5 +1,7 @@
#include "SynEngine.hpp"
Timer GameManager::timer;
class GameWindow
{
private:
@ -8,17 +10,20 @@ class GameWindow
std::string title;
sf::Uint32 style;
sf::RenderWindow window;
Timer timer;
Timer *timer;
GameConfiguration *config;
Drawable *drawable;
void (Drawable::*draw)(sf::RenderWindow *);
IDrawable *drawable;
void (IDrawable::*draw)(sf::RenderWindow *);
IBehaviour *behaviour;
void (IBehaviour::*behaviourUpdate)();
bool isFocused;
bool fullscreen;
void CreateWindow();
void CloseWindow();
public:
GameWindow(std::string = "Window", sf::Uint32 = sf::Style::Titlebar | sf::Style::Close);
void BindDrawable(Drawable *, void (Drawable::*)(sf::RenderWindow *));
void BindDrawable(IDrawable *, void (IDrawable::*)(sf::RenderWindow *));
void BindBehaviour(IBehaviour *, void (IBehaviour::*)());
void Update();
bool IsOpen();
~GameWindow();
@ -39,13 +44,17 @@ void GameWindow::Update()
break;
}
timer.UpdateTime();
timer -> UpdateTime();
if(!isFocused)
return;
window.clear(config -> GetBackgroundColor());
((drawable)->*(draw))(&window);
if(behaviour)
((behaviour)->*(behaviourUpdate))();
if(drawable)
((drawable)->*(draw))(&window);
window.display();
}
@ -59,7 +68,8 @@ void GameWindow::CreateWindow()
window.create(videoMode, title, fullscreen ? sf::Style::Fullscreen : style);
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(60);
timer.ResetTimer();
timer = &GameManager::timer;
timer -> ResetTimer();
}
void GameWindow::CloseWindow()
@ -70,12 +80,18 @@ void GameWindow::CloseWindow()
window.close();
}
void GameWindow::BindDrawable(Drawable *drawable, void (Drawable::*draw)(sf::RenderWindow *))
void GameWindow::BindDrawable(IDrawable *drawable, void (IDrawable::*draw)(sf::RenderWindow *))
{
this -> drawable = drawable;
this -> draw = draw;
}
void GameWindow::BindBehaviour(IBehaviour *behaviour, void (IBehaviour::*behaviourUpdate)())
{
this -> behaviour = behaviour;
this -> behaviourUpdate = behaviourUpdate;
}
GameWindow::GameWindow(std::string title, sf::Uint32 style)
{
config = GameManager::GetConfig();

View File

@ -1,6 +1,6 @@
#include "SynEngine.hpp"
class Grid : public Drawable
class Grid : public IDrawable
{
private:
sf::Vector2i offset;
@ -12,7 +12,7 @@ class Grid : public Drawable
public:
Grid();
bool SetGrid();
void UpdateCell(unsigned int, unsigned int, unsigned int, int = -1);
void UpdateCell(int, int, unsigned int, int = -1);
void Draw(sf::RenderWindow *);
~Grid();
};
@ -63,8 +63,10 @@ bool Grid::SetGrid()
return true;
}
void Grid::UpdateCell(unsigned int x, unsigned int y, unsigned int spriteIndex, int direction)
void Grid::UpdateCell(int x, int y, unsigned int spriteIndex, int direction)
{
x %= gridSize.x; if(x < 0) x += gridSize.x;
y %= gridSize.y; if(y < 0) y += gridSize.y;
int index = x + gridSize.x * y;
Cell *cell = cellArray + index;

7
IBehaviour.hpp Normal file
View File

@ -0,0 +1,7 @@
#include "SynEngine.hpp"
class IBehaviour
{
public:
virtual void Update() = 0;
};

View File

@ -1,6 +1,6 @@
#include "SynEngine.hpp"
class Drawable
class IDrawable
{
public:
virtual void Draw(sf::RenderWindow *) = 0;

175
Snake.hpp Normal file
View File

@ -0,0 +1,175 @@
#include "SynEngine.hpp"
enum PlayerSprite
{
Empty,
Point,
Straight,
Curved,
Back,
Head,
PointGot,
GameOver
};
struct SnakePart
{
sf::Vector2i cellPosition;
unsigned direction;
};
class Snake : public IBehaviour
{
private:
std::vector<SnakePart> snake;
unsigned int lenght;
SnakePart *head;
Timer *timer;
Grid *grid;
float timeCountdown;
float timeResetValue;
unsigned TickPerSec;
GameConfiguration *config;
void Move();
void Grow();
unsigned GetDirection(sf::Vector2i, sf::Vector2i);
unsigned GetBackDirection();
sf::Vector2i GetDirectionVector(unsigned);
PlayerSprite GetNewSprite(unsigned &);
public:
Snake();
void Update();
~Snake();
};
Snake::Snake()
{
TickPerSec = 4;
timeResetValue = 1.0 / (float)TickPerSec;
timeCountdown = timeResetValue;
lenght = 2;
snake.reserve(lenght);
for (unsigned i = 0; i < lenght; i++)
snake.push_back({ sf::Vector2i(1 - i, 0), 0});
timer = &GameManager::timer;
head = &snake[0];
config = GameManager::GetConfig();
grid = &GameManager::GetGrid();
grid -> UpdateCell(snake[0].cellPosition.x, snake[0].cellPosition.y, PlayerSprite::Head, 0);
grid -> UpdateCell(snake[1].cellPosition.x, snake[1].cellPosition.y, PlayerSprite::Straight, 0);
}
void Snake::Move()
{
sf::Vector2i *backPosition = &snake[lenght - 1].cellPosition;
sf::Vector2i *secondPosition = &snake[1].cellPosition;
sf::Vector2i headPosition = head -> cellPosition;
unsigned direction;
unsigned headDirection;
PlayerSprite sprite;
grid -> UpdateCell(backPosition -> x, -backPosition -> y, PlayerSprite::Empty);
headDirection = head -> direction;
snake.pop_back();
// Check if the new direction is opposite to the head's direction
if((GameManager::GetInputDirection() + 2) % 4 == headDirection)
headPosition += GetDirectionVector(headDirection);
else
{
headPosition += GameManager::GetInputVector();
headDirection = GameManager::GetInputDirection();
}
snake.insert(snake.begin(), { headPosition, headDirection });
direction = snake[1].direction;
sprite = GetNewSprite(direction);
grid -> UpdateCell(headPosition.x, -headPosition.y, PlayerSprite::Head, headDirection);
grid -> UpdateCell(secondPosition -> x, -secondPosition -> y, sprite, (int)direction);
grid -> UpdateCell(backPosition -> x, -backPosition -> y, PlayerSprite::Back, GetBackDirection());
}
void Snake::Update()
{
if(timeCountdown > 0.0)
{
timeCountdown -= timer -> GetDeltaTime();
return;
}
Move();
timeCountdown = timeResetValue;
}
sf::Vector2i Snake::GetDirectionVector(unsigned direction)
{
switch (direction)
{
case 0: return sf::Vector2i(1, 0);
case 1: return sf::Vector2i(0, -1);
case 2: return sf::Vector2i(-1, 0);
case 3: return sf::Vector2i(0, 1);
default: return sf::Vector2i(1, 0);
}
}
PlayerSprite Snake::GetNewSprite(unsigned &direction)
{
SnakePart *third = &snake[2];
SnakePart *second = &snake[1];
sf::Vector2i vector = third -> cellPosition - head -> cellPosition;
unsigned newDirection = GameManager::GetInputDirection();
// I need to update this. It look so bad
if(vector.x != 0 && vector.y != 0)
{
direction += 2;
direction %= 4;
if(direction > newDirection)
{
unsigned temp;
temp = direction;
direction = newDirection;
newDirection = temp;
}
// 0 - 1 -> 0
// 1 - 2 -> 1
// 2 - 3 -> 2
// 0 - 3 -> 3
if(direction == 0 && newDirection == 3)
direction = 3;
return PlayerSprite::Curved;
}
direction = GetDirection(head -> cellPosition, second -> cellPosition);
return PlayerSprite::Straight;
}
unsigned Snake::GetDirection(sf::Vector2i first, sf::Vector2i second)
{
first -= second;
if(first.x > 0) return 0;
if(first.y < 0) return 1;
if(first.x < 0) return 2;
if(first.y > 0) return 3;
return 0;
}
unsigned Snake::GetBackDirection()
{
return GetDirection(snake[lenght - 2].cellPosition, snake[lenght - 1].cellPosition);
}
Snake::~Snake()
{
}

View File

@ -4,12 +4,15 @@
#include <sstream>
#include <fstream>
#include <cmath>
#include <vector>
#include <SFML/Graphics.hpp>
#include "Timer.hpp"
#include "GameManager.hpp"
#include "GameConfiguration.hpp"
#include "Drawable.hpp"
#include "IDrawable.hpp"
#include "Cell.hpp"
#include "Grid.hpp"
#include "IBehaviour.hpp"
#include "Snake.hpp"
#include "GameWindow.hpp"
#endif

View File

@ -6,12 +6,12 @@ int main(int argc, char const *argv[])
GameManager::SetConfig(config);
GameWindow window("Long Starlight");
Grid grid = Grid();
GameManager::SetGrid(grid);
grid.SetGrid();
window.BindDrawable(&grid, &Drawable::Draw);
Snake player;
grid.UpdateCell(0, 0, 2);
grid.UpdateCell(0, 1, 2, 1);
window.BindDrawable(&grid, &IDrawable::Draw);
window.BindBehaviour(&player, &IBehaviour::Update);
while (window.IsOpen())
window.Update();