SwitchGame/source/EngineCore/Game.cpp

205 lines
5.4 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"
#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;
}