Всем привет! В этой статье мы узнаем, как обрабатывать события клавиатуры и мыши, и будем использовать их для перемещения объекта по окну. Ура!
Начнем с изображения. Я сделал это растровое изображение 64 × 64:
Как видите, я не умею рисовать, чтобы спасти свою жизнь. Но так как это растровое изображение, нам не нужно расширение SDL_image.
Получив изображение, вы захотите создать новый проект Visual Studio, подключите его для работы с SDL2, а затем добавьте некоторый код для отображения окна и космического корабля в нем. Если вы не помните, как эти прошлые статьи должны помочь:
- « Настройка SDL2 с помощью Visual Studio 2015 »
- « Отображение пустого окна в SDL2 »
- « Отображение изображения в окне SDL2 »
Вы должны получить код, который выглядит примерно так:
#include <SDL.h>
int main(int argc, char ** argv)
{
// variables
bool quit = false;
SDL_Event event;
int x = 288;
int y = 208;
// init SDL
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * window = SDL_CreateWindow("SDL2 Keyboard/Mouse events",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface * image = SDL_LoadBMP("spaceship.bmp");
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,
image);
SDL_FreeSurface(image);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
// handle events
while (!quit)
{
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
}
SDL_Rect dstrect = { x, y, 64, 64 };
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
SDL_RenderPresent(renderer);
}
// cleanup SDL
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Вы также хотите , чтобы место spaceship.bmp в вашу Debug папку (вместе с SDL2.dll ) , так что программа может найти файлы, необходимые ..
Как только вы действительно запустите программу, вы должны увидеть это:
Я установил белый фон окна, чтобы он соответствовал белому фону космического корабля, установив чистый цвет с помощью SDL_SetRenderDrawColor () , а затем вызвав SDL_RenderClear (), чтобы очистить окно от этого цвета.
Для обработки событий клавиатуры и мыши нам нужен SDL_Event . Хорошо, что вы знаете: мы использовали его все время, чтобы действовать, когда окно закрыто. Теперь нам нужно обработать другой тип события. Итак, давайте добавим новый case
оператор после того, который обрабатывает SDL_QUIT
:
case SDL_KEYDOWN:
break;
В этом case
утверждении давайте теперь определим, какая клавиша была фактически нажата, и соответственно передвинем космический корабль:
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_LEFT: x--; break;
case SDLK_RIGHT: x++; break;
case SDLK_UP: y--; break;
case SDLK_DOWN: y++; break;
}
break;
Если вы сейчас запустите программу, вы обнаружите, что можете перемещать космический корабль с помощью клавиш со стрелками:
Вы заметите, что он, кажется, движется довольно медленно, и вам нужно некоторое время нажимать, чтобы сделать какое-либо существенное движение. Теперь в своем коде замените SDL_WaitEvent на SDL_PollEvent :
Теперь попробуйте запустить его снова:
Swoosh! Менее чем за полсекунды космический корабль ударяется о край окна. Это на самом деле слишком быстро. Чтобы сделать это более понятным, добавьте небольшую задержку в начале while
цикла:
SDL_Delay(20);
SDL_PollEvent () лучше, чем SDL_WaitEvent (), когда вы хотите постоянно проверять (то есть опрашивать ) на наличие событий, но он потребляет больше ресурсов процессора (вы можете увидеть это, открыв диспетчер задач). SDL_WaitEvent () хорошо, когда ваше окно в основном бездействует, поэтому вам не нужно часто проверять события.
Обработка событий мыши также очень проста. Все, что вам нужно сделать, это обработать соответствующее событие. Давайте посмотрим, как справиться с щелчком мыши:
case SDL_MOUSEBUTTONDOWN:
switch (event.button.button)
{
case SDL_BUTTON_LEFT:
SDL_ShowSimpleMessageBox(0, "Mouse", "Left button was pressed!", window);
break;
case SDL_BUTTON_RIGHT:
SDL_ShowSimpleMessageBox(0, "Mouse", "Right button was pressed!", window);
break;
default:
SDL_ShowSimpleMessageBox(0, "Mouse", "Some other button was pressed!", window);
break;
}
break;
И вот что происходит, когда вы запускаете его и щелкаете где-то в окне:
Вы также можете отслеживать движение мыши и получить текущие координаты указателя мыши. Это полезно при перемещении объектов с помощью мыши (например, при перемещении объекта путем его перетаскивания). Следующий код получает координаты мыши и отображает их в заголовке окна:
case SDL_MOUSEMOTION:
int mouseX = event.motion.x;
int mouseY = event.motion.y;
std::stringstream ss;
ss << "X: " << mouseX << " Y: " << mouseY;
SDL_SetWindowTitle(window, ss.str().c_str());
break;
Обратите внимание, что вам нужно добавить следующее в начало вашего main.cpp, чтобы приведенный выше код работал:
#include <sstream>
Теперь вы заметите координаты мыши в заголовке окна:
Замечательный! Теперь у вас должно быть представление о том, как захватывать и обрабатывать события клавиатуры и мыши в SDL2. Мы увидим больше об этом в следующей статье, посвященной рисованию пикселей в окне, так что следите за обновлениями, чтобы узнать больше!
Эта статья была первоначально опубликована как « SDL2: движение клавиатуры и мыши (события) » на ранчо программистов 12 февраля 2014 года. Она немного обновлена здесь. Исходный код и космический корабль растровый доступны в репозитории Gigi Labs Bitbucket .