Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: [SDL 1.2] Движение квадрата при зажатой клавиши стрелки влево  (Прочитано 2240 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн qub

  • Автор темы
  • Новичок
  • *
  • Сообщений: 41
    • Просмотр профиля
Написал простой пример рисования желтого квадрата. Пытаюсь реализовать движение квадрата при удерживание нажатой клавиши стрелки влево. Проблема в том, что при удерживание клавиши стрелки влево квадрат не движится, а если нажимать и отпускать клавишу, то квадрат перемещается нормально. Вопрос в следующем, как сделать так, чтобы квадрат двигался при зажатой клавиши стрелки влево?

Код примера:
#include "SDL\SDL.h"

SDL_Rect init_new_rect(int h, int w, int x, int y);
struct colors init_clr();

struct colors {
    int r;
    int g;
    int b;
};

SDL_Rect init_new_rect(int h, int w, int x, int y) {
    SDL_Rect sDim;

    sDim.h = h;
    sDim.w = w;
    sDim.x = x;
    sDim.y = y;

    return sDim;
}

int main( int argc, char* args[] ) {
    SDL_Surface* display = NULL;
    SDL_Rect tmpDim;
    int x0, y0;

    int rect_h = 50;
    int rect_w = 50;

    struct colors yellow_clr;

    yellow_clr.r = 255;
    yellow_clr.g = 255;
    yellow_clr.b = 0;

    x0 = 640/2;
    y0 = 480/2;

    SDL_Init( SDL_INIT_EVERYTHING );

    display = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );

    int quit = 0;
    SDL_Event event;
    int dx = 0;

    while( !quit )
    {

    if( SDL_PollEvent( &event ) )
    {

        if( event.type == SDL_KEYDOWN ) {
             switch( event.key.keysym.sym ) {
                case SDLK_ESCAPE: quit = 1; break;
                case SDLK_LEFT: dx -= 2; break;
                default : break;
             }

        }
        else if( event.type == SDL_QUIT )
        {
            quit = 1;
        }

    }


    SDL_FillRect(display, NULL, 0);

    tmpDim = init_new_rect(rect_h, rect_w, x0 - rect_h/2 + dx, y0 - rect_w/2);
    SDL_FillRect(display, &tmpDim, SDL_MapRGB(display->format, yellow_clr.r, yellow_clr.g, yellow_clr.b));


    SDL_Delay(SDL_TIMESLICE);

    SDL_Flip(display);

    }
    return 0;
}

Оффлайн virusoft

  • Активист
  • *
  • Сообщений: 324
    • Просмотр профиля
    • Virusoft
Первое что пришло на ум, то что ты обрабатываешь не нажатую клавишу, а отпускание ее.
Я в Си не силен, но направление тебе задал. Дальше сам подумай.
Если работает - не трогай.

Оффлайн qub

  • Автор темы
  • Новичок
  • *
  • Сообщений: 41
    • Просмотр профиля
Первое что пришло на ум, то что ты обрабатываешь не нажатую клавишу, а отпускание ее.
Я в Си не силен, но направление тебе задал. Дальше сам подумай.
Не совсем пойму, почему ты решил, что обробатывается не нажатая клавиша? В документации на официальном сайте написано, что событие SDL_KEYDOWN возникает, когда пользователь нажимает клавишу на клавиатуре. Ссылка на описание события: https://wiki.libsdl.org/SDL_KeyboardEvent

Оффлайн virusoft

  • Активист
  • *
  • Сообщений: 324
    • Просмотр профиля
    • Virusoft
Посмотри в сторону SDL_PRESSED.
Оно отличается от SDL_KEYDOWN.

SDL_KEYDOWN возникает один раз при нажатии клавиши, а SDL_PRESSED говорит о том что клавиша нажата.
вот в этом и разница, как мне кажется.
« Последнее редактирование: 09 Июня 2015, 08:18:11 от virusoft »
Если работает - не трогай.

Оффлайн qub

  • Автор темы
  • Новичок
  • *
  • Сообщений: 41
    • Просмотр профиля
Посмотри в сторону SDL_PRESSED.
Оно отличается от SDL_KEYDOWN.

SDL_KEYDOWN возникает один раз при нажатии клавиши, а SDL_PRESSED говорит о том что клавиша нажата.
вот в этом и разница, как мне кажется.
В документации на официальном сайте написано https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkeyboardevent.html, что тип события клавиша нажата SDL_KEYDOWN и состояние клавиша нажата SDL_PRESSED возвращают одну и ту же информацию, но для этого используют только разные значения. Я так понимаю без разницы что использовать SDL_KEYDOWN или SDL_PRESSED. 
« Последнее редактирование: 09 Июня 2015, 10:51:37 от qub »

Оффлайн aSmile

  • Активист
  • *
  • Сообщений: 755
    • Просмотр профиля
В документации на официальном сайте написано https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkeyboardevent.html

Ты дочитал до конца? В особенности Note

Оффлайн qub

  • Автор темы
  • Новичок
  • *
  • Сообщений: 41
    • Просмотр профиля
В документации на официальном сайте написано https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkeyboardevent.html

Ты дочитал до конца? В особенности Note
Да, раздел Note я читал. Мне известно, что есть возможность реализовать необходимый мне эффект без использования функции SDL_EnableKeyRepeat, но как это сделать я не знаю. В данный момент пробую использовать функциию SDL_EnableKeyRepeat.
« Последнее редактирование: 09 Июня 2015, 12:19:43 от qub »

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
qub, псеводокод
есть скорость
есть координаты
когда нажимают клавишу
   скорость = значение
