简体   繁体   English

如何启用SDL2以允许所有key_down事件而不仅仅是退出事件?

[英]How do I enable SDL2 to allow all key_down events and not just the quit event?

My SDL Window displays a bitmap on top of another bitmap however I am not able to control the bitmap image using SDL_KeyDown events. 我的SDL窗口在另一个位图的顶部显示一个位图,但是我无法使用SDL_KeyDown事件来控制位图图像。 The only event that works is SDL_QUIT. 唯一有效的事件是SDL_QUIT。

I attempted to map using the ASWD keys and the Up Down Left and Right arrow keys, however the SDL Window doesn't process any of those events. 我尝试使用ASWD键和上下左右箭头键进行映射,但是SDL窗口不处理任何这些事件。 The only event that occurs is when I click the X button to close the window or when I press the q or escape keys to close the window. 发生的唯一事件是当我单击X按钮关闭窗口时,或者当我按q或Escape键关闭窗口时。 Also, none of the printf statements are appearing on the console so I am not sure exactly where the problem is because the program compiles and runs without any errors. 另外,控制台上没有出现任何printf语句,所以我不确定问题出在哪里,因为程序可以编译并运行而没有任何错误。

I am using C not C++ 我正在使用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();

} }

Your OR'ing your cases thus producing different integers than what are in .sym. 您的个案的OR'ing结果产生的整数与.sym中的整数不同。 You should split your ORs and let them fallthrough or use an if condition. 您应该拆分OR,让它们失败或使用if条件。 For example: 例如:

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;

Or 要么

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

So a few things, first your code is "working", I get printed the text out when I press the correct keys but you have another error, those breaks in the ifs are making you skip the bliting section, remember that breaks break the execution flow in switch, for, and while loops, you don't need them on ifs. 所以,首先,您的代码正在“工作”,当我按正确的键时,我将文本打印出来,但是您还有另一个错误,ifs中的中断使您跳过了bliting部分,请记住,中断会中断执行在switch,for和while循环中流动,在ifs上不需要它们。

Also If you press a key and then don't press anything you should be getting your screen updated. 另外,如果您按某个键,然后不按任何键,则应该更新屏幕。 I tested with this program. 我对此程序进行了测试。 Tell me if it is receiving your keys.. 告诉我它是否正在接收您的钥匙。

#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");
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM