首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使播放器动画看起来流畅?

如何使播放器动画看起来流畅?
EN

Game Development用户
提问于 2017-08-19 15:54:56
回答 1查看 412关注 0票数 0

我使用GLFW作为我的窗口和输入相关的工作。我正在计算三角时间,并将它与我的玩家速度相乘,然后最后将它添加到玩家的当前位置。事情是,虽然它使我的运动框架独立,球员的动作似乎是缓慢和加速的互换。原因是每个帧的δ时间值不同。我该怎么做才能使动画顺利进行呢?

下面是相关代码,以及正在发生的事情的捕获:

代码语言:javascript
运行
复制
float deltaTime = 0;
float oldTime = 0;

//The direction in which the player will move
int playerX = 0;
int playerY = 0;

//callback method for keyboard events
void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_W && action == GLFW_REPEAT) {
        playerX = 0; playerY = 1;
    }
    if (key == GLFW_KEY_S && action == GLFW_REPEAT) {
        playerX = 0; playerY = -1;
    }
    if (key == GLFW_KEY_D && action == GLFW_REPEAT) {
        playerX = 1; playerY = 0;
    }
    if (key == GLFW_KEY_A && action == GLFW_REPEAT)
    {
        playerX = -1; playerY = 0;
    }
}

//update player's position
void update() {
    player->move(playerX, playerY, TIME_PER_FRAME);
}

//set up glfw keyboard callback function and other stuff
void init() {
    glClearColor(0, 0, 0, 0);
    player->bindVertexAttributes(shader.getAttributeLocation("position"));
    glfwSetKeyCallback(window->getGLFWWindow(), keyboard_callback);
}


//wait logic 
float expected_frame_end = glfwGetTime() + TIME_PER_FRAME;
void wait() {
    while (glfwGetTime() < expected_frame_end) {

    }
    expected_frame_end += TIME_PER_FRAME;
    playerX = playerY = 0;
}

//rendering function
void render() {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    player->setUniformMatrixLocation(shader.getUniformLocation("projectionMatrix"), shader.getUniformLocation("transformationMatrix"));
    shader.useProgram();
    update();
    player->render();
    wait();
    shader.stopProgram();
}

//main function
int main(int argc, char** argv) {
    init();
//main loop
    while (!glfwWindowShouldClose(window->getGLFWWindow())) {
        render();
        window->swapBuffers();
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}
EN

回答 1

Game Development用户

回答已采纳

发布于 2017-08-19 16:18:37

我正在计算三角时间,并将它与我的玩家速度相乘,然后最后将它添加到玩家的当前位置。

这是可变的时间步骤,这与您当前如何标记问题:固定时间步相矛盾。

如果你的游戏目前可以运行在天空高帧速率像300赫兹,这是预期的。

这通常是通过实际修正时间步骤来解决的:确保您在固定框架(比如60 at )下运行您的游戏。这意味着你有1/60秒的时间来模拟和绘制一切。如果你的循环所花费的时间比这个要少,那就等等。(如图中所示,不要让你的线程进入睡眠状态。)

我通常喜欢做(伪代码)这样的事情:

代码语言:javascript
运行
复制
expected_frame_end = getCurrentTime() + FRAME_TIME

while( true ) {

  update( FRAME_TIME ) // frame time is your delta time, i.e. 1/DESIRED_FRAME_RATE, which is 
                       // constant.

  while ( getCurrentTime() < expected_frame_end )
  {
    // do nothing;
  }
  expected_frame_end += FRAME_TIME

}

通常,sleep方法保证线程将至少挂起所请求的时间,而不是最多,这会导致帧花费比预期更长的时间,并且导致实际帧速率的变化。

我建议你读一本好书:修好你的时间步子!

是否必须按照键盘输入的处理方式或其他方式处理?碳化硅

也许吧!

应用程序接收到的输入在很大程度上取决于操作系统决定发送什么。如果应用程序以60赫兹运行,它很可能对操作系统来说太快了,比如:操作系统不会以每秒60次的速度发送输入,但不太频繁。

要解决这个问题,当您期望键/鼠标按钮被按住时,您必须在按下键和释放键时注册。执行“按下键”操作的代码只会检查局部变量"isKeyDown“。

因此,您需要一个软件层来检查操作系统发送的状态更改,您的代码与该层进行交互,而不是直接与操作系统发送的原始输入交互。

票数 0
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/147364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档