代码:https://github.com/DXT00/Hazel_study/tree/f064a34112e7d7d3fcc03ab9d2f089a2da663df8/Hazel
不同的机器帧率不同,如果没帧都走1单元的话,就会导致:
400帧每秒 的机器---> 走400单元
60帧每秒 的机器 ---> 走60单元
会导致很大的差距。
我们希望的是一秒中所有的机器移动的步数单元是一样的

添加TimeStep类:
TimeStep.h
#pragma once
namespace Hazel {
class TimeStep
{
public:
TimeStep(float time = 0.0f)
:m_Time(time)
{
}
float GetSeconds() const { return m_Time; }
float GetMilliseconds() const { return m_Time * 1000.0f; }
private:
float m_Time;
};
}
m_Time记录每一帧的时间
Application.cpp
void Application::Run()
{
while (m_Running)
{
float time = (float)glfwGetTime(); //return the current value, in seconds
TimeStep timestep = time - m_LastFrameTime;
m_LastFrameTime = time;
for (Layer* layer : m_LayerStack)
layer->OnUpdate(timestep);
m_ImGuiLayer->Begin();
for (Layer* layer : m_LayerStack)
layer->OnImGuiRender();
m_ImGuiLayer->End();
m_Window->OnUpdate();
}
}
TimeStep timestep = time - m_LastFrameTime;
这里是一个隐式转换,当一个类只有一个成员变量时,可以把成员变量直接赋值给这个类。隐式类型转换由编译器完成,编译器通过构造函数构造出一个临时对象,并将其复制为timestep。
把TimeStep传递给客户端的SamplaLayer的OnUpdate函数:
void OnUpdate(Hazel::TimeStep ts) override
{
HZ_TRACE("Delta time: {0}s ({1}ms)", ts.GetSeconds(), ts.GetMilliseconds());
if (Hazel::Input::IsKeyPressed(HZ_KEY_LEFT))
{
m_CameraPosition.x -= m_MoveSpeed ;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_RIGHT))
{
m_CameraPosition.x += m_MoveSpeed;
}
if (Hazel::Input::IsKeyPressed(HZ_KEY_UP))
{
m_CameraPosition.y += m_MoveSpeed;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_DOWN))
{
m_CameraPosition.y -= m_MoveSpeed;
}
if (Hazel::Input::IsKeyPressed(HZ_KEY_A))
{
m_CameraRotation += m_RotateSpeed;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_D))
{
m_CameraRotation -= m_RotateSpeed;
}
Hazel::RenderCommand::SetClearColor({ 0.1f, 0.1f, 0.1f, 1 });
Hazel::RenderCommand::Clear();
/* m_Camera.SetPosition({ 0.5f,0.5f,0.0f });
m_Camera.SetRotation(45);*/
m_Camera.SetPosition(m_CameraPosition);
m_Camera.SetRotation(m_CameraRotation);
Hazel::Renderer::BeginScene(m_Camera);
Hazel::Renderer::Submit(m_SquareVA, m_SquareShader);
Hazel::Renderer::Submit(m_VertexArray, m_Shader);
Hazel::Renderer::EndScene();
}
打印出每帧的时间:

