/* * 2D Game Engine * Game.cpp: Base Game engine class * Based on pikuma.com 2D game engine in C++ and Lua course * Copyright (c) 2021 986-Studio. All Right Reserved * * Created by Manoƫl Trapier on 09/02/2021. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include uint32_t Game::windowsWidth = 0; uint32_t Game::windowsHeight = 0; uint32_t Game::mapWidth = 0; uint32_t Game::mapHeight = 0; Game::Game() { this->isRunning = false; this->isDebug = false; this->millisecsPerviousFrame = 0; this->registry = std::make_unique(); this->assetStore = std::make_unique(); this->eventBus = std::make_unique(); } Game::~Game() { } void Game::Initialize() { int ret; SDL_DisplayMode displayMode; ret = SDL_Init(SDL_INIT_EVERYTHING); if (ret) { Logger::Critical("SDL Initialisation error."); return; } ret = TTF_Init(); if (ret) { Logger::Critical("SDL_ttf Initialisation error."); return; } SDL_GetCurrentDisplayMode(0, &displayMode); Game::windowsWidth = 800; //displayMode.w; Game::windowsHeight = 600; //displayMode.h; this->window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Game::windowsWidth, Game::windowsHeight, SDL_WINDOW_BORDERLESS); if (!window) { Logger::Critical("SDL window creation error."); return; } this->renderer = SDL_CreateRenderer(this->window, -1, 0); if (!renderer) { Logger::Critical("SDL renderer creation error."); return; } //SDL_SetWindowFullscreen(this->window, SDL_WINDOW_FULLSCREEN); ImGui::CreateContext(); ImGuiSDL::Initialize(this->renderer, Game::windowsWidth, Game::windowsHeight); this->camera.x = 0; this->camera.y = 0; this->camera.w = Game::windowsWidth; this->camera.h = Game::windowsHeight; this->isRunning = true; } void Game::Destroy() { ImGuiSDL::Deinitialize(); ImGui::DestroyContext(); if (this->renderer) { SDL_DestroyRenderer(this->renderer); } if (this->window) { SDL_DestroyWindow(this->window); } SDL_Quit(); } void Game::Run() { this->Setup(); #if 0 for(int i = 0 ; i < 100; i++) { this->ProcessInput(); this->Update(); this->Render(); } #else while(this->isRunning) { this->ProcessInput(); this->Update(); this->Render(); } #endif } void Game::Setup() { LevelLoader loader; this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->registry->addSystem(); this->lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::os); this->lua.create_named_table("Logger"); sol::table Log = this->lua["Logger"]; Log["Info"] = Logger::Info; Log["Error"] = Logger::Error; Log["Warning"] = Logger::Warning; Log["Debug"] = Logger::Debug; this->registry->getSystem().setup(this->lua); loader.LoadLevel(this->lua, this->registry, this->assetStore, this->renderer, 1); } void Game::Update() { uint32_t timeToWait = MILLISECS_PER_FRAME - (SDL_GetTicks() - this->millisecsPerviousFrame); if (timeToWait > 0 && timeToWait <= MILLISECS_PER_FRAME) { SDL_Delay(timeToWait); } double deltaTime = (SDL_GetTicks() - this->millisecsPerviousFrame) / 1000.0; this->millisecsPerviousFrame = SDL_GetTicks(); eventBus->reset(); registry->getSystem().subscriptToEvents(eventBus); registry->getSystem().subscriptToEvents(eventBus); registry->getSystem().subscriptToEvents(eventBus); registry->getSystem().subscriptToEvents(eventBus); registry->update(); registry->getSystem().update(deltaTime); registry->getSystem().update(); registry->getSystem().update(this->eventBus); registry->getSystem().update(this->registry); registry->getSystem().update(); registry->getSystem().update(this->camera); registry->getSystem().update(deltaTime, SDL_GetTicks()); } void Game::ProcessInput() { SDL_Event event; while(SDL_PollEvent(&event)) { int mouseX, mouseY, buttons; ImGui_ImplSDL2_ProcessEvent(&event); ImGuiIO &io = ImGui::GetIO(); buttons = SDL_GetMouseState(&mouseX, &mouseY); io.MousePos = ImVec2(mouseX, mouseY); io.MouseDown[0] = buttons & SDL_BUTTON(SDL_BUTTON_LEFT); io.MouseDown[1] = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT); io.MouseDown[2] = buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE); switch(event.type) { case SDL_QUIT: this->isRunning = false; break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) { this->isRunning = false; } else if (event.key.keysym.sym == SDLK_F1) { this->isDebug = !this->isDebug; } else { this->eventBus->emitEvent(event.key.keysym.sym); } break; default: break; } } } void Game::Render() { SDL_SetRenderDrawColor(this->renderer, 21, 21, 21, 255); SDL_RenderClear(this->renderer); registry->getSystem().update(this->renderer, this->assetStore, this->camera); registry->getSystem().update(this->renderer, this->assetStore, this->camera); registry->getSystem().update(this->renderer, this->assetStore, this->camera); if (this->isDebug) { registry->getSystem().debugRender(this->renderer, this->camera); registry->getSystem().update(this->registry, this->camera); } SDL_RenderPresent(this->renderer); }