Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Qt и кроссплатформенное программирование С/С++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.06.2011, 14:55   #1
Кипящий чайник
Форумчанин
 
Регистрация: 17.12.2009
Сообщений: 101
По умолчанию (SDL) Управление с клавиатуры

Я уже создавал подобную тему, но вопрос в этот раз имеет несколько иной характер.
Главной проблемой так и осталось удобное управление в игре, которую я пишу.

Как и раньше, что требовалось?
Предположим, я жму кнопку влево, и персонаж движется в нужном направлении. Затем я, не отпуская влево, жму вниз или любую другую стрелку. Персонаж прекращает движение в прежнем направлении и движется в новом.
Отпускаю клавишу вниз, и персонаж движется в прежнем направлении.

Что у меня получилось:
Как вы увидите из нижеследующего мною написанного алгоритма, нажатые клавиши определяются последовательно. И если я нажму клавишу вверх, то я могу, зажав другие клавиши, следовать соответствующим им направлениям.
А вот если я нажму вниз, то я ещё смогу свернуть влево или вправо, а вверх персонаж не пойдёт.
А дальше соответственно: жму клавишу влево, то смогу повернуть уже только вправо. Нажму вправо, уже никуда не поверну.
Разумеется, если я отпущу вторую зажатую клавишу, то персонаж пойдёт туда, куда указывает первая зажатая клавиша. Но мне ещё нужно, чтобы я, не отпуская первой клавиши, нажатием второй мог менять направление движения.

Я понимаю, почему происходит эта неполадка, но никак не могу придумать нормальную схему для считывания управления.


Я написал следующий алгоритм:

Код:
Uint8* keys = 0;

void ReadKeyboard(character* ch){
    int dir = none;
    int act = ch->action;

    SDL_PumpEvents();
    keys = SDL_GetKeyState(NULL);

    if(keys[SDLK_ESCAPE]) exit(0);

    if(keys[SDLK_UP]){
        act = ACTION_WALKING_UP;
        dir = up;
    }

    if(keys[SDLK_DOWN]){
        act = ACTION_WALKING_DOWN;
        dir = down;
    }

    if(keys[SDLK_LEFT]){
        act = ACTION_WALKING_LEFT;
        dir = left;
    }

    if(keys[SDLK_RIGHT]){
        act = ACTION_WALKING_RIGHT;
        dir = right;
    }

    character_ANIMATE(ch, act);
    character_MOVE(ch, dir);
}
Здесь переменная act отвечает за выбор анимации, не заостряйте на ней внимание. А вот dir - это направление движения персонажа. Значение none подразумевает, что персонаж никуда не движется.

Очень важно: мне не нужно, чтобы персонаж двигался по диагонали. Только горизонтальные линии движения.

Итак, у меня слёзная просьба: пожалуйста, подскажите правильный алгоритм управления в данной ситуации. Если необходимо, я сделаю нужные пояснения и выложу необходимые куски кода.
Кипящий чайник вне форума Ответить с цитированием
Старый 01.07.2011, 08:40   #2
Lunex.08
Форумчанин
 
Аватар для Lunex.08
 
Регистрация: 25.02.2009
Сообщений: 145
По умолчанию

А если попробовать проверить сколько нажато клавиш и выполнять ветвь только в том случае, когда нажата лишь одна из нужных клавиш.
Ну примерно так:
Код:
if(keys[SDLK_DOWN] 
   && !keys[SDLK_LEFT]
   && !keys[SDLK_RIGHT]
   && !keys[SDLK_UP])
{
        act = ACTION_WALKING_DOWN;
        dir = down;
}
Компьютеры бесподобны: за несколько минут они могут совершить такую грандиозную ошибку, какую не в состоянии сделать множество людей за многие месяцы.
Lunex.08 вне форума Ответить с цитированием
Старый 01.07.2011, 19:24   #3
Кипящий чайник
Форумчанин
 
Регистрация: 17.12.2009
Сообщений: 101
По умолчанию

Нет, увы. Как только я нажимаю новую клавишу движения, не отпуская старую, персонаж просто замирает на месте.
Кипящий чайник вне форума Ответить с цитированием
Старый 02.07.2011, 17:54   #4
Lunex.08
Форумчанин
 
Аватар для Lunex.08
 
Регистрация: 25.02.2009
Сообщений: 145
По умолчанию

Угу. Я сначала не до конца понял задачу.
Только что пробовал в одном из своих Qt проектов нажать сразу на несколько клавиш, и все работает так, как вам надо. Но в Qt обработчик событий вызывается при каждом новом нажатии клавиши. А как у вас вызывается эта функция?
Компьютеры бесподобны: за несколько минут они могут совершить такую грандиозную ошибку, какую не в состоянии сделать множество людей за многие месяцы.
Lunex.08 вне форума Ответить с цитированием
Старый 02.07.2011, 21:25   #5
Кипящий чайник
Форумчанин
 
Регистрация: 17.12.2009
Сообщений: 101
По умолчанию

Я использую только SDL. Функции обработки каждой клавиши нет, я вызываю SDL_PumpEvents, чтобы получить новые данные, и затем возвращаю в указатель keys массив из клавиш при помощи SDL_GetKeyState, и затем уже проверяю индекс каждой нужной клавиши в массиве, была ли она зажата.
Кипящий чайник вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перемещение объекта по форме.(Управление с клавиатуры) gralex10 Помощь студентам 1 28.03.2011 15:57
C# + SDL.net Dimone-kun Помощь студентам 0 25.10.2010 10:11
Управление в игре с клавиатуры Mr_freeman Помощь студентам 2 19.01.2010 11:07
Управление с клавиатуры kpishnik Помощь студентам 10 27.07.2008 18:38
Управление с клавиатуры PikeIt Общие вопросы Delphi 6 27.12.2006 17:41