Четверг, 18 Апреля 2024, 09:18

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Форум игроделов » Программирование » C/C++ » Описание действий в игре. (Как лучше описать действия, выполняемые персонажем и NPC?)
Описание действий в игре.
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? Или я тебя не понял и ты что-то другое имел ввиду, можно подробнее и с примером?
Форум игроделов » Программирование » C/C++ » Описание действий в игре. (Как лучше описать действия, выполняемые персонажем и NPC?)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг