Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //main.cpp
- #define DEBUG /*Enable debugging*/
- #include "GameManager.h"
- #include <ctime> /*For time()*/
- const int BLOCK_SIZE = 10;
- const int SCREEN_WIDTH = 500;
- const int SCREEN_HEIGHT = 500;
- int main( int argc, char** argv )
- {
- /*Set seed for random number generation*/
- srand(static_cast<unsigned int>(time(0)));
- /*Call rand() once, because the first value isn't actually random*/
- rand();
- GameManager game(SCREEN_WIDTH, SCREEN_HEIGHT, BLOCK_SIZE);
- game.mainLoop();
- return 0;
- }
- //snake.h
- #ifndef SNAKE_H
- #define SNAKE_H
- #include "Coord.h" /*We will need this to store our snake*/
- #include "Random.h" /*For RandInt(min, max)*/
- #include "SDL2\SDL.h" /*For SDL_Rect and rendering functions*/
- #undef main /*SDL does some nasty macro stuff to main*/
- #include <vector> /*To store the entire snake*/
- #include <iostream> /*For overloaded output operator*/
- enum Direction
- {
- DIRECTION_UP,
- DIRECTION_RIGHT,
- DIRECTION_DOWN,
- DIRECTION_LEFT,
- DIRECTION_NONE
- };
- class Snake
- {
- private:
- Coord m_head;
- std::vector<Coord> m_snakeCoords;
- static const int HEAD_INDEX = 0;
- int m_size;
- int m_blockSize;
- public:
- Snake(int blockSize, SDL_Rect spawnArea); /*SpawnArea is required because we have no information on how big the grid is*/
- #ifdef DEBUG
- Snake();
- #endif
- friend std::ostream& operator<<(std::ostream &out, Snake &snake);
- /*Access functions*/
- Coord getHead();
- Coord getCoord(int index);
- int getSize();
- int getBlockSize();
- void move(int boardWidth, int boardHeight, Direction direction);
- };
- #endif /*SNAKE_H defined*/
- //snake.cpp
- #include "Snake.h"
- #ifdef DEBUG
- Snake::Snake() { }
- #endif
- Snake::Snake(int blockSize, SDL_Rect spawnArea) : m_blockSize(blockSize)
- {
- m_snakeCoords.resize(1); /*Make space to store the head of the snake*/
- /*We will multiply all coords by blockSize when rendering for simplicity, so now we have to divide by blockSize*/
- int startX = RandInt(spawnArea.x / m_blockSize, spawnArea.x / m_blockSize + spawnArea.w / m_blockSize);
- int startY = RandInt(spawnArea.y / m_blockSize, spawnArea.y / m_blockSize + spawnArea.h / m_blockSize);
- /*Create head struct*/
- m_head.x = startX;
- m_head.y = startY;
- /*Insert head at starting position of snakeCoords vector*/
- m_snakeCoords.insert(m_snakeCoords.begin(), m_head);
- m_size = 1;
- }
- /*Access functions*/
- Coord Snake::getHead() { return m_head; }
- Coord Snake::getCoord(int index) { return m_snakeCoords.at(index); }
- int Snake::getSize() { return m_size; }
- int Snake::getBlockSize() { return m_blockSize; }
- void Snake::move(int boardWidth, int boardHeight, Direction direction)
- {
- /*This won't work with the GameManager otherwise*/
- boardWidth /= m_blockSize;
- boardHeight /= m_blockSize;
- /*First, we insert a new block at the beginning of the snake, with the same coordinates as the previous head*/
- m_snakeCoords.insert(m_snakeCoords.begin(), {m_head.x, m_head.y});
- /*Now, we increment or decrement the coordinates where needed, using the SDL Coordinate system:*/
- /*
- X 0 1 2 3
- 0 - - - -
- 1 - - - -
- 2 - - - -
- 3 - - - -
- */
- switch(direction)
- {
- case DIRECTION_UP:
- m_snakeCoords[HEAD_INDEX].y--;
- break;
- case DIRECTION_DOWN:
- m_snakeCoords[HEAD_INDEX].y++;
- break;
- case DIRECTION_LEFT:
- m_snakeCoords[HEAD_INDEX].x--;
- break;
- case DIRECTION_RIGHT:
- m_snakeCoords[HEAD_INDEX].x++;
- break;
- }
- /*Next, we have to check if we moved out of the board*/
- //Up
- if (m_snakeCoords[HEAD_INDEX].y < 0)
- {
- /*Move the head to the bottom of the screen*/
- m_snakeCoords[HEAD_INDEX].y = boardHeight - 1;
- }
- /*Down*/
- if (m_snakeCoords[HEAD_INDEX].y >= boardHeight)
- {
- /*Move the head to the top of the screen*/
- m_snakeCoords[HEAD_INDEX].y = 0;
- }
- /*Left*/
- if (m_snakeCoords[HEAD_INDEX].x < 0)
- {
- /*Move the head to the right of the screen*/
- m_snakeCoords[HEAD_INDEX].x = boardWidth - 1;
- }
- /*Right*/
- if (m_snakeCoords[HEAD_INDEX].x >= boardWidth)
- {
- /*Move the head to the left of the screen*/
- m_snakeCoords[HEAD_INDEX].x = 0;
- }
- /*Finally, we can assign m_head and remove the last element in the coord vector*/
- m_head = m_snakeCoords[HEAD_INDEX];
- m_snakeCoords.pop_back();
- /* TODO (#1#): Collisions */
- }
- std::ostream& operator<<(std::ostream &out, Snake &snake)
- {
- out << "Snake Info:\n";
- out << "Size: " << snake.m_size << "\n";
- out << "Head:\tx = " << snake.m_head.x << "\n";
- out << "\ty = " << snake.m_head.y << "\n";
- return out;
- }
- //random.h
- #ifndef RANDOM_H
- #define RANDOM_H
- #include <cstdlib>
- #include <ctime>
- int RandInt(int min, int max);
- #endif /*RANDOM_H defined*/
- //random.cpp
- #include "Random.h"
- int RandInt(int min, int max)
- {
- static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0); // static used for efficiency, so we only calculate this value once
- // evenly distribute the random number across our range
- return static_cast<int>(rand() * fraction * (max - min + 1) + min);
- }
- //coord.h
- #ifndef COORD_H
- #define COORD_H
- struct Coord
- {
- int x;
- int y;
- };
- #endif /*COORD_H defined*/
- //debug.h
- #define DEBUG
- #ifndef DEBUG_H
- #define DEBUG_H
- #include "Snake.h"
- #include <iostream>
- /*Debugging class*/
- class Debug
- {
- public:
- void printSnakeInfo(Snake *snake);
- };
- #endif /*DEBUG_H defined*/
- //debug.cpp
- #include "Debug.h"
- void Debug::printSnakeInfo(Snake *snake)
- {
- std::cout << *snake;
- }
- //GameManger.h
- #ifndef GAMEMANAGER_H
- #define GAMEMANAGER_H
- #include "Snake.h"
- #include "Debug.h"
- #include "RenderManager.h"
- #include "SDL2\SDL.h"
- class GameManager
- {
- private:
- Snake* m_snake;
- int m_width;
- int m_height;
- int m_blockSize;
- RenderManager *m_rendering;
- SDL_Window *m_window = nullptr;
- SDL_Surface *m_screenSurface = nullptr;
- SDL_Renderer *m_renderer;
- Direction getMoveDirection();
- void moveSnake(Direction direction);
- bool InitSDL();
- void closeSDL();
- public:
- GameManager(int width, int height, int blockSize);
- ~GameManager();
- void mainLoop();
- #ifdef DEBUG
- void PrintSnakeInfo();
- Debug d;
- #endif
- };
- #endif /*GAMEMANAGER_H defined*/
- //gamemanager.cpp
- #include "GameManager.h"
- GameManager::GameManager(int width, int height, int blockSize) : m_width(width),
- m_height(height),
- m_blockSize(blockSize)
- {
- /*Initialize Snake*/
- m_snake = new Snake(blockSize, {0, 0, width, height});
- m_rendering = new RenderManager();
- bool success = InitSDL();
- if (!success)
- {
- std::cerr << "Error while creating window... Shutting down.\n";
- exit(-1);
- }
- }
- GameManager::~GameManager()
- {
- closeSDL();
- delete m_snake;
- }
- std::istream& operator>>(std::istream &in, Direction &dir)
- {
- std::cout << "Enter a direction (Up, Down, Left, Right): ";
- std::string direction;
- std::cin >> direction;
- if (direction == "Up")
- dir = DIRECTION_UP;
- else if (direction == "Down")
- dir = DIRECTION_DOWN;
- else if (direction == "Left")
- dir = DIRECTION_LEFT;
- else if (direction == "Right")
- dir = DIRECTION_RIGHT;
- else dir = DIRECTION_NONE;
- return in;
- }
- Direction GameManager::getMoveDirection()
- {
- /*Temporary implementation, this will be using SDL events*/
- Direction direction;
- std::cin >> direction;
- return direction;
- }
- void GameManager::moveSnake(Direction direction)
- {
- m_snake->move(m_width, m_height, direction);
- }
- #ifdef DEBUG
- void GameManager::PrintSnakeInfo()
- {
- d.printSnakeInfo(m_snake);
- }
- #endif
- bool GameManager::InitSDL()
- {
- bool success = true;
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- {
- std::cerr << "Failed to initialize SDL. SDL Error: " << SDL_GetError();
- success = false;
- }
- else
- {
- m_window = SDL_CreateWindow("Snake Game",
- SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED,
- m_width,
- m_height,
- SDL_WINDOW_SHOWN);
- if (m_window == nullptr)
- {
- std::cerr << "Failed to create SDL window. SDL Error: " << SDL_GetError();
- success = false;
- }
- else
- {
- m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED);
- if (m_renderer == nullptr)
- {
- std::cerr << "Failed to create SDL Renderer. SDL Error: " << SDL_GetError();
- success = false;
- }
- else
- {
- SDL_SetRenderDrawColor(m_renderer, 0xFF, 0xFF, 0xFF, 0xFF);
- m_screenSurface = SDL_GetWindowSurface(m_window);
- }
- }
- }
- return success;
- }
- void GameManager::closeSDL()
- {
- SDL_FreeSurface(m_screenSurface);
- m_screenSurface = nullptr;
- SDL_DestroyWindow(m_window);
- m_window = nullptr;
- SDL_Quit();
- }
- void GameManager::mainLoop()
- {
- SDL_Event e;
- bool quit = false;
- while (!quit)
- {
- while(SDL_PollEvent(&e))
- {
- if (e.type == SDL_QUIT)
- {
- quit = true;
- }
- }
- Direction dir = getMoveDirection();
- moveSnake(dir);
- #ifdef DEBUG
- PrintSnakeInfo();
- #endif
- SDL_RenderClear(m_renderer);
- SDL_SetRenderDrawColor(m_renderer, 0xFF, 0xFF, 0xFF, 0xFF);
- m_rendering->renderSnake(m_snake, m_renderer);
- SDL_RenderPresent(m_renderer);
- }
- }
- //rendermanager.h
- #ifndef RENDERMANAGER_H
- #define RENDERMANAGER_H
- #include "SDL2\SDL.h"
- #undef main
- #include "Snake.h"
- class RenderManager
- {
- private:
- // SDL_Renderer* m_renderer;
- // SDL_Window *m_window;
- public:
- // RenderManager(SDL_Renderer *renderer, SDL_Window *window);
- void renderSquare(int x, int y, int size, SDL_Color color, SDL_Renderer *renderer);
- void renderSnake(Snake *snake, SDL_Renderer *renderer);
- };
- #endif /*RENDERMANAGER_H defined*/
- //rendermanager.cpp
- #include "RenderManager.h"
- //RenderManager::RenderManager(SDL_Renderer *renderer, SDL_Window *window)
- //{
- // m_renderer = renderer;
- // m_window = window;
- //}
- void RenderManager::renderSquare(int x, int y, int size, SDL_Color color, SDL_Renderer *renderer)
- {
- SDL_Rect square = {x, y, size, size};
- SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a); /*CRASH -> FIXED :)*/
- SDL_RenderFillRect(renderer, &square);
- SDL_RenderPresent(renderer);
- }
- void RenderManager::renderSnake(Snake *snake, SDL_Renderer *renderer)
- {
- for (int i = 0; i < snake->getSize(); ++i)
- {
- renderSquare(snake->getCoord(i).x * snake->getBlockSize() + 1,
- snake->getCoord(i).y * snake->getBlockSize() + 1,
- snake->getBlockSize(),
- {0x00, 0x00, 0xFF, 0xFF},
- renderer);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement