2013-06-11 4 views
-2

Я хочу реализовать простой интерфейс событий с указателями функций для простой игры на C++. Это будет сделано для улучшения интерфейса события allegro lib. Поэтому я написал следующий код, но он не работает. ЖурналИнтерфейс обработки событий C++ с указателями функций

typedef void (*event_handler)(int); //type for the event handler 
const int TESTKEY_A = 1; // example Key as event arg 

class Game 
{ 
     private: 
       bool is_running ; 
     protected: 
       event_handler on_key_down[2]; 
     public: 
       void run(); 
       void do_events(int e) ; 
       void stop() {is_running = false;} 
}; 
void Game::run() 
{ 
    is_running=true; 
    while(is_running) 
     do_events(1); 
} 

void Game::do_events(int e) 
{ 
    if(e==1) 
    { 
     for(int i = 0; i < 2 ;i++) 
      on_key_down[i](TESTKEY_A); 
    } 
} 

class Pong_Game : public Game 
{ 
     public: 
       Pong_Game(); 
       void On_Key_Down_Player1(int key) { return;} 
       void On_Key_Down_Player2(int key) { return;} 
}; 

Pong_Game::Pong_Game() 
{ 
    on_key_down[0] = &this->On_Key_Down_Player1; 
    on_key_down[1] = &this->On_Key_Down_Player2; 
} 

int main() 
{ 
    Game *my_game = new Pong_Game(); 
    my_game->run(); 
    return 0; 
} 

Компилятор:

Compiler: Default compiler 
Executing g++.exe... 
g++.exe "U:\Eigene Dateien\eventhandler.cpp" -o "U:\Eigene Dateien\eventhandler.exe" -I"C:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include" -I"C:\Dev-Cpp\include\c++\3.4.2\backward" -I"C:\Dev-Cpp\include\c++\3.4.2\mingw32" -I"C:\Dev-Cpp\include\c++\3.4.2" -I"C:\Dev-Cpp\include" -L"C:\Dev-Cpp\lib" 
U:\Eigene Dateien\eventhandler.cpp: In constructor `Pong_Game::Pong_Game()': 
U:\Eigene Dateien\eventhandler.cpp:45: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&Pong_Game::On_Key_Down_Player1' 
U:\Eigene Dateien\eventhandler.cpp:45: error: cannot convert `void (Pong_Game::*)(int)' to `void (*)(int)' in assignment 
U:\Eigene Dateien\eventhandler.cpp:46: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&Pong_Game::On_Key_Down_Player2' 
U:\Eigene Dateien\eventhandler.cpp:46: error: cannot convert `void (Pong_Game::*)(int)' to `void (*)(int)' in assignment 

Execution terminated 

EDIT: - изменен код - добавлен лог компилятор

Спасибо!

+0

Вы должны сообщить нам, как * он не работает *! – Nick

+0

«Это не работает». Как? Ошибка компилятора? Ошибка компоновщика? Сбой? Неожиданное поведение (и что такое ожидаемое поведение)? Мы здесь не волшебники. – Angew

+0

Как уже упоминалось, предоставьте более подробную информацию о проблемах, с которыми вы столкнулись, и кто-то может ответить. –

ответ

1
  1. Вы используете функцию-член для инициализации указателя функции «plain». Функции-члены отличаются от «простых» функций тем, что у них есть скрытый T *this, переданный вместе с функцией.
  2. Это похоже на то, что было бы намного лучше, если бы у него был интерфейс «обработчик событий», реализованный наследованием, чем использование указателей функций.

Что-то вроде этого:

class Game 
{ 
    private: 
     bool is_running ; 
    public: 
     void run(){is_running=true; while(is_running) do_events(1);} 
     void do_events(int e) {if(e==1) On_Key_Down(TESTKEY_A);} 
     void stop() {is_running = false;} 

     virtual void On_Key_Down(int key) = 0; 
     ... other event handlers here ... 
}; 

class Pong_Game : public Game 
{ 
    public: 
     void Pong_Game() {} 
     void On_Key_Down(int key) { // handle key event...} 
     ... other event handlers here ... 
}; 

По комментариям: Чтобы охватить несколько игроков, вы можете реализовать "обработку на игрока событие":

class Player 
{ 
    public: 
    enum moves { move_up, 
       move_down, 
       move_left, 
       move_right, 
       move_jump, 
       move_shoot, ... }; 

    ... 
    virtual void On_Key_Down(int key) = 0; 
    ... 
}; 

class Player_A 
{ 
    public: 
    ... 
    virtual moves On_Key_Down(int key) { if (key == 'W') return move_up; ... } 
} 

class Player_B 
{ 
    public: 
    ... 
    virtual moves On_Key_Down(int key) { if (key == 'I') return move_up; ... } 
} 


class Pong_Game : public Game 
{ 
    private: 
     vector<Player *> players; 
    public: 

     void Pong_Game() {} 
     void On_Key_Down(int key) 
     { 
      for(p : players) { 
       Player::moves m = p->On_key_down(); 
       ... 
      } 
     } 
     ... other event handlers here ... 
}; 

(Это просто быстро взломали - «ходы», возможно, могут быть лучше размещены где-то в другом месте, а точная структура - это просто «то, о чем я мог подумать прямо сейчас» - вам, вероятно, нужен class Player_A_Pong : public Player_A или некоторые из них для решения со спецификой «ракетки игрока А здесь, ракетка игрока Б здесь ...» - хотя, вероятно, есть и другие способы справиться с этим).

+0

Благодарим вас за ответ, но что мне делать, если я хочу добавить несколько событий для события? – Kris

+0

Просьба описать сценарий, который вы ищете, где у вас более одного обработчика событий ... –

+0

Извините за мое плохое описание. Я скорректировал свой пример, и я надеюсь, что теперь стало яснее, что моя цель и моя проблема. – Kris

Смежные вопросы