Обработка событий с использованием SDL и C для моего движка хобби - PullRequest
1 голос
/ 24 апреля 2020

Я создаю движок для 2d-игр для хобби / минимализма, используя SDL и C в качестве языка программирования. Кроме того, следуя инструкциям Lazy Foo Production. Я использую язык C для целей обучения.

Я хотел бы реализовать функцию общего обработчика событий, которая могла бы запускать пользовательскую функцию для обработки данного события. В настоящее время я все еще на начальных этапах.

файл заголовка обработчика:

#ifndef HANDLER_H
#define HANDLER_H

#include <SDL2/SDL.h>
#include <stdarg.h>

int handle(SDL_Event e, void (*handler)(int args,...));

#endif

Код клиента:

        int quit = FALSE;
        SDL_Event e;
        while (quit == FALSE) {
                while (SDL_PollEvent(&e) != 0) {
                        if (e.type == SDL_QUIT) {
                                quit = TRUE;
                        }
                        //call to handle goes here
                }

                render_image(&dp,&i_p);
                update_display(&dp);
        }

Достаточно ли нам указателя функции как параметр handle() или есть лучший способ для реализации обобщенного обработчика событий c.

Моя основная цель для движка с точки зрения обработки событий - просто иметь возможность иметь handler обрабатывать события, которые опрашиваются в игре l oop, используя функцию, написанную конечным пользователем, вместо жесткого кодирования в функциях для обработки любого типа возможного события.

1 Ответ

1 голос
/ 24 апреля 2020

Если вы хотите, чтобы конечные пользователи писали функции для обработки событий, я бы предложил использовать callbacks . Идея состоит в том, что конечный пользователь будет диктовать , какой обработчик события вызывать для каждого типа события, тогда как игровой движок будет диктовать , когда вызвать соответствующий обработчик события.

Пользователю предоставляется структура обратных вызовов, чтобы пользовательский код мог определять пользовательские обработчики событий и настраивать эти обратные вызовы для обращения к этим пользовательским функциям. Затем l oop для обработки событий игрового движка вызывает эти функции с помощью обратных вызовов, установленных пользователем.


Пример

Вы можете определить разные типы функций для разных events:

typedef void (*quit_handler_t)(void);
typedef void (*keydown_handler_t)(SDL_Keycode);
typedef void (*keyup_handler_t)(SDL_Keycode);

То есть обработчик для выхода не принимает аргументов, тогда как для ключа, идущего вверх и вниз, принимает аргумент, представляющий соответствующий ключ.

Затем вы предоставляете клиент со структурой event_handlers, которая содержит указатели на обработчики событий, и конечный пользователь должен заполнить:

struct {
   quit_handler_t    quit;
   keydown_handler_t keydown;
   keyup_handler_t   keyup;
} event_handlers;

Наконец, игровой движок l oop для обработки вызова событий те функции через обратные вызовы, которые были установлены пользователем:

SDL_Event e;
while (!quit && SDL_PollEvent(&e)) {
   switch(e.type) {
   case SDL_QUIT:
      event_handlers.quit();
      break;
   case SDL_KEYDOWN:
      event_handlers.keydown(e.key.keysym.sym);
      break;
   case SDL_KEYUP:
      event_handlers.keyup(e.key.keysum.sym);
      break;
   }
}

Обратите внимание, что игровой движок может также инициализировать структуру event_handler с обработчиками событий по умолчанию . Конечный пользователь сможет переопределить это поведение по умолчанию, изменив элементы event_handler.

...