tBane Temat założony przez niniejszego użytkownika |
[Irrlicht] Eventy w menu » 2024-02-15 15:55:24 Witam. Potrzebuję obsłużyć eventy przycisków z menu. #include <irrlicht.h>
using namespace irr; using namespace core; using namespace scene; using namespace video; using namespace io; using namespace gui; #include<iostream> #include <set>
int width = 720; int height = 480; int bitsPerPixel = 32; bool fullscreen = false; bool stencilbuffer = false; bool vsync = false; int eventReceiver = 0; int clear_r = 48; int clear_g = 48; int clear_b = 48; int clear_a = 256;
IrrlichtDevice * device; IVideoDriver * driver; ISceneManager * sceneManager; IGUIEnvironment * GUI;
IGUIFont * basicFont; IGUIFont * boldFont;
ITexture * TWTexture;
std::string modelPathfile = "Media/TT_RTS_Demo_Character.obj"; std::string modelTexturePathfile = "Media/TT_RTS_Units_blue.png";
IAnimatedMesh * mesh; IAnimatedMeshSceneNode * model; ITexture * modelTexture;
class MyEventReceiver : public IEventReceiver { public: bool KeyIsDown[ KEY_KEY_CODES_COUNT ]; MyEventReceiver(); virtual bool OnEvent( const SEvent & ); virtual bool IsKeyDown( EKEY_CODE ); };
MyEventReceiver::MyEventReceiver() { for( u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i ) KeyIsDown[ i ] = false; }
bool MyEventReceiver::OnEvent( const SEvent & event ) { if( event.EventType == irr::EET_KEY_INPUT_EVENT ) { KeyIsDown[ event.KeyInput.Key ] = event.KeyInput.PressedDown; return true; } return false; }
bool MyEventReceiver::IsKeyDown( EKEY_CODE keyCode ) { return KeyIsDown[ keyCode ]; }
void createWorld() { std::cout << "create world"; }
void saveWorld() { std::cout << "save world"; IGUIFileOpenDialog * dialog = GUI->addFileOpenDialog( L"Please choose a file.", true, 0, - 1, true ); path filename( dialog->getFileName() ); path extension; getFileNameExtension( extension, filename ); if( extension != ".hexmap" ) filename = filename + ".hexmap"; }
void loadWorld() { std::cout << "load world"; IGUIFileOpenDialog * dialog = GUI->addFileOpenDialog( L"Please choose a file.", true, 0, - 1, true ); path filename( dialog->getFileName() ); path extension; getFileNameExtension( extension, filename ); extension.make_lower(); if( extension == ".hexmap" ) { std::cout << "loaded map"; } }
void generateWorld() { std::cout << "generate world"; }
enum { GUI_ID_CREATEWORLD, GUI_ID_LOADWORLD, GUI_ID_SAVEWORLD, GUI_ID_GENERATEWORLD, GUI_ID_TUTORIAL, GUI_ID_INFO };
int main() { MyEventReceiver receiver; device = createDevice( EDT_SOFTWARE, dimension2d < u32 >( width, height ), bitsPerPixel, fullscreen, stencilbuffer, vsync, & receiver ); if( !device ) return 1; driver = device->getVideoDriver(); sceneManager = device->getSceneManager(); GUI = device->getGUIEnvironment(); basicFont = device->getGUIEnvironment()->getBuiltInFont(); boldFont = device->getGUIEnvironment()->getFont( "media/fonthaettenschweiler.bmp" ); IGUISkin * GUIskin = GUI->getSkin(); GUIskin->setFont( boldFont ); for( s32 i = 0; i < gui::EGDC_COUNT; ++i ) { GUIskin->setColor(( EGUI_DEFAULT_COLOR ) i, SColor( 255, 96, 96, 96 ) ); GUIskin->setColor( EGDC_BUTTON_TEXT, SColor( 255, 224, 224, 224 ) ); GUIskin->setColor( EGDC_HIGH_LIGHT_TEXT, SColor( 255, 128, 48, 48 ) ); } IGUIContextMenu * menu = GUI->addMenu(); menu->addItem( L"World", - 1, true, true ); menu->addItem( L"Help", - 1, true, true ); IGUIContextMenu * worldMenu = menu->getSubMenu( 0 ); worldMenu->addItem( L"Create World", GUI_ID_CREATEWORLD ); worldMenu->addSeparator(); worldMenu->addItem( L"Save world", GUI_ID_SAVEWORLD ); worldMenu->addItem( L"Load World", GUI_ID_LOADWORLD ); worldMenu->addSeparator(); worldMenu->addItem( L"Generate World", GUI_ID_GENERATEWORLD ); IGUIContextMenu * helpMenu = menu->getSubMenu( 1 ); helpMenu->addItem( L"Tutorial", GUI_ID_TUTORIAL ); helpMenu->addItem( L"Info", GUI_ID_INFO ); TWTexture = driver->getTexture( "Media/TW.png" ); sceneManager->addCameraSceneNode( 0, vector3df( 0, 30, - 40 ), vector3df( 0, 5, 0 ) ); device->getCursorControl()->setVisible( true ); mesh = sceneManager->getMesh( modelPathfile.c_str() ); if( !mesh ) device->drop(); model = sceneManager->addAnimatedMeshSceneNode( mesh ); model->setScale( vector3df( 10, 10, 10 ) ); model->setPosition( vector3df( 0, 0, 0 ) ); model->setRotation( vector3df( 0, 180, 0 ) ); model->setMaterialFlag( EMF_LIGHTING, false ); model->setMD2Animation( scene::EMAT_STAND ); model->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) ); while( device->run() ) { if( device->isWindowActive() ) { irr::SEvent event; if( receiver.IsKeyDown( irr::KEY_ESCAPE ) ) device->drop(); driver->beginScene( true, true, SColor( clear_a, clear_r, clear_g, clear_b ) ); sceneManager->drawAll(); driver->draw2DImage( TWTexture, position2d < s32 >( 0, height - 128 - 20 ), rect < s32 >( 0, 0, 128, 128 ) ); boldFont->draw( L"TW World Editor v0.1", recti( 20, height - 20, 100, height ), SColor( 256, 128, 48, 48 ), true, true ); GUI->drawAll(); core::position2d < s32 > m = device->getCursorControl()->getPosition(); driver->endScene(); int currentFPS = driver->getFPS(); core::stringw str = L"FPS: "; str += currentFPS; device->setWindowCaption( str.c_str() ); } else device->yield(); } device->drop(); return 0; }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-02-15 20:49:50 Udało mi się częściowo rozwiązać problem. Teraz po otworzeniu menu i zaznaczania któregoś z pól menu w konsoli wyświetla stosowną informację. Ale to po zaznaczeniu a nie kliknięciu, więc problem nadal jest nierozwiązany. #include <irrlicht.h>
using namespace irr; using namespace core; using namespace scene; using namespace video; using namespace io; using namespace gui; #include<iostream> #include <set>
int width = 720; int height = 480; int bitsPerPixel = 32; bool fullscreen = false; bool stencilbuffer = false; bool vsync = false; int eventReceiver = 0; int clear_r = 48; int clear_g = 48; int clear_b = 48; int clear_a = 256;
IrrlichtDevice * device; IVideoDriver * driver; ISceneManager * sceneManager; IGUIEnvironment * GUI;
IGUIFont * basicFont; IGUIFont * boldFont;
ITexture * TWTexture;
std::string modelPathfile = "Media/TT_RTS_Demo_Character.obj"; std::string modelTexturePathfile = "Media/TT_RTS_Units_blue.png";
IAnimatedMesh * mesh; IAnimatedMeshSceneNode * model; ITexture * modelTexture;
enum { GUI_ID_CREATEWORLD, GUI_ID_LOADWORLD, GUI_ID_SAVEWORLD, GUI_ID_GENERATEWORLD, GUI_ID_TUTORIAL, GUI_ID_INFO };
void createWorld(); void loadWorld(); void saveWorld(); void generateWorld();
class MyEventReceiver : public IEventReceiver { public: bool KeyIsDown[ KEY_KEY_CODES_COUNT ]; MyEventReceiver(); virtual bool OnEvent( const SEvent & ); virtual bool IsKeyDown( EKEY_CODE ); bool OnMenuItemSelected( IGUIContextMenu * menu ); };
MyEventReceiver::MyEventReceiver() { for( u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i ) KeyIsDown[ i ] = false; }
bool MyEventReceiver::OnEvent( const SEvent & event ) { if( event.EventType == irr::EET_KEY_INPUT_EVENT ) { KeyIsDown[ event.KeyInput.Key ] = event.KeyInput.PressedDown; return true; } if( event.EventType == EET_GUI_EVENT ) { } return false; }
bool MyEventReceiver::IsKeyDown( EKEY_CODE keyCode ) { return KeyIsDown[ keyCode ]; }
bool MyEventReceiver::OnMenuItemSelected( IGUIContextMenu * menu ) { s32 id = menu->getSelectedItem(); if( id == GUI_ID_CREATEWORLD ) { createWorld(); return true; } if( id == GUI_ID_LOADWORLD ) { loadWorld(); return true; } if( id == GUI_ID_SAVEWORLD ) { saveWorld(); return true; } if( id == GUI_ID_GENERATEWORLD ) { generateWorld(); return true; } return false; }
void createWorld() { std::cout << "create world" << std::endl; }
void loadWorld() { std::cout << "load world" << std::endl; }
void saveWorld() { std::cout << "save world" << std::endl; }
void generateWorld() { std::cout << "generate world" << std::endl; }
int main() { MyEventReceiver receiver; device = createDevice( EDT_SOFTWARE, dimension2d < u32 >( width, height ), bitsPerPixel, fullscreen, stencilbuffer, vsync, & receiver ); if( !device ) return 1; driver = device->getVideoDriver(); sceneManager = device->getSceneManager(); GUI = device->getGUIEnvironment(); basicFont = device->getGUIEnvironment()->getBuiltInFont(); boldFont = device->getGUIEnvironment()->getFont( "media/fonthaettenschweiler.bmp" ); IGUISkin * GUIskin = GUI->getSkin(); GUIskin->setFont( boldFont ); for( s32 i = 0; i < gui::EGDC_COUNT; ++i ) { GUIskin->setColor(( EGUI_DEFAULT_COLOR ) i, SColor( 255, 96, 96, 96 ) ); GUIskin->setColor( EGDC_BUTTON_TEXT, SColor( 255, 224, 224, 224 ) ); GUIskin->setColor( EGDC_HIGH_LIGHT_TEXT, SColor( 255, 128, 48, 48 ) ); } IGUIContextMenu * menu = GUI->addMenu(); menu->addItem( L"World", - 1, true, true ); menu->addItem( L"Help", - 1, true, true ); IGUIContextMenu * worldMenu = menu->getSubMenu( 0 ); worldMenu->addItem( L"Create World", GUI_ID_CREATEWORLD ); worldMenu->addItem( L"Load World", GUI_ID_LOADWORLD ); worldMenu->addItem( L"Save world", GUI_ID_SAVEWORLD ); worldMenu->addItem( L"Generate World", GUI_ID_GENERATEWORLD ); IGUIContextMenu * helpMenu = menu->getSubMenu( 1 ); helpMenu->addItem( L"Tutorial", GUI_ID_TUTORIAL ); helpMenu->addItem( L"Info", GUI_ID_INFO ); TWTexture = driver->getTexture( "Media/TW.png" ); sceneManager->addCameraSceneNode( 0, vector3df( 0, 30, - 40 ), vector3df( 0, 5, 0 ) ); device->getCursorControl()->setVisible( true ); mesh = sceneManager->getMesh( modelPathfile.c_str() ); if( !mesh ) device->drop(); model = sceneManager->addAnimatedMeshSceneNode( mesh ); model->setScale( vector3df( 10, 10, 10 ) ); model->setPosition( vector3df( 0, 0, 0 ) ); model->setRotation( vector3df( 0, 180, 0 ) ); model->setMaterialFlag( EMF_LIGHTING, false ); model->setMD2Animation( scene::EMAT_STAND ); model->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) ); while( device->run() ) { if( device->isWindowActive() ) { irr::SEvent event; if( receiver.IsKeyDown( irr::KEY_ESCAPE ) ) device->drop(); receiver.OnMenuItemSelected( worldMenu ); driver->beginScene( true, true, SColor( clear_a, clear_r, clear_g, clear_b ) ); sceneManager->drawAll(); driver->draw2DImage( TWTexture, position2d < s32 >( 0, height - 128 - 20 ), rect < s32 >( 0, 0, 128, 128 ) ); boldFont->draw( L"TW World Editor v0.1", recti( 20, height - 20, 100, height ), SColor( 256, 128, 48, 48 ), true, true ); GUI->drawAll(); position2d < s32 > m = device->getCursorControl()->getPosition(); driver->endScene(); int currentFPS = driver->getFPS(); core::stringw str = L"FPS: "; str += currentFPS; device->setWindowCaption( str.c_str() ); } else device->yield(); } device->drop(); return 0; }
|
|
DejaVu |
» 2024-02-15 21:46:46 ChatGPT: Aby obsłużyć zdarzenia przycisków w menu przy użyciu Irrlicht Engine, będziesz potrzebować klasy, która implementuje interfejs IEventReceiver. Poniżej znajdziesz przykładową implementację, która obsługuje kliknięcia przycisków w menu: Krok 1: Definicja klasy MyEventReceiver Definiujesz klasę MyEventReceiver, która dziedziczy po IEventReceiver i obsługuje zdarzenia GUI, takie jak kliknięcie przycisku. #include <irrlicht.h>
using namespace irr; using namespace gui;
class MyEventReceiver : public IEventReceiver { public: virtual bool OnEvent( const SEvent & event ) { if( event.EventType == EET_GUI_EVENT ) { s32 id = event.GUIEvent.Caller->getID(); switch( event.GUIEvent.EventType ) { case EGET_BUTTON_CLICKED: switch( id ) { case 101: printf( "Przycisk 'World' został kliknięty.\n" ); break; case 102: printf( "Przycisk 'Help' został kliknięty.\n" ); break; } return true; default: break; } } return false; } };
Krok 2: Utworzenie GUI i przypisanie MyEventReceiver Następnie musisz utworzyć interfejs użytkownika oraz zainstalować MyEventReceiver jako odbiornik zdarzeń dla twojej aplikacji Irrlicht. int main() { MyEventReceiver receiver; IrrlichtDevice * device = createDevice( video::EDT_SOFTWARE, core::dimension2d < u32 >( 640, 480 ), 16, false, false, false, & receiver ); if( !device ) return 1; device->setWindowCaption( L"Przykład menu - Irrlicht Engine" ); video::IVideoDriver * driver = device->getVideoDriver(); gui::IGUIEnvironment * env = device->getGUIEnvironment(); IGUIContextMenu * menu = env->addMenu(); menu->addItem( L"World", 101, true, true ); menu->addItem( L"Help", 102, true, true ); while( device->run() ) { if( device->isWindowActive() ) { driver->beginScene( true, true, video::SColor( 255, 200, 200, 200 ) ); env->drawAll(); driver->endScene(); } } device->drop(); return 0; }
W tym przykładzie, gdy użytkownik kliknie przyciski "World" lub "Help" w menu, metoda OnEvent w klasie MyEventReceiver będzie reagować na te zdarzenia, wypisując odpowiedni komunikat na konsoli. Zwróć uwagę, że w rzeczywistej aplikacji zamiast wypisywania na konsolę prawdopodobnie będziesz chciał wykonać bardziej złożone akcje, takie jak przełączanie ekranów, aktualizacja danych wyświetlanych w GUI itp. Kluczowe jest, aby odpowiednio przypisać unikalne identyfikatory (ID) do elementów GUI i obsłużyć je w metodzie OnEvent. Powyższy kod zakłada, że posiadasz podstawową konfigurację projektu Irrlicht i wszystkie niezbędne pliki nagłówkowe oraz biblioteki są poprawnie dołączone do twojego projektu. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-02-15 22:05:22 skopiowałem kod, błędów nie pokazuje ale ... nie wyświetla tekstu po naduszeniu przycisku |
|
DejaVu |
» 2024-02-15 22:08:02 A gdzie oczekujesz, że zostanie wyświetlony? |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-02-15 22:09:45 w konsoli nie wyświetla informacji o naduszeniu przycisku |
|
DejaVu |
» 2024-02-15 22:11:59 Jeśli komunikaty nie pojawiają się w konsoli po kliknięciu przycisków, możliwe są następujące problemy: Aplikacja nie uruchamia się z konsolą: Jeśli używasz Windows i uruchamiasz aplikację jako aplikację GUI (np. z Visual Studio ustawionym na projekt Win32), konsola może nie być domyślnie widoczna. Możesz spróbować uruchomić aplikację bezpośrednio z cmd.exe lub zmienić typ projektu na aplikację konsolową w ustawieniach projektu w IDE. Zdarzenia nie są przechwytywane: Może się zdarzyć, że zdarzenia z GUI nie są prawidłowo przechwytywane przez MyEventReceiver. Upewnij się, że instancja MyEventReceiver jest poprawnie przekazana do createDevice i że metoda OnEvent jest wywoływana. Problem z przekierowaniem wyjścia: Jeśli używasz środowiska, które może zmieniać standardowe wyjście (stdout), upewnij się, że nie ma przekierowania, które mogłoby zakłócić wyświetlanie na konsoli. Aby zdiagnozować i rozwiązać problem, spróbujmy: Sprawdzić wywołanie OnEvent: Dodaj prosty komunikat na początku metody OnEvent, aby zobaczyć, czy jest ona w ogóle wywoływana. virtual bool OnEvent( const SEvent & event ) { printf( "Zdarzenie przechwycone.\n" ); }
Uruchomić aplikację z linii poleceń: Jeśli do tej pory nie robiłeś tego, spróbuj uruchomić skompilowaną aplikację bezpośrednio z wiersza poleceń (cmd.exe lub terminala), aby zobaczyć, czy komunikaty się pojawiają. Sprawdzenie konfiguracji projektu w IDE: Jeśli używasz Visual Studio, sprawdź, czy projekt jest ustawiony jako aplikacja konsolowa. Możesz to zrobić, przechodząc do właściwości projektu (Prawy klik na projekt → Properties → Linker → System) i sprawdzając, czy opcja "Subsystem" jest ustawiona na "Console". Użyć std::cout zamiast printf: Jest to długi strzał, ale różne środowiska mogą lepiej obsługiwać std::cout z biblioteki iostream zamiast tradycyjnego printf z biblioteki cstdio. #include <iostream>
std::cout << "Przycisk 'World' został kliknięty." << std::endl;
Jeśli po wykonaniu powyższych kroków nadal nie widzisz oczekiwanych wyników, problem może leżeć głębiej w konfiguracji systemu lub środowiska deweloperskiego. Upewnij się, że wszystkie inne aspekty aplikacji działają poprawnie i że środowisko uruchomieniowe Irrlicht jest prawidłowo skonfigurowane. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-02-15 22:18:03 nie działa :-/ class MyEventReceiver : public IEventReceiver { public: virtual bool OnEvent( const SEvent & event ) { std::cout << "jest event i dziala\n"; if( event.EventType == EET_GUI_EVENT ) { std::cout << "jest zdarzenie GUI i dziala\n"; s32 id = event.GUIEvent.Caller->getID(); switch( event.GUIEvent.EventType ) { case EGET_BUTTON_CLICKED: std::cout << "naduszony przycisk i nie dziala\n"; switch( id ) { case 101: std::cout << "Przycisk 'World' został kliknięty.\n"; break; case 102: std::cout << "Przycisk 'Help' został kliknięty.\n"; break; } return true; default: break; } } std::cout << "\n\n\n"; return false; } };
|
|
« 1 » 2 |