когда отпускают клавишу
   скорость = 0
отрисовка
   координаты += скорость
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн peregrine

  • FSM
  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 7215
  • Gentoo x64 Ubuntu 16.04.1 x64
    • Просмотр профиля
qub, у тебя SDL или SDL2? Если у тебя SDL 1.2, то зачем ты читаешь документацию по SDL2? Они же разные.
« Последнее редактирование: 09 Июня 2015, 18:48:25 от peregrine »

Оффлайн aSmile

  • Активист
  • *
  • Сообщений: 755
    • Просмотр профиля
Мне известно, что есть возможность реализовать необходимый мне эффект без использования функции SDL_EnableKeyRepeat, но как это сделать я не знаю.

Тогда запоминай, что кнопка была нажата, и сбрасывай его, когда отпущена. Например, так:
Код: (c) [Выделить]
#include "SDL.h"

SDL_Rect init_new_rect(int h, int w, int x, int y);
struct colors init_clr();

struct colors {
    int r;
    int g;
    int b;
};

SDL_Rect init_new_rect(int h, int w, int x, int y) {
    SDL_Rect sDim;

    sDim.h = h;
    sDim.w = w;
    sDim.x = x;
    sDim.y = y;

    return sDim;
}

int main( int argc, char* args[] ) {
    SDL_Surface* display = NULL;
    SDL_Rect tmpDim;
    int x0, y0;

    int rect_h = 50;
    int rect_w = 50;

    struct colors yellow_clr;

    yellow_clr.r = 255;
    yellow_clr.g = 255;
    yellow_clr.b = 0;

    x0 = 640/2;
    y0 = 480/2;

    SDL_Init( SDL_INIT_EVERYTHING );

    display = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );

    int quit = 0;
    SDL_Event event;
    int dx = 0;
    int leftKeyPressed = 0;

    while( !quit )
    {

    if( SDL_PollEvent( &event ) )
    {

        if( event.type == SDL_KEYDOWN ) {
             switch( event.key.keysym.sym ) {
                case SDLK_ESCAPE: quit = 1; break;
                case SDLK_LEFT: leftKeyPressed = 1; break;
                default : break;
             }

        }
else if( event.type == SDL_KEYUP ) {
    switch( event.key.keysym.sym ) {
                case SDLK_LEFT: leftKeyPressed = 0; break;
                default : break;
             }
}
        else if( event.type == SDL_QUIT )
        {
            quit = 1;
        }

    }


    if (leftKeyPressed) {
dx -= 2;
    }

    SDL_FillRect(display, NULL, 0);

    tmpDim = init_new_rect(rect_h, rect_w, x0 - rect_h/2 + dx, y0 - rect_w/2);
    SDL_FillRect(display, &tmpDim, SDL_MapRGB(display->format, yellow_clr.r, yellow_clr.g, yellow_clr.b));


    SDL_Delay(SDL_TIMESLICE);

    SDL_Flip(display);

    }
    return 0;
}

Оффлайн virusoft

  • Активист
  • *
  • Сообщений: 324
    • Просмотр профиля
    • Virusoft
Посмотри в сторону SDL_PRESSED.
Оно отличается от SDL_KEYDOWN.

SDL_KEYDOWN возникает один раз при нажатии клавиши, а SDL_PRESSED говорит о том что клавиша нажата.
вот в этом и разница, как мне кажется.
В документации на официальном сайте написано https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkeyboardevent.html, что тип события клавиша нажата SDL_KEYDOWN и состояние клавиша нажата SDL_PRESSED возвращают одну и ту же информацию, но для этого используют только разные значения. Я так понимаю без разницы что использовать SDL_KEYDOWN или SDL_PRESSED. 
А ты посмотри чем отличаются эти значения.
Все сразу станет ясно. И есть разница между одним собитием и другим.
Все сделали правильные программисты. Обозначили события так, как понимается из написанного, а не так как подумалось кому-то.
Собитие возникает в ответ на действия пользователя. Но действия разные бывают. Одно дело нажать клавишу, а другое дело держать ее.
« Последнее редактирование: 09 Июня 2015, 18:29:17 от virusoft »
Если работает - не трогай.

Оффлайн qub

  • Автор темы
  • Новичок
  • *
  • Сообщений: 41
    • Просмотр профиля
alsoijw,
qub, псеводокод
есть скорость
есть координаты
когда нажимают клавишу
   скорость = значение
когда отпускают клавишу
   скорость = 0
отрисовка
   координаты += скорость
Помогло, спасибо. Такую же реализацию я нашел на сайте с документацией по SDL. Кому интересно вот ссылка:https://www.libsdl.org/release/SDL-1.2.15/docs/html/guideinputkeyboard.html

peregrine,
Использую SDL1.2, в ссылке https://wiki.libsdl.org/SDL_KeyboardEvent действительно документация для версии SDL2. Спасибо, что сказали.

aSmile,
Спасибо. Твой вариант кода тоже работает.

virusoft,
Спорить не буду. Возможно ты прав, но мне бы хотелось увидеть пример кода, где используется состояние нажатия клавиши SDL_PRESSED и в котором можно увидеть разницу между использованием SDL_PRESSED и SDL_KEYDOWN. Сам реализовать это у себя в коде я не смог. Поиск по google, где бы использовалась SDL_PRESSED, ничего не дал.

Вопрос решен. Всем спасибо, кто участвовал в дискуссии. Напоследок скажу, что вариант с функцией SDL_EnableKeyRepeat тоже работает.

 

Страница сгенерирована за 0.018 секунд. Запросов: 21.