This commit is contained in:
2025-10-06 04:18:49 +08:00
commit df2cacdb92
2784 changed files with 1280840 additions and 0 deletions

223
source/EngineCore/Game.cpp Normal file
View File

@@ -0,0 +1,223 @@
#include "Game.h"
#include "squirrel/SquirrelEx.h"
#include "EngineFrame/Component/Sprite.h"
#include "EngineFrame/Actor/Actor.h"
#include "EngineFrame/Component/Text.h"
#include "EngineFrame/Actor/Debug_Actor.h"
Game::Game()
{
}
Game::~Game()
{
Clear();
}
void Game::Init(std::function<void()> CallBack)
{
// 计算帧时间
m_frameTime = 1000 / m_fps;
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);
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);
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");
// 构造调试对象
m_DebugInfoActor = new Debug_Actor();
CallBack();
}
void Game::Run()
{
while (m_isRunning)
{
u32 frameStart = SDL_GetTicks(); // 帧开始时间
SDL_Event m_event;
HandleEvents(&m_event);
Update(m_deltaTime); // 注意这里使用的是上一帧的deltaTime合理见说明
Render();
// 帧率统计(保持不变)
m_frameCount++;
u32 currentTime = SDL_GetTicks();
if (currentTime - m_lastFpsPrintTime >= 1000)
{
u32 fps = m_frameCount;
if (m_DebugInfoActor)
m_DebugInfoActor->FPS = fps;
m_lastFpsPrintTime = currentTime;
m_frameCount = 0;
}
// 计算实际总帧时间(关键修改)
u32 diff = SDL_GetTicks() - frameStart; // 处理耗时
if (diff < m_frameTime)
{
SDL_Delay(m_frameTime - diff); // 尝试延迟补全
}
// 延迟后,重新计算从帧开始到现在的总时间(包含可能的延迟误差)
u32 actualFrameTime = SDL_GetTicks() - 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);
// 调试信息
if (m_DebugInfoActor != nullptr)
{
m_DebugInfoActor->Update(deltaTime);
m_DebugInfoActor->RenderCount = RenderCount;
}
RenderCount = 0;
}
void Game::Render()
{
SDL_RenderClear(m_renderer);
if (m_scene != nullptr)
m_scene->Render();
if (m_uiScene != nullptr)
m_uiScene->Render();
if (m_DebugInfoActor != nullptr)
m_DebugInfoActor->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;
m_DebugInfoActor = 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;
}