Files
DNF_DEV/source/EngineCore/Game.cpp

220 lines
5.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Game.h"
#include "squirrel/SquirrelEx.h"
#include "EngineFrame/Component/Sprite.h"
#include "EngineFrame/Actor/Actor.h"
#include "EngineFrame/Component/Text.h"
Game::Game()
{
}
Game::~Game()
{
Clear();
}
void Game::Init(std::function<void()> CallBack)
{
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
SDL_JoystickEventState(SDL_ENABLE);
SDL_JoystickOpen(0);
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not initialize! Error: %s\n", SDL_GetError());
m_isRunning = false;
}
m_window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Screen_W, Screen_H, SDL_WINDOW_SHOWN);
if (m_window == nullptr)
{
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not Create Window! Error: %s\n", SDL_GetError());
m_isRunning = false;
}
// 打开所有检测到的控制器
int numControllers = SDL_NumJoysticks();
for (int i = 0; i < numControllers; i++)
{
if (SDL_IsGameController(i))
{
SDL_GameController *controller = SDL_GameControllerOpen(i);
if (controller)
{
SDL_Log("成功打开控制器: %s", SDL_GameControllerName(controller));
}
else
{
SDL_Log("无法打开控制器 %d! SDL错误: %s", i, SDL_GetError());
}
}
}
// 创建渲染器
m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (m_renderer == nullptr)
{
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not Create Renderer! Error: %s\n", SDL_GetError());
m_isRunning = false;
}
// 启用渲染器的混合功能(必须,否则纹理混合模式无效)
SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_BLEND);
// SDL_RenderSetScale(m_renderer, 1.2, 1.2);
IMG_Init(IMG_INIT_PNG);
// 初始化SDL_mixer支持OGG格式
// 44100: 采样率, MIX_DEFAULT_FORMAT: 音频格式, 2: 声道数(立体声), 4096: 缓冲区大小
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) < 0)
{
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL_mixer初始化失败! Mix_Error: %s\n", Mix_GetError());
m_isRunning = false;
}
// 初始化 TTF
if (TTF_Init() == -1)
{
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "TTF 初始化失败TTF_Error: %s\n", TTF_GetError());
m_isRunning = false;
}
// SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
CallBack();
}
void Game::Run()
{
// 计算帧时间
m_frameTime = 1000.0 / m_Settingfps;
while (m_isRunning)
{
// 帧开始时间
Uint64 frameStart = SDL_GetTicks64();
SDL_Event m_event;
HandleEvents(&m_event);
Update(m_deltaTime);
Render();
// 帧率统计 每一秒钟的时候记录一次帧率
m_frameCounter++;
Uint64 currentTime = SDL_GetTicks64();
if (currentTime - m_lastFpsPrintTime >= 1000)
{
m_fps = m_frameCounter;
m_lastFpsPrintTime = currentTime;
m_frameCounter = 0;
}
// 计算实际总帧时间(关键修改)
Uint64 diff = SDL_GetTicks64() - frameStart; // 处理耗时
if (diff < m_frameTime)
{
SDL_Delay(m_frameTime - diff); // 尝试延迟补全
}
// 延迟后,重新计算从帧开始到现在的总时间(包含可能的延迟误差)
Uint64 actualFrameTime = SDL_GetTicks64() - frameStart;
m_deltaTime = actualFrameTime / 1000.0f; // 用实际总时间更新deltaTime
}
}
void Game::HandleEvents(SDL_Event *e)
{
while (SDL_PollEvent(e))
{
if (e->type == SDL_QUIT)
{
m_isRunning = false;
SDL_Log("Game Exit1");
}
else if (e->type == SDL_JOYBUTTONDOWN)
{
if (e->jbutton.button == JOY_PLUS)
{
m_isRunning = false;
SDL_Log("Game Exit2");
}
}
// 处理屏幕按下事件
else if (e->type == SDL_FINGERDOWN)
{
// 触发双击事件
SDL_Log("退出程序");
m_isRunning = false;
SDL_Log("Game Exit3");
}
if (m_scene != nullptr)
m_scene->HandleEvents(e);
if (m_uiScene != nullptr)
m_uiScene->HandleEvents(e);
}
}
void Game::Update(float deltaTime)
{
if (m_scene != nullptr)
m_scene->Update(deltaTime);
if (m_uiScene != nullptr)
m_uiScene->Update(deltaTime);
}
void Game::Render()
{
// 绘制调用次数清0
m_RenderCount = 0;
// 调用预渲染
if (m_scene != nullptr)
m_scene->PreRender();
if (m_uiScene != nullptr)
m_uiScene->PreRender();
// 清空渲染器后渲染
SDL_RenderClear(m_renderer);
if (m_scene != nullptr)
m_scene->Render();
if (m_uiScene != nullptr)
m_uiScene->Render();
SDL_RenderPresent(m_renderer);
}
void Game::Clear()
{
if (m_scene != nullptr)
{
m_scene->Exit();
}
m_scene = nullptr;
if (m_uiScene != nullptr)
{
m_uiScene->Exit();
}
m_uiScene = nullptr;
IMG_Quit();
SDL_DestroyRenderer(m_renderer);
SDL_DestroyWindow(m_window);
SDL_Quit();
}
void Game::ChangeScene(RefPtr<Scene> scene)
{
if (m_scene != nullptr)
{
m_scene->Exit();
}
m_scene = scene;
m_scene->Enter();
}
void Game::ChangeUIScene(RefPtr<Scene> scene)
{
if (m_uiScene != nullptr)
{
m_uiScene->Exit();
}
m_uiScene = scene;
m_uiScene->Enter();
}
SDL_Renderer *Game::GetRenderer()
{
return m_renderer;
}