2014-11-06 2 views
1

키보드에서 키를 사용하여 창에서 사각형을 이동하려고했지만 프로그램 시작 후/컴파일로 Failreport가 표시됩니다.키 누르기가 SDL2에서 올바르게 사용합니까?

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; 
} 
+0

"시작한 후/내 프로그램을 컴파일 할 때 Failreport가 나타납니다."- 컴파일 할 때 또는 프로그램을 실행하거나 시작한 후 컴파일 및 충돌이 발생 했습니까? – bitcell

+0

나는 그것을 컴파일하고, 시작한 다음 추락시켰다. – student96

+0

디버거를 사용하여 실행 한 후에 어디에서 충돌했는지 확인하십시오. 도움이 될 것입니다. – bitcell

답변

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; 

이것은 내부 배열입니다. 너는 그것을 풀어 주기로되어 있지 않다! 이것은 흔히 볼 수있는 실수입니다 ... "도서관 목록을 가져오고 있습니다. 따라서 나중에 메모리 누출을 피하기 위해 삭제하는 것이 좋습니다." 그러나 실제로 이것은 SDL_GetKeyboardState에 의해 할당되지 않고 함수는 키 상태의 내부 저장소에 대한 포인터를 제공합니다. 따라서 프로그램의 나머지 부분을 확인하십시오.이 프로그램을 해제 한 경우 프로그램 중단을 유발할 수 있으므로 중지하십시오.


편집 좋아, 그래서 여기 참 문제입니다!

주소 keys을 오프셋하여 SDLK_LEFT으로 지정합니다. SDLK_... 매크로는 이러한 목적으로 사용되지 않습니다. 대신, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UPSDL_SCANCODE_DOWN에 의해 오프셋.

SDLK_... 매크로는이 용도로 사용되지 않으므로 다른 값입니다. 세그먼트 분할 오류가 발생하는 이유는 배열의 길이를 훨씬 넘어서는 큰 값으로 정의되어 있기 때문입니다. keys

+1

코드를 수정했지만 이전과 같은 문제가 있습니다. 어쩌면 전체 소스 코드를 게시 할 때 도움이 될 수 있습니다 (그리 길지 않습니다). 나는 내 질문에 그것을 편집하기 위해 부심이다. – student96

+0

나는 그것을 편집했다. 문제는'SDLK _...'대신'SDL_SCANCODE _...'를 사용해야한다는 것이다. – rsethc

관련 문제