205 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			205 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | #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; | |||
|  |     } | |||
|  | 
 | |||
|  |     // 创建渲染器
 | |||
|  |     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); | |||
|  |         Render(m_deltaTime); | |||
|  | 
 | |||
|  |         // -------------------------- 新增:帧率统计与输出 --------------------------
 | |||
|  |         m_frameCount++; // 每帧递增计数器
 | |||
|  |         u32 currentTime = SDL_GetTicks(); | |||
|  |         // 判断是否已过去 1 秒(1000 毫秒)
 | |||
|  |         if (currentTime - m_lastFpsPrintTime >= 1000) | |||
|  |         { | |||
|  |             // 计算帧率:总帧数 / 1秒 = 帧率(如 60 帧 → 60FPS)
 | |||
|  |             u32 fps = m_frameCount; | |||
|  |             // 输出帧率(用 SDL_Log 或 printf 均可,SDL_Log 更适配 SDL 日志系统)
 | |||
|  |             // SDL_Log("当前帧率:%d FPS | DeltaTime:%.4f 秒", fps, m_deltaTime);
 | |||
|  |             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); | |||
|  |             m_deltaTime = m_frameTime / 1000.0f; | |||
|  |         } | |||
|  |         else | |||
|  |         { | |||
|  |             m_deltaTime = diff / 1000.0f; | |||
|  |         } | |||
|  |     } | |||
|  | } | |||
|  | 
 | |||
|  | 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"); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         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); | |||
|  | } | |||
|  | 
 | |||
|  | void Game::Render(float deltaTime) | |||
|  | { | |||
|  |     SDL_RenderClear(m_renderer); | |||
|  |     if (m_scene != nullptr) | |||
|  |         m_scene->Render(deltaTime); | |||
|  |     if (m_uiScene != nullptr) | |||
|  |         m_uiScene->Render(deltaTime); | |||
|  |     if (m_DebugInfoActor != nullptr) | |||
|  |         m_DebugInfoActor->Render(deltaTime); | |||
|  |     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; | |||
|  | } |