2D_Engine/Game.cpp

197 lines
5.4 KiB
C++

/********************\
| Copyright 2024, |
| Ulysse Cura |
\********************/
/////////////////////////////////////
// //
// Definition de la classe Game. //
// //
/////////////////////////////////////
#include <iostream> // cerr
#include <SDL2/SDL_image.h> // IMG_Init, IMG_GetError
#include <stdexcept> // runtime_error
#include "Camera.hpp" // Camera::
#include "ECS/Components.hpp" // ECS and Components definition
#include "Events.hpp" // Events::
#include "Game.hpp" // Game declaration
#include "IP/Properties.hpp" // Item definition
#include "MapManager.hpp" // MapManager::
#include "TextureManager.hpp" // TextureManager::
#include "TileMap.hpp" // TileMap::
using std::cerr, std::runtime_error;
SDL_Renderer *Game::renderer;
SDL_Texture *Game::textureRenderer;
Events Game::events;
TextureManager Game::textureManager;
Camera Game::camera {WINDOW_WIDTH, WINDOW_HEIGHT};
TileMap Game::tileMap;
MapManager Game::mapManager;
Manager Game::entityManager;
Entity &player(Game::entityManager.addEntity());
// Game constructor
Game::~Game()
{
if(renderer != NULL) SDL_DestroyRenderer(renderer);
if(m_window != NULL) SDL_DestroyWindow(m_window);
SDL_Quit();
cerr << "Game cleaned.\n";
}
// Init SDL, IMG...
bool Game::Init()
{
// Init SDL
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
cerr << "Erreur SDL_Init : " << SDL_GetError() << '\n';
throw runtime_error("Impossible d'initialiser SDL2.\n");
}
cerr << "SDL initialised successfully.\n";
// Init IMG
if(IMG_Init(IMG_INIT_PNG) == 0)
{
cerr << "Erreur IMG_Init : " << IMG_GetError() << '\n';
throw runtime_error("Impossible d'initialiser IMG.\n");
}
cerr << "IMG initialised successfully.\n";
// Create Window
m_window = SDL_CreateWindow(WINDOW_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if(m_window == NULL)
{
cerr << "Erreur SDL_CreateWindow : " << SDL_GetError() << '\n';
throw runtime_error("Impossible d'initialiser la fenêtre.\n");
}
cerr << "Window created successfully.\n";
// Disable unused events
SDL_EventType disableEvents[] = {
// Joysticks events
SDL_JOYAXISMOTION,
SDL_JOYBALLMOTION,
SDL_JOYHATMOTION,
SDL_JOYBUTTONDOWN,
SDL_JOYBUTTONUP,
SDL_JOYDEVICEADDED,
SDL_JOYDEVICEREMOVED,
// Game controllers events
SDL_CONTROLLERAXISMOTION,
SDL_CONTROLLERBUTTONDOWN,
SDL_CONTROLLERBUTTONUP,
SDL_CONTROLLERDEVICEADDED,
SDL_CONTROLLERDEVICEREMOVED,
SDL_CONTROLLERDEVICEREMAPPED,
// Drag & drop events
SDL_DROPFILE,
SDL_DROPTEXT,
SDL_DROPBEGIN,
SDL_DROPCOMPLETE,
// Tactile events
SDL_FINGERMOTION,
SDL_FINGERDOWN,
SDL_FINGERUP,
SDL_MULTIGESTURE,
SDL_DOLLARGESTURE,
SDL_DOLLARRECORD,
// Sensor event
SDL_SENSORUPDATE,
// User event
SDL_USEREVENT
};
for(const SDL_EventType &disableEvent : disableEvents) SDL_EventState(disableEvent, SDL_DISABLE);
// Create renderer
renderer = SDL_CreateRenderer(m_window, -1, 0);
if(renderer == NULL)
{
cerr << "Erreur SDL_CreateRenderer : " << SDL_GetError() << '\n';
throw runtime_error("Impossible d'initialiser le renderer.\n");
}
cerr << "Renderer created successfully\n\n";
// Load initial map and tileset
tileMap.LoadTileset("ressources/tileset/tileset.png");
tileMap.LoadTileMap("ressources/maps/dungeon entry.json");
// Init player
TransformComponent *p_transform = &player.addComponent<TransformComponent>(tileMap.getPlayerInitPos(), Vector2D<int>(32, 32), 2, 3.0f);
player.addComponent<SpriteComponent>("ressources/heroes/knight/idle-sheet.png");
player.addComponent<HitboxComponent>(Vector2D<float>(0.81f, 0.41f), Vector2D<float>(0.5f, 1.0f));
player.addComponent<AnimationSystem>();
player.addComponent<PlayerSystem>();
camera.centerPos.x = static_cast<int>(p_transform->position.x - static_cast<float>(p_transform->dimension.x) * static_cast<float>(p_transform->scale) / 2.0f);
camera.centerPos.y = static_cast<int>(p_transform->position.y - static_cast<float>(p_transform->dimension.y) * static_cast<float>(p_transform->scale) / 2.0f);
m_isRunning = true;
return true;
}
void Game::HandleEvents()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
m_isRunning = false;
else if(event.type == SDL_KEYDOWN && event.key.repeat == 0)
events.keys[event.key.keysym.scancode] = true;
else if(event.type == SDL_KEYUP)
events.keys[event.key.keysym.scancode] = false;
}
}
void Game::Update()
{
entityManager.refresh();
entityManager.update();
camera.update();
}
void Game::Render()
{
// Dessin sur une texture intermediaire
SDL_SetRenderTarget(renderer, textureRenderer);
SDL_SetRenderDrawColor(renderer, 20, 20, 18, 255);
SDL_RenderClear(renderer);
tileMap.draw(1);
tileMap.draw(2);
entityManager.draw();
tileMap.draw(3);
// Affichage sur la fenêtre avec la caméra
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderCopy(renderer, textureRenderer, &camera.camR, NULL);
SDL_RenderPresent(renderer);
}
bool Game::Running()
{
return m_isRunning;
}