根据上面所述,我们需要把speed(每帧走多少单元)乘以TimeStep
if (Hazel::Input::IsKeyPressed(HZ_KEY_LEFT))
{
m_CameraPosition.x -= m_MoveSpeed * ts.GetSeconds();
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_RIGHT))
{
m_CameraPosition.x += m_MoveSpeed * ts.GetSeconds();
}
ts.GetSeconds()这样写有点麻烦---》重载float()类型转换!!(厉害了 = =)
operator float()const { return m_Time; }
TimeStep.h
#pragma once
namespace Hazel {
class TimeStep
{
public:
TimeStep(float time = 0.0f)
:m_Time(time)
{
}
operator float()const { return m_Time; }
float GetSeconds() const { return m_Time; }
float GetMilliseconds() const { return m_Time * 1000.0f; }
private:
float m_Time;
};
}
所以上述乘以timestep的代码就可以写成:
void OnUpdate(Hazel::TimeStep ts) override
{
HZ_TRACE("Delta time: {0}s ({1}ms)", ts.GetSeconds(), ts.GetMilliseconds());
float timestep = ts;//相当一 timestep = float(ts)
if (Hazel::Input::IsKeyPressed(HZ_KEY_LEFT))
{
m_CameraPosition.x -= m_MoveSpeed * timestep;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_RIGHT))
{
m_CameraPosition.x += m_MoveSpeed * timestep;
}
if (Hazel::Input::IsKeyPressed(HZ_KEY_UP))
{
m_CameraPosition.y += m_MoveSpeed * timestep;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_DOWN))
{
m_CameraPosition.y -= m_MoveSpeed * timestep;
}
if (Hazel::Input::IsKeyPressed(HZ_KEY_A))
{
m_CameraRotation += m_RotateSpeed * timestep;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_D))
{
m_CameraRotation -= m_RotateSpeed * timestep;
}
Hazel::RenderCommand::SetClearColor({ 0.1f, 0.1f, 0.1f, 1 });
Hazel::RenderCommand::Clear();
/* m_Camera.SetPosition({ 0.5f,0.5f,0.0f });
m_Camera.SetRotation(45);*/
m_Camera.SetPosition(m_CameraPosition);
m_Camera.SetRotation(m_CameraRotation);
Hazel::Renderer::BeginScene(m_Camera);
Hazel::Renderer::Submit(m_SquareVA, m_SquareShader);
Hazel::Renderer::Submit(m_VertexArray, m_Shader);
Hazel::Renderer::EndScene();
}
或者直接隐式转换:
void OnUpdate(Hazel::TimeStep ts) override
{
HZ_TRACE("Delta time: {0}s ({1}ms)", ts.GetSeconds(), ts.GetMilliseconds());
//float timestep = ts;//相当一 timestep = float(ts)
if (Hazel::Input::IsKeyPressed(HZ_KEY_LEFT))
{
m_CameraPosition.x -= m_MoveSpeed * ts;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_RIGHT))
{
m_CameraPosition.x += m_MoveSpeed * ts;
}
if (Hazel::Input::IsKeyPressed(HZ_KEY_UP))
{
m_CameraPosition.y += m_MoveSpeed * ts;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_DOWN))
{
m_CameraPosition.y -= m_MoveSpeed * ts;
}
if (Hazel::Input::IsKeyPressed(HZ_KEY_A))
{
m_CameraRotation += m_RotateSpeed * ts;
}
else if (Hazel::Input::IsKeyPressed(HZ_KEY_D))
{
m_CameraRotation -= m_RotateSpeed * ts;
}
Hazel::RenderCommand::SetClearColor({ 0.1f, 0.1f, 0.1f, 1 });
Hazel::RenderCommand::Clear();
/* m_Camera.SetPosition({ 0.5f,0.5f,0.0f });
m_Camera.SetRotation(45);*/
m_Camera.SetPosition(m_CameraPosition);
m_Camera.SetRotation(m_CameraRotation);
Hazel::Renderer::BeginScene(m_Camera);
Hazel::Renderer::Submit(m_SquareVA, m_SquareShader);
Hazel::Renderer::Submit(m_VertexArray, m_Shader);
Hazel::Renderer::EndScene();
}
F5成功运行,可以看到三角形的移动速度不再随着帧率大小而 变,而是以每秒speed单位变化了!

本文详细介绍了在游戏开发中如何使用时间步长来控制角色移动速度,确保不同帧率下的一致性。通过引入TimeStep类,实现了速度与时间的精确匹配,避免了因帧率波动导致的速度不均。
3230

被折叠的 条评论
为什么被折叠?



