Files
DNF_DEV/source/EngineCore/Game.cpp
2026-02-08 16:20:50 +08:00

244 lines
6.1 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/Base/Actor.h"
#include "EngineFrame/Component/Text.h"
#include "Asset/Asset_SoundPack.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);
// 设置OpenGL ES 3.2上下文属性
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // 双缓冲
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // 24位深度缓冲避免z-fighting
// 启用多重采样(关键步骤)
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // 启用多重采样缓冲
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
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 | SDL_WINDOW_OPENGL);
if (m_window == nullptr)
{
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not Create Window! Error: %s\n", SDL_GetError());
m_isRunning = false;
}
// 关闭原生鼠标
SDL_ShowCursor(0);
// 打开所有检测到的控制器
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());
}
}
}
// 创建OpenGL渲染器
m_renderer = new RenderManager(m_window);
IMG_Init(IMG_INIT_PNG);
// 初始化 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
m_frameTime_ms = actualFrameTime;
}
}
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)
{
// 内存回收机制
m_lastMemoryPrintTime += deltaTime;
if (m_lastMemoryPrintTime >= m_memoryPrintInterval)
{
m_lastMemoryPrintTime = 0;
MemoryReclaims();
}
// 调用松鼠的更新
SquirrelEx::GetInstance().Update(deltaTime);
if (m_scene != nullptr)
m_scene->Update(deltaTime);
if (m_uiScene != nullptr)
m_uiScene->Update(deltaTime);
}
void Game::Render()
{
// 调用预渲染
if (m_scene != nullptr)
m_scene->PreRender();
if (m_uiScene != nullptr)
m_uiScene->PreRender();
// 清空渲染器后渲染
m_renderer->ClearScreen();
if (m_scene != nullptr)
{
m_renderer->SetOrthoMatrixType(0);
m_scene->Render();
}
if (m_uiScene != nullptr)
{
m_renderer->SetOrthoMatrixType(1);
m_uiScene->Render();
}
m_renderer->SwapBuffer();
}
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_DestroyWindow(m_window);
SDL_Quit();
}
void Game::MemoryReclaims()
{
// 音频内存回收
Asset_SoundPack::GetInstance().Reclaims();
}
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();
}
RefPtr<Scene> Game::GetScene()
{
return m_scene;
}
RenderManager *Game::GetRenderer()
{
return m_renderer;
}