代码之家  ›  专栏  ›  技术社区  ›  Jeremiah Onwubuya

如何启用SDL2以允许所有key\u down事件,而不仅仅是quit事件?

  •  1
  • Jeremiah Onwubuya  · 技术社区  · 6 年前

    我的SDL窗口在另一个位图的顶部显示一个位图,但我无法使用SDL\U按键事件控制位图图像。唯一有效的事件是SDL\u QUIT。

    我尝试使用ASWD键和上下左右箭头键进行映射,但是SDL窗口不处理任何这些事件。唯一发生的事件是当我单击X按钮关闭窗口或当我按下q或escape键关闭窗口时。此外,控制台上没有出现任何printf语句,因此我不确定问题出在哪里,因为程序编译和运行时没有任何错误。

    我使用的是C而不是C++

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <SDL2/SDL.h>
    #include <SDL2/SDL_timer.h>
    #include <SDL_image.h>
    
    
    #define WINDOW_WIDTH (640)
    #define WINDOW_HEIGHT (480)
    // Speed in Pixels/Seconds
    #define SCROLL_SPEED (300)
    
    // Spirte Size
    #define SPRITE_SIZE    32
    
    
    int main(int argc, const char * argv[]) {
    
    // Attempt to initialize graphics library
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
        return 1;
    }
    
    //Initialize Key Variables
    SDL_Window *window = NULL;
    SDL_Renderer *renderer = NULL;
    SDL_Surface *windowSurface = NULL;
    SDL_Surface *imageSurface = NULL;
    
    
    
    // Creating Surfaces and Addresses
    SDL_Surface *temp = NULL;
    SDL_Surface *sprite = NULL;
    
    // set sprite position
    SDL_Rect dstSprite = {0, 0, 32, 32};
    
    
    // Attempt to create SDL Window
    window = SDL_CreateWindow("Atari Lunar Lander", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, 0);
    
    // Print an Error if the window fails to initialize
    if (window == NULL) {
        printf("Could not create window: %s\n", SDL_GetError());
        return 1;
    }
    
    // Create The Title of the Window
    SDL_SetWindowTitle(window, "Atari Lunar Lander");
    
    // Create SDL Render Window
    Uint32 render_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE;
    renderer = SDL_CreateRenderer(window, -1, render_flags);
    
    // if rendering the window fails
    if (!renderer) {
        printf("error creating render: %s\n", SDL_GetError());
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }
    
    windowSurface = SDL_GetWindowSurface(window);
    
    // Load A bitmap image as an Surface
    windowSurface = SDL_LoadBMP("/Users/jeremiahonwubuya/Desktop/AtariLunarLander/outerspace.bmp");
    
    if (!windowSurface) {
        printf("error creating surface: %s\n", SDL_GetError());
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }
    
    //Load Image data into graphics hardware memory
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, windowSurface);
    
    
    if (!texture) {
        printf("error creating texture: %s\n", SDL_GetError());
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }
    
    
    // load bitmap image into an SDL_Surface "temp" and store "temp" into the SDL_Surface "sprite" that is optimized for Blitting
    temp   = SDL_LoadBMP("/Users/jeremiahonwubuya/Desktop/AtariLunarLander/player.bmp");
    sprite = SDL_ConvertSurface(temp, temp->format, 0);
    SDL_FreeSurface(temp);
    
    SDL_Texture *playerTexture = SDL_CreateTextureFromSurface(renderer, sprite);
    
    
    if (!sprite) {
        printf("error creating sprite: %s\n", SDL_GetError());
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }
    
    
    
    // updating the Window Surface to be the BitMap Image
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, texture, NULL, NULL);
    SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
    SDL_RenderPresent(renderer);
    
    
    
    bool isRunning = true;
    SDL_Event event;
    
    while (isRunning) {
    
        while (SDL_PollEvent(&event) != 0 ) {
            if (event.type == SDL_QUIT) {
                // close button clicked
                isRunning = false;
                break;
            }
    
            if (event.type == SDL_KEYDOWN) {
                // close program upon buttons pressed
                switch(event.key.keysym.sym){
                    case SDLK_q:
                        printf("program stopped");
                        isRunning = false;
                        break;
                    case SDLK_ESCAPE:
                        printf("programm stopped");
                        isRunning = false;
                        break;
    
                }
    
                // Animating the Sprite
    
                if (event.key.keysym.sym == SDLK_a || event.key.keysym.sym == SDLK_LEFT) {
                    dstSprite.x -= 5;
                    dstSprite.w = 32;
                    dstSprite.h = 32;
                    SDL_RenderClear(renderer);
                    SDL_RenderCopy(renderer, texture, NULL, NULL);
                    SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
                    SDL_RenderPresent(renderer);
                    printf("sprite moved leftt to position %d \n", dstSprite.x);
    
         }
    
                if (event.key.keysym.sym == SDLK_d || event.key.keysym.sym == SDLK_RIGHT) {
                    dstSprite.x += 5;
                    dstSprite.w = 32;
                    dstSprite.h = 32;
                    SDL_RenderClear(renderer);
                    SDL_RenderCopy(renderer, texture, NULL, NULL);
                    SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
                    SDL_RenderPresent(renderer);
                    printf("sprite moved right to position %d \n", dstSprite.x);
    
                }
    
                if (event.key.keysym.sym == SDLK_w || event.key.keysym.sym == SDLK_UP) {
                    dstSprite.y -= 5;
                    dstSprite.w = 32;
                    dstSprite.h = 32;
                    SDL_RenderClear(renderer);
                    SDL_RenderCopy(renderer, texture, NULL, NULL);
                    SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
                    SDL_RenderPresent(renderer);
                    printf("sprite moved up to position %d \n", dstSprite.y);
    
    
                }
    
                if (event.key.keysym.sym == SDLK_s || event.key.keysym.sym == SDLK_DOWN) {
                    dstSprite.y += 5;
                    dstSprite.w = 32;
                    dstSprite.h = 32;
                    SDL_RenderClear(renderer);
                    SDL_RenderCopy(renderer, texture, NULL, NULL);
                    SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
                    SDL_RenderPresent(renderer);
                    printf("sprite moved down to position %d \n", dstSprite.y);
    
    
                }
    
            }
    
    
          // Prevent Sprite from colliding with the edges of the screen
    
            if ( dstSprite.x < 0 ) {
                dstSprite.x = 0;
            }
            else if ( dstSprite.x > WINDOW_WIDTH-SPRITE_SIZE ) {
                dstSprite.x = WINDOW_WIDTH-SPRITE_SIZE;
            }
            if ( dstSprite.y < 0 ) {
                dstSprite.y = 0;
            }
            else if ( dstSprite.y > WINDOW_HEIGHT-SPRITE_SIZE ) {
                dstSprite.y = WINDOW_HEIGHT-SPRITE_SIZE;
            }
    
    
            // Draw the Sprite
            SDL_BlitSurface(sprite, NULL, windowSurface, &dstSprite);
    
    
            SDL_UpdateWindowSurface(window);
        }
    
    }
    
    
    SDL_Delay(5000);
    
    // Clean Up
    
    // Free SDL Surfaces
    SDL_FreeSurface(sprite);
    sprite = NULL;
    SDL_FreeSurface(windowSurface);
    windowSurface = NULL;
    SDL_FreeSurface(imageSurface);
    imageSurface = NULL;
    // Destroy Texture and Window
    texture = NULL;
    SDL_DestroyTexture(texture);
    playerTexture = NULL;
    SDL_DestroyTexture(playerTexture);
    window = NULL;
    SDL_DestroyWindow(window);
    SDL_Quit();
    

    }

    1 回复  |  直到 6 年前
        1
  •  2
  •   aram    6 年前

    你的OR'ing你的情况,从而产生不同的整数比什么是在。符号。您应该拆分or,让它们失效或使用if条件。例如:

    case SDLK_a:    
    case SDLK_LEFT: 
       printf("sprite moved leftt");
       break;
    
    case SDLK_d:
    case SDLK_RIGHT:
      printf("sprite moved right");
      break;
    
    case SDLK_w:
    case SDLK_UP:
      printf("sprite moved up");
      break;
    
    case SDLK_s:
    case SDLK_DOWN:
      printf("sprite moved down");
      break;
    

    if (event.key.keysym.sym == SDLK_a || event.key.keysym.sym == SDLK_LEFT)
      // do something..
    

    所以有几件事,首先,你的代码是“工作的”,当我按正确的键时,我会打印出文本,但你有另一个错误,ifs中的这些中断会让你跳过bliting部分,记住,中断会中断switch中的执行流,for,while循环,你不需要在ifs上使用它们。

    此外,如果你按下一个键,然后不按任何东西,你应该得到你的屏幕更新。我用这个程序进行了测试。告诉我它是否收到你的钥匙。。

    #include <SDL2/SDL.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        SDL_Init(SDL_INIT_VIDEO);
    
        bool isRunning = true;
        SDL_Event event;
        SDL_Rect dstSprite = {0, 0, 0, 0};
        while (isRunning) {
    
            while (SDL_PollEvent(&event) != 0) {
                if (event.type == SDL_QUIT) {
                    // close button clicked
                    isRunning = false;
                    break;
                }
    
                if (event.type == SDL_KEYDOWN) {
                    // close program upon buttons pressed
                    switch (event.key.keysym.sym) {
                    case SDLK_q:
                        printf("program stopped");
                        isRunning = false;
                        break;
                    case SDLK_ESCAPE:
                        printf("programm stopped");
                        isRunning = false;
                        break;
                    }
    
                    // Animating the Sprite
    
                    if (event.key.keysym.sym == SDLK_a ||
                        event.key.keysym.sym == SDLK_LEFT) {
                        dstSprite.x -= 5;
                        printf("sprite moved leftt to position %d \n", dstSprite.x);
                        break;
                    }
    
                    if (event.key.keysym.sym == SDLK_d ||
                        event.key.keysym.sym == SDLK_RIGHT) {
                        dstSprite.x += 5;
                        printf("sprite moved right to position %d \n", dstSprite.x);
                        break;
                    }
    
                    if (event.key.keysym.sym == SDLK_w ||
                        event.key.keysym.sym == SDLK_UP) {
                        dstSprite.y -= 5;
                        printf("sprite moved up to position %d \n", dstSprite.y);
                        break;
                    }
    
                    if (event.key.keysym.sym == SDLK_s ||
                        event.key.keysym.sym == SDLK_DOWN) {
                        dstSprite.y += 5;
                        printf("sprite moved down to position %d \n", dstSprite.y);
                        break;
                    }
                }
                printf("update graphics\n");
            }
        }
    }