Введення опитування проти подій


19

Я розробляю гру, використовуючи опитування для методу введення. Однак тепер, коли я заглиблююсь у меню ігор та інші компоненти інтерфейсу, я вважаю, що, мабуть, хотів би мати внесок, керований подіями. Можливо, навіть є і те, і інше, використовуючи події, керовані для інтерфейсу користувача, і опитування для "світового" вкладу. Мені цікаво, який найкращий шлях - це.

Я визначаю опитування як: кожен цикл оновлення Я перевіряю, які клавіші натискаються, де знаходиться миша, натискаються кнопки, потім виконуються через них і виконую дії, грунтуючись на зібраній інформації.

Я визначаю подію, керовану як: події на основі переривання, коли відбувається подія, і переривання спрацьовує, і блок коду запускається на основі події.

Ви вважаєте, що найкраще проводити всі події, все опитування чи це комбінація обох? Якщо у вас є плюси і мінуси будь-якого, будь ласка, перерахуйте їх. Спасибі.

EDIT

Гра заснована на Java / OpenGL, тому буде випущена в Windows / Mac / Linux. Можливість поширити це на мобільні пристрої низька. Гра в стилі RTS, третя особа 3D.

EDIT 2

Я все ще не зовсім задоволений тим, як я це реалізував, але те, що я рухаюсь, - це ловити події в моєму інтерфейсі, і якщо вони не обробляються жодним із моїх компонентів інтерфейсу, я передаю подію на "Світ" для вибору / відбору. Щось на зразок:

@Override  
private boolean handleEvent(Event event) {  
    if(hud.handleEvent(event)) {  
        return true;  
    }  
    return WORLD.handleEvent(event);  
}

Таким чином я не отримую клацань, що протікають через інтерфейс користувача, щоб вибирати об'єкти за кнопками, а що ні.

Наразі управління моїми камерами все ще базується на опитуванні, і, здається, зараз працює, але згодом я можу оновити це.

Я ціную всі відповіді, вибачте, що могла вибрати лише одну!


6
Я не впевнений у Java, але загалом завжди потрібно опитувати вхід. Потім ви можете публікувати події, коли все змінюється, але це все ще базується на системі опитування.
Джеймс

На мою думку, найбільш релевантний фокус - це створити цикл подій, який не містить будь-якого іншого навантаження, ніж колекція входів. Дозвольте мені пояснити: операційна система зробить введення, що керується входом, і обробить його в глобальній "вхідній потоці", тоді цей потік ОС перенаправить повідомлення в додаток, що знаходиться у фокусі, і запише інтелігентну інформацію в свою чергу повідомлень. Черга повідомлень повинна опитуватися PeekMessage або GetMessage. Найшвидший спосіб отримати це - скористатися GetMessage і дозволити планувальникові розбудити вас, після чого ви можете дуже точно позначити мітку часу.
v.oddou

Відповіді:


17

Це залежить від вимог вашої гри та обладнання. Більшість ігор, як правило, зацікавлені в зміні стану введення, тобто користувач натискає клавішу вогню і зброя починає стріляти, користувач відпускає вогневий ключ і зброя припиняє стріляти, користувач натискає клавішу переміщення і починає рух, відпускає клавішу переміщення і припиняє рух тощо, тому система введення з урахуванням подій має найбільш сенс у тих випадках, оскільки інформація вже у відповідному форматі. Крім того, на платформі Windows ви вже отримуєте події для зміни стану клавіатури та миші, тому часто це перетворення 1: 1 з подій низького рівня введення в ігрові події високого рівня. Під час опитування часто виникає необхідність генерувати такі події вручну, порівнюючи стан між поточним та останнім кадрами. В основному, "які кнопки зараз натиснуті?"

Це означає, що на певних платформах ви застрягаєте з введенням опитувань на низькому рівні, і немає ніякого способу зробити перевірку краю. Однак я завжди домагався найкращих результатів, використовуючи події за всіма логіками високого рівня, тому що, як правило, ці системи прагнуть працювати.


Дякую, я включив додаткову інформацію про платформу та мету гри.
MichaelHouse

1
Зауважте, що GetAsyncKeyStateце простий спосіб використання опитування на Win32.
Макке

Дерп, я поставив запитання в коментарях Нейт Бросса, з якими ви тут розбираєтесь, тому, мабуть, я уточнив це. Чи всі комп'ютери пропонують, щоб апаратне забезпечення 1: 1 перервало зв'язок подій на клавіатурі ОС, а які платформи обмежені опитуванням низького рівня?
michael.bartnett

@Macke: іноді антивірус повідомляє про програми, які використовують цей API, оскільки вони можуть отримувати натискання клавіш з усієї глобальної системи, таким чином, умикаючи зловмисні журнали. Найдивовижніша стаття про це в усьому Інтернеті (я знаю про це): ця: securelist.com/analysis/publications/36358/…
v.oddou

7

Я не бачу причин, щоб ви не могли зробити обоє, і отримати найкраще з обох світів.

Події введення генеруються при опитуванні (на певному рівні драйвер опитує апаратне забезпечення, щоб побачити, у якому стані знаходиться його), і оскільки ваш основний цикл опитує всі пристрої введення, ви можете легко реалізувати свій власний. Щось таке, як нижче, - це те, що я використовував у минулому.

mouseInput = GetMouse();
kbInput = GetKeyboard();


// refactor this out to its own method if it makes sense
if menuState == Showing
    if mouseInput.LeftButton == State.Pressed
        LeftButton(mouseInput.X, mouseInput.Y)

// rest of game input code processing

void LeftButton(int x, int y)
{
    // left button event handler
}

Я знаю, що ви визначили події перервами, і те, що я тут помістив, не є "справді заснованим на події", але я не бачу, що вище сказане не дає вам, що переривання дають вам - більшість користувачів не помітять один кадр втрачено, якщо ваша гра не працює з дуже низькою швидкістю кадрів.


1
Мені цікаво характер отримання інформації від пристроїв. Чи події клавіатури, що надсилаються ОС, є результатом опитування на рівні драйверів пристрою? Або подія клавіатури відповідає перерві? Або є переривання, але ОС їх буферизує та розсилає, коли вважає за потрібне?
michael.bartnett

Я не впевнений у тому, як він працює на цьому рівні, але це найосновніше, що деяке програмне забезпечення працює в циклі і перевіряє стан клавіатури і порівнює його з попереднім станом, якщо його зміна зміна набухає.
Нейт

5

Тут є два різні питання:

  1. Як ви читаєте дані користувача з ОС / обладнання?

  2. Як ви обробляєте введення користувачів у свій движок?

Для читання це чітко залежить від вашої платформи та того, який тип входу ви хочете прочитати. Зауважте, що легко перетворити одну річ на іншу у вхідному шарі. (Тобто опитування та випромінювання подій у двигуні або прослуховування подій та випромінення стану двигуна.)

Для обробки існує кілька різних варіантів:

  • Для контролю руху гравця (і подібних схем) опитування може бути простішим, оскільки потрібно перерахувати швидкість кожного кадру. Цілком ймовірно, що ваш внутрішній цикл буде опитуватись на основі опитування:

    тобто щось подібне speed += 1 if button.down else -1; clamp(speed, 0, 42);

  • Для дискретних подій (вогнепальна ракета, гра на паузу, телепорт на інший бік планети) обробка подій бажана, інакше ваш код буде завалений maybeLaunchMissile(key_state);дзвінками, і це просто ... погано, добре. ;)

Сподіваюся, це допомагає.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.