【问题标题】:C SDL Object movement flowC SDL 对象移动流程
【发布时间】:2016-01-27 10:11:16
【问题描述】:

我刚开始使用 SDL,并在窗户上制作了一个小方块。 我使用了 DL_GetKeyboardState,并且让它移动得有点顺利。但是,就在我按住一个键开始向一个方向移动时,它会移动一点,停止,然后像我想要的那样移动。这会破坏平滑度。我最好的猜测是它等待鼠标双击,但我不确定。有什么建议么?

代码:

#include <stdio.h>
#include <SDL.h>

int main(int argc, char * argv[])
{
   SDL_Window *window;
   SDL_Renderer *renderer;
   SDL_Event event;

   SDL_Init(SDL_INIT_VIDEO);
   window = SDL_CreateWindow("Yelda!", SDL_WINDOWPOS_UNDEFINED,        SDL_WINDOWPOS_UNDEFINED, 1600, 1200, 0);
   renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

   const Uint8 *state;
   int run = 1;
   int xpos=300;
   int ypos=300;
   int projectileYPos;
   int projectileXPos;
   int loop;
   int lanceLength = 10;

   while(run)
   {
      while(SDL_PollEvent(&event))
      {
         state=SDL_GetKeyboardState(NULL);

         if(state[SDL_SCANCODE_ESCAPE])
            run=0;
         if(state[SDL_SCANCODE_W])
            ypos-=10;
         if(state[SDL_SCANCODE_S])
            ypos+=10;
         if(state[SDL_SCANCODE_A])
            xpos-=10;
         if(state[SDL_SCANCODE_D])
            xpos+=10;

         SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
         SDL_RenderClear(renderer);
         SDL_SetRenderDrawColor(renderer, 255, 255, 255 ,255);
         SDL_Rect rect = {xpos, ypos, 20, 20 };
         SDL_RenderFillRect(renderer, &rect);
         SDL_RenderPresent(renderer);

         SDL_Delay(20);
      }
   }

   SDL_DestroyWindow(window);
   SDL_DestroyRenderer(renderer);
   SDL_Quit();
   return 0;
}

【问题讨论】:

  • 您的 SDL_PollEvent 循环迭代每个事件,因此您正在更新/绘制系统中发生的每个事件。基本上,如果我密集地移动鼠标,您的代码将尝试绘制每个动作,如果它发生在很久以前的事件(绘制需要时间,尤其是使用 vsync,加上强制延迟)。这个循环应该用来收集事件;更新和绘图应在事件循环之外执行(在顶级 while(run) 中)。
  • 这一行:int main(int argc, char * argv[])(并且因为在发布的代码中没有使用任何参数)将导致编译器针对未使用的参数发出两个警告:argcargv[]。建议将主函数签名改为:int main( void )

标签: c sdl


【解决方案1】:

SDL wiki 表示您应该使用SDL_PumpEvents() 来更新键盘状态数组。

确实,如果我们

  • 删除不需要的while(SDL_PollEvent(&amp;event)) 循环(不是其内容),
  • while(run)循环之前移动state=SDL_GetKeyboardState(NULL);(数组的地址“将在应用程序的整个生命周期内有效”,因此它总是返回相同的指针),并且
  • 只在循环内调用SDL_PumpEvents()

那么运动就很顺畅了。

【讨论】:

  • 其实SDL_PollEvent调用SDL_PumpEvents
猜你喜欢
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
  • 2017-06-06
  • 2013-05-30
  • 2016-02-08
  • 2015-07-14
  • 2010-11-27
  • 2011-04-30
相关资源
最近更新 更多