正确使用SDL2中的按键?

时间:2014-11-06 12:30:44

标签: c keypress rectangles sdl-2

我尝试使用键盘上的键在窗口中移动一个矩形,但是在启动/编译程序后我得到一个Failreport。

  keystate=NULL;
if (keystate[SDLK_LEFT] ) 
{
  rect2.x -= 2;
}
if (keystate[SDLK_RIGHT] ) 
{
  rect2.x += 2;
}
if (keystate[SDLK_DOWN] ) 
{
  rect2.y += 2;
}
if (keystate[SDLK_UP] ) 
{
  rect2.y -= 2;
}

这是不起作用的代码。在main()的开头我把这行:

Uint8 * keystate; 我在C中使用lib SDL.h来执行此操作。

failmessage包含:

  

程序接收信号SIGSEGV   堆栈跟踪可在“调用堆栈”选项卡中找到   PS:我认为最好发布整个代码。稍作修改:

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


int main()
{
  //Request successful execute
  if(SDL_Init(SDL_INIT_EVERYTHING)!=0)
  {
    printf("fehler");
    return 1;
  }

  //create window 800x600
  SDL_Window *win;
  win = SDL_CreateWindow("test",100,100,800,600,SDL_WINDOW_SHOWN);

  //create renderwindow with vysnc enabled
  SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

  if(ren==NULL)
  {
    printf("Fehler");
    SDL_Quit();
    return 1;
  }

  Uint8 *keystate=SDL_GetKeyboardState(NULL);
  //boolean data type not supported
  int gameRunning = 1;

 SDL_Event event;

//create rectangle which is the whole window
 SDL_Rect rect={
    0,0,800,600
  };
  //smaller rectangle 
  SDL_Rect rect2={
    0,0,50,50
  };

//while loop to hold the window opened
  while (gameRunning)
  {
    if (SDL_PollEvent(&event))//close the window 
    {
      if (event.type == SDL_QUIT)
      {
          gameRunning = 0;
      }
    }
    //color of the first rectangle(red)
    SDL_SetRenderDrawColor(ren, 255,0,0,255);
    SDL_RenderClear(ren);
    SDL_RenderFillRect( ren, &rect );

    //second rectangle (blue)
    SDL_SetRenderDrawColor(ren, 0,0,255,255);
    SDL_RenderFillRect( ren, &rect2 );
    //change/update the render
    SDL_RenderPresent(ren);

    //rect2.x+=5.f;

   if (keystate[SDLK_LEFT] ) 
    {
      rect2.x -= 2;
    }
    if (keystate[SDLK_RIGHT] ) 
    {
      rect2.x += 2;
    }
    if (keystate[SDLK_DOWN] ) 
    {
      rect2.y += 2;
    }
    if (keystate[SDLK_UP] ) 
    {
      rect2.y -= 2;
    }

  }
  //give heap free
  SDL_DestroyRenderer(ren);
  SDL_DestroyWindow(win);
  SDL_Quit();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

这些是宏。 您正在通过宏值将指针偏移到NULL,然后尝试取消引用它。 这是分段错误的原因(SIGSEGV)。

Uint8* keys = SDL_GetKeyboardState(NULL); // NOT "keys = NULL;"
if (keys[SDLK_LEFT]) rect2.x -= 2;
if (keys[SDLK_RIGHT]) rect2.x += 2;
if (keys[SDLK_DOWN]) rect2.y += 2;
if (keys[SDLK_UP]) rect2.y -= 2;

请记住,这是一个内部数组。你不应该释放它!这是一个常见的错误......&#34;我从库中获取了列表的副本,因此我最好在以后删除它以避免内存泄漏。&#34;但实际上这不是由SDL_GetKeyboardState分配的,而是函数只是给你一个指向关键状态的内部存储的指针。因此,请检查程序的其余部分,如果您正在释放它,请将其停止,因为这也会导致应用程序崩溃。


修改的 好吧,所以这是真正的问题!

您正在通过keys抵消地址SDLK_LEFTSDLK_...宏不用于此目的!相反,偏移SDL_SCANCODE_LEFTSDL_SCANCODE_RIGHTSDL_SCANCODE_UPSDL_SCANCODE_DOWN

由于SDLK_...宏并非用于此目的,因此它们是不同的值。您可能会遇到分段错误的原因是它们被定义为远远超出数组keys长度的大值。