Описание действий в игре.
| |
Morfay | Дата: Вторник, 29 Мая 2012, 13:49 | Сообщение # 1 |
почетный гость
Сейчас нет на сайте
| Добрый день. Добрался до момента, когда нужно прописать действия игроков. Сделал так:
1) Есть активаторы (jump, run, kick и т.д.). При нажатии на определенную клавишу, активатор ставим true, при отпускании false. 2) В главном цикле получаем состояние активаторов и выполняем проверку. Вот тут-то и возникают сложности: действия могут быть сложными (к примеру, просто jump = true - прыжок, jump и run = true - сальто, jump, run, kick = true - удар в прыжке в движении). Решил таким образом:
Code if (jump){ if (run){ if (kick){ //определяем как удар в прыжке в движении и выполняем. Выходим из цикла } //Определяем как сальто, выполняем, выходим из цикла } if(kick){ //определяем как удар в прыжке, выполняем, выходим } //Определяем как обычный прыжок, ... }
if (run) { //движение }
if (kick) { //удар }
Все выполняется нормально, но не нравится сама организация кода - при десятке действий (а это мелочь), код становится захламленным и трудноредактируемым. Интересуют способы, которыми пользуются более опытные люди. Заранее спасибо.
|
|
| |
Racot | Дата: Вторник, 29 Мая 2012, 14:04 | Сообщение # 2 |
постоянный участник
Сейчас нет на сайте
| Используй Switch case
Специалист "во всем" - специалист "ни в чем" ------------------------------------ Script Reference для Unity3D Помогу со скриптами for Unity3D
|
|
| |
Morfay | Дата: Вторник, 29 Мая 2012, 15:03 | Сообщение # 3 |
почетный гость
Сейчас нет на сайте
| Думал об этом. Но как реализовать сложные действия? да и в switch надо что-то передать (к примеру switch(action), (bool action) ), а потом как?
Code switch(action){ case jump: { case run: { case kick: { // Действие break; } //Действие break; } //Действие break; } }
Ну, если так сделать, то код лучше станет, это да. Но при большом количестве действий картина получится все же не радостной.
|
|
| |
Racot | Дата: Вторник, 29 Мая 2012, 15:16 | Сообщение # 4 |
постоянный участник
Сейчас нет на сайте
| Ну....есть еще один вариант. Использование структур или комбинация Switch case (для кнопок) с if else (для действий).
Специалист "во всем" - специалист "ни в чем" ------------------------------------ Script Reference для Unity3D Помогу со скриптами for Unity3D
|
|
| |
Morfay | Дата: Вторник, 29 Мая 2012, 15:23 | Сообщение # 5 |
почетный гость
Сейчас нет на сайте
| Quote Использование структур или комбинация Switch case (для кнопок) с if else (для действий).
А подробнее можно? Не могу въехать, как оно выглядеть будет.
|
|
| |
Racot | Дата: Вторник, 29 Мая 2012, 15:46 | Сообщение # 6 |
постоянный участник
Сейчас нет на сайте
| Quote (Morfay) Не могу въехать, как оно выглядеть будет. //Создаешь функции для прыгания, бега, удара и переменную Button ..... switch (Button) { case buttonUp: Jump(); break; //Вызываешь Прыжок если нажата кнопка вверх case buttonShift: Run(); break; // Все по аналогии case buttonKeyE: Kick(); break; } ... Получается, что в функциях можешь прописывать и изменять что угодно
Специалист "во всем" - специалист "ни в чем" ------------------------------------ Script Reference для Unity3D Помогу со скриптами for Unity3D
Сообщение отредактировал Racot - Вторник, 29 Мая 2012, 15:50 |
|
| |
Morfay | Дата: Вторник, 29 Мая 2012, 15:54 | Сообщение # 7 |
почетный гость
Сейчас нет на сайте
| Так и задумывалось изначально. Но что делать со сложными нажатиями (комбинациями кнопок)? То есть, если игрок нажмет две-три клавиши, вызвав при этом определенное действие? В итоге, возвращаемся к прошлому варианту с switch case и перечислением (пока это самый оптимальный вариант).
Уточню: функции действий есть (тот же Jump(), Run()). Но чтобы их выполнить, нужно определить что из них выполнять. И проиграть соответственную анимацию.
|
|
| |
Matou | Дата: Вторник, 29 Мая 2012, 16:37 | Сообщение # 8 |
Исходный коТ
Сейчас нет на сайте
| В принципе комбинацию клавиш можно записывать в виде флагов. Но это не очень хорошо если важна последовательность нажатий.
|
|
| |
Racot | Дата: Вторник, 29 Мая 2012, 16:42 | Сообщение # 9 |
постоянный участник
Сейчас нет на сайте
| Quote (Morfay) Но что делать со сложными нажатиями (комбинациями кнопок)? То есть, если игрок нажмет две-три клавиши, вызвав при этом определенное действие?
ставишь на место break, continue например case buttonKeyE: Kick(); continue; или case buttonKeyE: Kick(LeftKick); continue; // ты можешь указывать, какой метод вызывать. Я вызвал LeftKick к примеру. ибо совет Matou
Специалист "во всем" - специалист "ни в чем" ------------------------------------ Script Reference для Unity3D Помогу со скриптами for Unity3D
Сообщение отредактировал Racot - Вторник, 29 Мая 2012, 16:44 |
|
| |
Morfay | Дата: Вторник, 29 Мая 2012, 16:44 | Сообщение # 10 |
почетный гость
Сейчас нет на сайте
| Quote (Matou) В принципе комбинацию клавиш можно записывать в виде флагов. В смысле, делать каждое сложное действие флагом (типа прыжок + удар - bool jumpKick, как-то так )? Тогда проблема не исчезнет - все равно надо узнать когда включить флаг = все то же самое, только еще кода добавится.
Или ты что-то другое имел ввиду?
Quote (Racot) ставишь на место break, continue например case buttonKeyE: Kick(); continue; или case buttonKeyE: Kick(LeftKick); continue; // ты можешь указывать, какой метод вызывать. Я вызвал LeftKick к примеру.
Ребята, видимо я плохо описал суть проблемы, либо чего-то не понимаю. Выполнить определенное действие не проблема, проблема распознать, что именно это действие надо выполнить. Что-то простое (вроде обычного прыжка или движения вправо/влево) делается элементарно. Но если что-то сложное? К примеру, пользователь нажал кнопку вперед+ кнопку вверх+ кнопка удар. Действие назовем "ударом в прыжке в движении" (идиотское название, но есть разница между просто ударом в прыжке (вверх+удар) и таким ударом). Распознание этих активаторов (флагов) есть, но оно слишком уж неоптимальное. В любом случае, нужно определить - нажаты ли эти 3 кнопки (или только 2, или 1). Вот как эту часть упростить (чтобы не было тучи кода, в которой потом хрен что найдешь). Пока самый нормальный вариант - переписать все через switch case (проблемы с тучей кода не решит, но он станет более оптимизированный).
Сообщение отредактировал Morfay - Вторник, 29 Мая 2012, 16:53 |
|
| |
Matou | Дата: Вторник, 29 Мая 2012, 16:49 | Сообщение # 11 |
Исходный коТ
Сейчас нет на сайте
| Наверное у тебя буферизованный ввод, тогда да, флаги не катят.
|
|
| |
Morfay | Дата: Вторник, 29 Мая 2012, 17:02 | Сообщение # 12 |
почетный гость
Сейчас нет на сайте
| Я уже думаю, переписать через switch case и оставить до поры, до времени. Может чего придумаю потом.
|
|
| |
Lord_Zeon | Дата: Вторник, 29 Мая 2012, 20:13 | Сообщение # 13 |
частый гость
Сейчас нет на сайте
| Можно сделать переменную которая будет хранить номер комбинации, а при считывании нажатия клавиш будет складываться общее значение в переменную, по нему можно будет определить какая комбинация будет выполнена. После выполнения сбрасывать переменную и считывать заново. Сам еще не пробовал так сделать, излагаю свои мысли, если пригодиться буду рад.
|
|
| |
Matou | Дата: Вторник, 29 Мая 2012, 20:36 | Сообщение # 14 |
Исходный коТ
Сейчас нет на сайте
| Quote (Lord_Zeon) Можно сделать переменную которая будет хранить номер комбинации, а при считывании нажатия клавиш будет складываться общее значение в переменную, по нему можно будет определить какая комбинация будет выполнена. После выполнения сбрасывать переменную и считывать заново. Сам еще не пробовал так сделать, излагаю свои мысли, если пригодиться буду рад. Это называется флаги, делается немного по другому.
|
|
| |
Lord_Zeon | Дата: Вторник, 29 Мая 2012, 20:43 | Сообщение # 15 |
частый гость
Сейчас нет на сайте
| Matou, Что ж, я к этому сам дошел.
> Делается немного по другому. Подробнее опиши, интересно в чем различие.
|
|
| |
Matou | Дата: Вторник, 29 Мая 2012, 20:50 | Сообщение # 16 |
Исходный коТ
Сейчас нет на сайте
| Quote (Lord_Zeon) Подробнее опиши, интересно в чем различие. В том что надо не складывать а делать побитовое логическое сложение, потом анализировать биты. Складывая и проверяя сумму можно получить тот же результат, но манипуляция с битами проще для понимания.
|
|
| |
Morfay | Дата: Понедельник, 04 Июня 2012, 13:04 | Сообщение # 17 |
почетный гость
Сейчас нет на сайте
| Quote (Matou) В том что надо не складывать а делать побитовое логическое сложение, потом анализировать биты. Складывая и проверяя сумму можно получить тот же результат, но манипуляция с битами проще для понимания.
Quote (Lord_Zeon) Можно сделать переменную которая будет хранить номер комбинации, а при считывании нажатия клавиш будет складываться общее значение в переменную, по нему можно будет определить какая комбинация будет выполнена. После выполнения сбрасывать переменную и считывать заново. Сам еще не пробовал так сделать, излагаю свои мысли, если пригодиться буду рад.
Правильно ли я понял, что каждому действию присваиваем номер (беря выше, например, jump - 1, run - 2, kick - 3). Потом берем переменную (int result), к которой прибавляем значение. Пример:
Code keys = SDL_GetKeyState(NULL); if (keys[SDLK_w]){ jump = true; result +=1;
} if (keys[SDLK_d]){ run = true; result += 2; } if (keys[SDLK_l]){ kick = true; result += 3; } Потом в цикле проверяем - если result = 1 - обычный прыжок, 2 - движение, ..., 6 - удар в прыжке в движении. Если так, то интересная схема получается. Будут свои сложности (пример - при удержании клавиши все время будет прибавляться значение), но объемы кода уменьшатся на порядок. Опробую, спасибо.
Похоже, это будет оптимальный вариант. Вышеназванный вариант с switch case провалился - в case надо передавать константное значение, то есть каждый активатор (jump, kick, run) нужно проверять switch отдельно = кода станет еще больше. В ближайшее время (на этой/ следующей неделе) опробую, напишу что получилось и какие сложности возникли.Добавлено (04.06.2012, 13:04) --------------------------------------------- Итак, опробовал, кое-что получилось. Но возникли проблемы. Сначала как делал: 1) Опознаем нажатие клавиш - тут оставил как было, при нажатии на клавиши активаторы (jump, run kick) устанавливаем true, при отпускании false. 2) В контроллере создаем переменную result = 0, к ней, в зависимости от активатора, прибавляем определенное значение:
Code if (jump){ result += 1; } if (run){ result += 2; } if (kick){ result += 3; }
3) Передаем result в switch и в зависимости от результата выполняем действия: Code switch (result) { case 1: //jump { // } case 2: //run { // } case 3: // kick { // } case 4: // jump + kick { // } case 5: //run + kick { // } case 6: //jump+run+kick { // } } В чем проблема: даже при трех действиях появляются одинаковые значения - jump +run (3) = kick (3). И чем больше действий, тем больше одинаковых значений в результате суммы. Даже если сделать все значения действий нечетными (или же наоборот, четными) количество совпадений уменьшится, но не сильно. Надо что-то придумывать (сейчас на ум приходит только делать действия в разных разрядах: удары/другие действия - единицы, движения- десятки и т.д., но идея не нравится). Еще проблема - увеличивается отклик на нажатие. После нажатия идет задержка, после выполняется действие. Не смертельно, но неприятно.
Сообщение отредактировал Morfay - Среда, 30 Мая 2012, 11:05 |
|
| |
Apati | Дата: Понедельник, 04 Июня 2012, 13:17 | Сообщение # 18 |
заслуженный участник
Сейчас нет на сайте
| Code if (jump){ result += 1; } if (run){ result += 2; } if (kick){ result += 4; } Code switch (result) { case 1: //jump { // } case 2: //run { // } case 3: // jump+run { // } case 4: // kick { // } case 5: //jump + kick { // } case 6: //run+kick { // } case 7: //jump+run+kick { // }
}
|
|
| |
Stalker_Shooter | Дата: Понедельник, 04 Июня 2012, 13:22 | Сообщение # 19 |
3D XNA'шник
Сейчас нет на сайте
| Я, конечно, в плюсах ноль, но почему бы не пользоваться знакомой всем конъюнкцией, тобишь логический союз "И"/&. Всего три-четы условия составить, и парить мозг не надо...
*Не убегай от снайпера, умрешь уставшим. *Мои статьи...
Сообщение отредактировал Stalker_Shooter - Понедельник, 04 Июня 2012, 13:23 |
|
| |
Morfay | Дата: Понедельник, 04 Июня 2012, 14:00 | Сообщение # 20 |
почетный гость
Сейчас нет на сайте
| Apati, понятно же, что действия не три, их будет больше. к примеру с 10. Как тогда будешь делать, чтобы не повториться?
Stalker_Shooter, если я правильно тебя понял, то у меня такой вариант был сразу. Опять же, с тремя действиями 6 вариантов развития. А если действий 10? Или я тебя не понял и ты что-то другое имел ввиду, можно подробнее и с примером?
|
|
| |
|