tBane Temat założony przez niniejszego użytkownika |
[Irrlicht] Zwracanie klikniętego pola na mapie » 2024-02-19 20:59:10 Witam. Piszę "Edytor Mapy". Potrzebuję uzyskać informacje, które pole zostało naduszone, aby móc za pomocą kliknięć myszy edytować mapę. #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 screenWidth = 1080; int screenHeight = 720; int bitsPerPixel = 32; bool fullscreen = false; bool stencilbuffer = false; bool vsync = false; int eventReceiver = 0; int cam_x, cam_y, cam_z;
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 * modelMesh; IAnimatedMeshSceneNode * animModel1; IAnimatedMeshSceneNode * animModel2; IAnimatedMeshSceneNode * animModel3; ITexture * modelTexture;
enum { GUI_CREATEWORLD, GUI_LOADWORLD, GUI_SAVEWORLD, GUI_GENERATEWORLD, GUI_TUTORIAL, GUI_INFO, BAR_BUTTON_WATER, BAR_BUTTON_SANDS, BAR_BUTTON_GRASS, BAR_BUTTON_ROCKS, BAR_BUTTON_HIGHLANDS, BAR_BUTTON_DARKNESS };
float outerRadius = 10.0f; float innerRadius = outerRadius * 0.866025404f; float heighStep = 0.8f;
float hexVertices[ ] = { 0.0f, outerRadius, innerRadius, outerRadius * 0.5f, innerRadius, - outerRadius * 0.5f, 0.0f, - outerRadius, - innerRadius, - outerRadius * 0.5f, - innerRadius, outerRadius * 0.5f, 0.0f, outerRadius };
float texture_uv[ ] { 0.0f, 1.0f, 1.0f, 0.5f, 1.0f, - 0.5f, 0.0f, - 1.0f, - 1.0f, - 0.5f, - 1.0f, 0.5f, 0.0f, 1.0f, };
float hexToGlobalX( float x, float z ) { return x * 2.0f * innerRadius +( int( z ) % 2 ) * innerRadius; }
float hexToGlobalZ( float z ) { return z * 1.5f * outerRadius; }
enum class terrainType { water, sands, grass, rocks, highlands, darkness };
terrainType paint = terrainType::grass;
ITexture * getTexture( terrainType ttype ) { ITexture * tex = 0; if( ttype == terrainType::sands ) tex = driver->getTexture( "Media/Terrains/sands.png" ); if( ttype == terrainType::grass ) tex = driver->getTexture( "Media/Terrains/grass.png" ); return tex; }
class HexTile : public scene::ISceneNode { aabbox3d < f32 > Box; S3DVertex Vertices[ 8 ]; SMaterial Material; public: terrainType ttype; HexTile( ISceneNode * parent, ISceneManager * mgr, s32 id ); virtual void OnRegisterSceneNode(); virtual void render(); virtual const aabbox3d < f32 > & getBoundingBox() const; virtual u32 getMaterialCount() const; virtual SMaterial & getMaterial( u32 i ); void setTexture( ITexture * ); void setTerrainType( terrainType ); };
HexTile::HexTile( ISceneNode * parent, ISceneManager * mgr, s32 id ) : ISceneNode( parent, mgr, id ) { ttype = terrainType::grass; Material.Wireframe = false; Material.Lighting = false; Material.setTexture( 0, getTexture( ttype ) ); SColor color = SColor( 255, 255, 255, 255 ); for( int i = 0; i < 7; i++ ) Vertices[ i + 1 ] = S3DVertex( hexVertices[ 2 * i ], 0, hexVertices[ 2 * i + 1 ], 0, 0, 0, color, texture_uv[ 2 * i ], texture_uv[ 2 * i + 1 ] ); Box.reset( Vertices[ 0 ].Pos ); for( s32 i = 1; i < 7; ++i ) Box.addInternalPoint( Vertices[ i ].Pos ); }
void HexTile::OnRegisterSceneNode() { if( IsVisible ) SceneManager->registerNodeForRendering( this ); ISceneNode::OnRegisterSceneNode(); }
void HexTile::render() { u16 indices[ ] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7 }; IVideoDriver * driver = SceneManager->getVideoDriver(); driver->setMaterial( Material ); driver->setTransform( video::ETS_WORLD, AbsoluteTransformation ); driver->drawVertexPrimitiveList( & Vertices[ 0 ], 3, & indices[ 0 ], 6, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT ); }
const aabbox3d < f32 > & HexTile::getBoundingBox() const { return Box; }
u32 HexTile::getMaterialCount() const { return 1; }
SMaterial & HexTile::getMaterial( u32 i ) { return Material; }
void HexTile::setTexture( ITexture * tex ) { Material.setTexture( 0, tex ); }
void HexTile::setTerrainType( terrainType ttype ) { this->ttype = ttype; setTexture( getTexture( ttype ) ); }
class HexMap { public: std::set < HexTile * > tiles; HexMap(); ~HexMap(); void addTile( HexTile * ); };
HexMap::HexMap() { tiles.clear(); }
HexMap::~HexMap() { }
void HexMap::addTile( HexTile * tile ) { tiles.insert( tile ); }
void thisIsNotBuildYet() { int rectWidth = 300; int rectHeight = 300; int x1 =( screenWidth - rectWidth ) / 2; int x2 =( screenWidth + rectWidth ) / 2; int y1 =( screenHeight - rectHeight ) / 2; int y2 =( screenHeight + rectHeight ) / 2; rect < s32 > rectangle = rect < s32 >( x1, y1, x2, y2 ); IGUIWindow * window = GUI->addWindow( rectangle ); const wchar_t * t = L"This section is not build yed"; IGUIStaticText * text = GUI->addStaticText( t, rect < s32 >( 0, 20, rectWidth, rectHeight ), true, true, window, - 1, true ); text->setTextAlignment( EGUIA_CENTER, EGUIA_CENTER ); }
void createWorld() { std::cout << "created new world" << std::endl; thisIsNotBuildYet(); }
void loadWorld() { std::cout << "load world" << std::endl; thisIsNotBuildYet(); }
void saveWorld() { std::cout << "save world" << std::endl; thisIsNotBuildYet(); }
void generateWorld() { std::cout << "generate world" << std::endl; thisIsNotBuildYet(); }
void tutorial() { std::cout << "tutorial" << std::endl; thisIsNotBuildYet(); }
void info() { std::cout << "info" << std::endl; int rectWidth = 300; int rectHeight = 300; int x1 =( screenWidth - rectWidth ) / 2; int x2 =( screenWidth + rectWidth ) / 2; int y1 =( screenHeight - rectHeight ) / 2; int y2 =( screenHeight + rectHeight ) / 2; rect < s32 > rectangle = rect < s32 >( x1, y1, x2, y2 ); IGUIWindow * window = GUI->addWindow( rectangle ); const wchar_t * t = L"Program created by tBane"; IGUIStaticText * text = GUI->addStaticText( t, rect < s32 >( 0, 20, rectWidth, rectHeight ), true, true, window, - 1, true ); text->setTextAlignment( EGUIA_CENTER, EGUIA_CENTER ); }
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 ) { switch( event.GUIEvent.EventType ) { case EGET_MENU_ITEM_SELECTED: { IGUIContextMenu * menu =( IGUIContextMenu * ) event.GUIEvent.Caller; s32 id = menu->getItemCommandId( menu->getSelectedItem() ); if( id == GUI_CREATEWORLD ) createWorld(); if( id == GUI_LOADWORLD ) loadWorld(); if( id == GUI_SAVEWORLD ) saveWorld(); if( id == GUI_GENERATEWORLD ) generateWorld(); if( id == GUI_TUTORIAL ) tutorial(); if( id == GUI_INFO ) info(); } break; case EGET_BUTTON_CLICKED: { s32 id = event.GUIEvent.Caller->getID(); if( id == BAR_BUTTON_WATER ) paint = terrainType::water; if( id == BAR_BUTTON_SANDS ) paint = terrainType::sands; if( id == BAR_BUTTON_GRASS ) paint = terrainType::grass; if( id == BAR_BUTTON_ROCKS ) paint = terrainType::rocks; if( id == BAR_BUTTON_HIGHLANDS ) paint = terrainType::highlands; if( id == BAR_BUTTON_DARKNESS ) paint = terrainType::darkness; std::cout << "setted a paint" << std::endl; } break; default: break; } } return false; }
bool MyEventReceiver::IsKeyDown( EKEY_CODE keyCode ) { return KeyIsDown[ keyCode ]; } int main() { MyEventReceiver receiver; device = createDevice( EDT_SOFTWARE, dimension2d < u32 >( screenWidth, screenHeight ), 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_CREATEWORLD ); worldMenu->addItem( L"Load World", GUI_LOADWORLD ); worldMenu->addItem( L"Save world", GUI_SAVEWORLD ); worldMenu->addItem( L"Generate World", GUI_GENERATEWORLD ); IGUIContextMenu * helpMenu = menu->getSubMenu( 1 ); helpMenu->addItem( L"Tutorial", GUI_TUTORIAL ); helpMenu->addItem( L"Info", GUI_INFO ); gui::IGUIToolBar * bar = GUI->addToolBar(); bar->setMinSize( dimension2du( screenWidth, 48 ) ); IGUIButton * water = bar->addButton( BAR_BUTTON_WATER, 0, L"water", driver->getTexture( "Media/GUI/water.png" ), 0, false, true ); IGUIButton * sands = bar->addButton( BAR_BUTTON_SANDS, 0, L"sands", driver->getTexture( "Media/GUI/sands.png" ), 0, false, true ); IGUIButton * grass = bar->addButton( BAR_BUTTON_GRASS, 0, L"grass", driver->getTexture( "Media/GUI/grass.png" ), 0, false, true ); IGUIButton * rocks = bar->addButton( BAR_BUTTON_ROCKS, 0, L"rocks", driver->getTexture( "Media/GUI/rocks.png" ), 0, false, true ); IGUIButton * highlands = bar->addButton( BAR_BUTTON_HIGHLANDS, 0, L"highlands", driver->getTexture( "Media/GUI/highlands.png" ), 0, false, true ); IGUIButton * darkness = bar->addButton( BAR_BUTTON_DARKNESS, 0, L"darkness", driver->getTexture( "Media/GUI/darkness.png" ), 0, false, true ); TWTexture = driver->getTexture( "Media/TW.png" ); cam_x = 0; cam_y = 100; cam_z = - 40; ICameraSceneNode * cam = sceneManager->addCameraSceneNode( 0, vector3df( cam_x, 30, cam_z ), vector3df( 0, 5, 0 ) ); cam->setTarget( vector3df( cam_x, cam_y, cam_z ) ); cam->setUpVector( vector3df( cam_x, cam_y, cam_z ) ); device->getCursorControl()->setVisible( true ); modelMesh = sceneManager->getMesh( modelPathfile.c_str() ); if( !modelMesh ) device->drop(); animModel1 = sceneManager->addAnimatedMeshSceneNode( modelMesh ); animModel1->setScale( vector3df( 10, 10, 10 ) ); animModel1->setPosition( vector3df( hexToGlobalX( 0, 0 ), 0, hexToGlobalZ( 0 ) ) ); animModel1->setRotation( vector3df( 0, 180, 0 ) ); animModel1->setMaterialFlag( EMF_LIGHTING, false ); animModel1->setMD2Animation( scene::EMAT_STAND ); animModel1->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) ); animModel2 = sceneManager->addAnimatedMeshSceneNode( modelMesh ); animModel2->setScale( vector3df( 10, 10, 10 ) ); animModel2->setPosition( vector3df( hexToGlobalX( 3, 4 ), 0, hexToGlobalZ( 4 ) ) ); animModel2->setRotation( vector3df( 0, 180, 0 ) ); animModel2->setMaterialFlag( EMF_LIGHTING, false ); animModel2->setMD2Animation( scene::EMAT_STAND ); animModel2->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) ); animModel3 = sceneManager->addAnimatedMeshSceneNode( modelMesh ); animModel3->setScale( vector3df( 10, 10, 10 ) ); animModel3->setPosition( vector3df( hexToGlobalX( 7, 5 ), 0, hexToGlobalZ( 5 ) ) ); animModel3->setRotation( vector3df( 0, 180, 0 ) ); animModel3->setMaterialFlag( EMF_LIGHTING, false ); animModel3->setMD2Animation( scene::EMAT_STAND ); animModel3->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) ); HexMap * hexMap = new HexMap(); for( int z = 0; z < 40; z++ ) { for( int x = 0; x < 40; x++ ) { HexTile * tile = new HexTile( sceneManager->getRootSceneNode(), sceneManager, - 1 ); tile->setPosition( vector3df( hexToGlobalX( x, z ), 0, hexToGlobalZ( z ) ) ); hexMap->addTile( tile ); } } while( device->run() ) { if( device->isWindowActive() ) { if( receiver.IsKeyDown( irr::KEY_ESCAPE ) ) { device->drop(); return 0; } if( receiver.IsKeyDown( irr::KEY_KEY_A ) || receiver.IsKeyDown( irr::KEY_LEFT ) ) cam_x -= 1.0f; if( receiver.IsKeyDown( irr::KEY_KEY_D ) || receiver.IsKeyDown( irr::KEY_RIGHT ) ) cam_x += 1.0f; if( receiver.IsKeyDown( irr::KEY_KEY_W ) || receiver.IsKeyDown( irr::KEY_UP ) ) cam_z += 1.0f; if( receiver.IsKeyDown( irr::KEY_KEY_S ) || receiver.IsKeyDown( irr::KEY_DOWN ) ) cam_z -= 1.0f; cam->setPosition( vector3df( cam_x, cam_y, cam_z ) ); cam->setTarget( vector3df( cam_x, 30, cam_z + 50 ) ); driver->beginScene( true, true, SColor( clear_a, clear_r, clear_g, clear_b ) ); sceneManager->drawAll(); driver->draw2DImage( TWTexture, position2d < s32 >( 0, screenHeight - 128 - 20 ), rect < s32 >( 0, 0, 128, 128 ) ); boldFont->draw( L"TW World Editor v0.1", recti( 20, screenHeight - 20, 100, screenHeight ), 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-19 21:45:27 Zapisz sobie w zmiennej 'jaki jest aktualny pędzel'. Najprostszym przykładem jest Paint. Odpal go sobie, kliknij na kolor. Widzisz jaki jest aktywny kolor (osobna zmienna), a gdy klikasz myszką na obszarze rysowania to używany jest ten kolor. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-02-19 21:48:31 Tą pierwszą część zrobiłem. A tą drugą .. to nie mam pojęcia jak odczytać naduszone pole. terrainType paint = terrainType::grass;
|
|
DejaVu |
» 2024-02-19 21:54:52 Zmienna nie powinna być lokalna, tylko 'globalna', abyś mógł się do niej jakoś dostać z innego miejsca niż przycisk. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-02-19 21:56:57 Przecież jest globalna. |
|
DejaVu |
» 2024-02-19 22:21:10 Chodzi Ci o identyfikację, które pole na mapie zostało kliknięte, aby je zmienić? Musisz zobaczyć jak się nazywa metoda w Irrlicht, która umożliwia Ci identyfikację punktu nad którym znajduje się kursor myszy (jeżeli jest taka metoda). To są problemy, które dochodzą z perspektywą. ChatGPT: W Irrlicht Engine istnieje funkcjonalność, która pozwala na obliczenie promienia (ray) od kamery do punktu wskazywanego przez kursor myszy. Możesz wykorzystać tę funkcję do wykrywania, na które pole kafelkowej mapy terenu wskazuje kursor, nawet jeśli kamera jest ustawiona pod kątem. Proces ten, znany jako "ray casting", jest często używany do interakcji z obiektami 3D w scenie. Oto kroki, jak to zrobić: 1. Oblicz Promień od Kamery do Kursora Musisz przekształcić pozycję kursora myszy na ekranie do przestrzeni 3D, tworząc promień (ray) wychodzący z kamery. core::line3d < f32 > calculateRayFromScreenCoordinates( const core::position2d < s32 > & mousePos, ISceneManager * smgr ) { const scene::ICameraSceneNode * camera = smgr->getActiveCamera(); core::line3d < f32 > ray; if( camera ) { ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates( mousePos, camera ); } return ray; } 2. Wykryj Kolizję Promienia z Terenem Następnie, użyj wyliczonego promienia do znalezienia punktu na terenie, w który promień się wbija. Irrlicht posiada narzędzia do detekcji kolizji, które możesz wykorzystać do tego celu. core::vector3df getIntersectionWithTerrain( const core::line3d < f32 > & ray, ISceneManager * smgr ) { core::vector3df intersection; core::triangle3df hitTriangle; scene::ISceneNode * terrainNode = smgr->getSceneNodeFromType( scene::ESNT_TERRAIN ); scene::ITriangleSelector * selector = 0; if( terrainNode ) { selector = smgr->createTriangleSelectorFromBoundingBox( terrainNode ); } if( selector ) { scene::ISceneCollisionManager * collMan = smgr->getSceneCollisionManager(); if( collMan->getCollisionPoint( ray, selector, intersection, hitTriangle, terrainNode ) ) { selector->drop(); return intersection; } selector->drop(); } return core::vector3df( 0, 0, 0 ); }
3. Przelicz Punkt Przecięcia na Koordynaty Kafelka Po znalezieniu punktu przecięcia na terenie, musisz przeliczyć ten punkt 3D na koordynaty twojej kafelkowej mapy. To wymaga znajomości rozmiaru kafelków i struktury mapy. core::vector2di convert3DPositionToTileCoordinates( const core::vector3df & position, f32 tileSize ) { int x =( int ) floor( position.X / tileSize ); int z =( int ) floor( position.Z / tileSize ); return core::vector2di( x, z ); }
Przykładowe Użycie void update() { ISceneManager * smgr = device->getSceneManager(); IVideoDriver * driver = device->getVideoDriver(); core::position2d < s32 > mousePos = device->getCursorControl()->getPosition(); core::line3d < f32 > ray = calculateRayFromScreenCoordinates( mousePos, smgr ); core::vector3df intersection = getIntersectionWithTerrain( ray, smgr ); core::vector2di tileCoords = convert3DPositionToTileCoordinates( intersection, TILE_SIZE ); }
Warto zauważyć, że potrzebujesz znać TILE_SIZE, czyli rozmiar kafelka na twojej mapie, aby prawidłowo przeliczyć pozycję 3D na koordynaty kafelka. Podsumowując, używając funkcji detekcji kolizji Irrlichta i odpowiednich przeliczeń, możesz wykryć, na który kafel kursor myszy wskazuje, nawet jeśli kamera jest pod kątem. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-02-20 14:58:15 nie zadziałało niestety :-/ wypisuje mi tileCoords jako [0,0] #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> #include<vector>
int screenWidth = 1080; int screenHeight = 720; int bitsPerPixel = 32; bool fullscreen = false; bool stencilbuffer = false; bool vsync = false; int eventReceiver = 0; int cam_x, cam_y, cam_z;
int clear_r = 48; int clear_g = 48; int clear_b = 48; int clear_a = 256;
IrrlichtDevice * device; IVideoDriver * driver; ISceneManager * smgr; 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 * modelMesh; IAnimatedMeshSceneNode * animModel1; IAnimatedMeshSceneNode * animModel2; IAnimatedMeshSceneNode * animModel3; ITexture * modelTexture;
enum { GUI_CREATEWORLD, GUI_LOADWORLD, GUI_SAVEWORLD, GUI_GENERATEWORLD, GUI_TUTORIAL, GUI_INFO, BAR_BUTTON_WATER, BAR_BUTTON_SANDS, BAR_BUTTON_GRASS, BAR_BUTTON_ROCKS, BAR_BUTTON_HIGHLANDS, BAR_BUTTON_DARKNESS };
float outerRadius = 10.0f; float innerRadius = outerRadius * 0.866025404f; float heighStep = 0.8f;
float hexVertices[ ] = { 0.0f, outerRadius, innerRadius, outerRadius * 0.5f, innerRadius, - outerRadius * 0.5f, 0.0f, - outerRadius, - innerRadius, - outerRadius * 0.5f, - innerRadius, outerRadius * 0.5f, 0.0f, outerRadius };
float texture_uv[ ] { 0.0f, 1.0f, 1.0f, 0.5f, 1.0f, - 0.5f, 0.0f, - 1.0f, - 1.0f, - 0.5f, - 1.0f, 0.5f, 0.0f, 1.0f, };
float hexToGlobalX( float x, float z ) { return x * 2.0f * innerRadius +( int( z ) % 2 ) * innerRadius; }
float hexToGlobalZ( float z ) { return z * 1.5f * outerRadius; }
enum class terrainType { water, sands, grass, rocks, highlands, darkness };
terrainType paint = terrainType::grass;
ITexture * getTexture( terrainType ttype ) { ITexture * tex = 0; if( ttype == terrainType::water ) tex = driver->getTexture( "Media/Terrains/water.png" ); if( ttype == terrainType::sands ) tex = driver->getTexture( "Media/Terrains/sands.png" ); if( ttype == terrainType::grass ) tex = driver->getTexture( "Media/Terrains/grass.png" ); if( ttype == terrainType::rocks ) tex = driver->getTexture( "Media/Terrains/rocks.png" ); if( ttype == terrainType::highlands ) tex = driver->getTexture( "Media/Terrains/highlands.png" ); if( ttype == terrainType::darkness ) tex = driver->getTexture( "Media/Terrains/darkness.png" ); return tex; }
class HexTile : public scene::ISceneNode { aabbox3d < f32 > Box; S3DVertex Vertices[ 8 ]; SMaterial Material; public: terrainType ttype; HexTile( ISceneNode * parent, ISceneManager * smgr, s32 id ); virtual void OnRegisterSceneNode(); virtual void render(); virtual const aabbox3d < f32 > & getBoundingBox() const; virtual u32 getMaterialCount() const; virtual SMaterial & getMaterial( u32 i ); void setTexture( ITexture * ); void setTerrainType( terrainType ); };
HexTile::HexTile( ISceneNode * parent, ISceneManager * smgr, s32 id ) : ISceneNode( parent, smgr, id ) { ttype = terrainType::grass; Material.Wireframe = false; Material.Lighting = false; Material.setTexture( 0, getTexture( ttype ) ); SColor color = SColor( 255, 255, 255, 255 ); for( int i = 0; i < 7; i++ ) Vertices[ i + 1 ] = S3DVertex( hexVertices[ 2 * i ], 0.0f, hexVertices[ 2 * i + 1 ], 0, 0, 0, color, texture_uv[ 2 * i ], texture_uv[ 2 * i + 1 ] ); Box.reset( Vertices[ 0 ].Pos ); for( s32 i = 1; i < 7; ++i ) Box.addInternalPoint( Vertices[ i ].Pos ); }
void HexTile::OnRegisterSceneNode() { if( IsVisible ) SceneManager->registerNodeForRendering( this ); ISceneNode::OnRegisterSceneNode(); }
void HexTile::render() { u16 indices[ ] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7 }; IVideoDriver * driver = smgr->getVideoDriver(); driver->setMaterial( Material ); driver->setTransform( video::ETS_WORLD, AbsoluteTransformation ); driver->drawVertexPrimitiveList( & Vertices[ 0 ], 3, & indices[ 0 ], 6, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT ); }
const aabbox3d < f32 > & HexTile::getBoundingBox() const { return Box; }
u32 HexTile::getMaterialCount() const { return 1; }
SMaterial & HexTile::getMaterial( u32 i ) { return Material; }
void HexTile::setTexture( ITexture * tex ) { Material.setTexture( 0, tex ); }
void HexTile::setTerrainType( terrainType ttype ) { this->ttype = ttype; setTexture( getTexture( ttype ) ); }
class HexMap { public: std::vector < HexTile * > tiles; HexMap(); ~HexMap(); void addTile( HexTile * ); void setTerrainType( terrainType ); };
HexMap::HexMap() { tiles.clear(); }
HexMap::~HexMap() { }
void HexMap::addTile( HexTile * tile ) { tiles.push_back( tile ); }
void HexMap::setTerrainType( terrainType ttype ) { for( auto & t: tiles ) t->setTerrainType( ttype ); }
HexMap * hexMap;
void thisIsNotBuildYet() { int rectWidth = 300; int rectHeight = 300; int x1 =( screenWidth - rectWidth ) / 2; int x2 =( screenWidth + rectWidth ) / 2; int y1 =( screenHeight - rectHeight ) / 2; int y2 =( screenHeight + rectHeight ) / 2; rect < s32 > rectangle = rect < s32 >( x1, y1, x2, y2 ); IGUIWindow * window = GUI->addWindow( rectangle ); const wchar_t * t = L"This section is not build yed"; IGUIStaticText * text = GUI->addStaticText( t, rect < s32 >( 0, 20, rectWidth, rectHeight ), true, true, window, - 1, true ); text->setTextAlignment( EGUIA_CENTER, EGUIA_CENTER ); }
void createWorld() { std::cout << "created new world" << std::endl; thisIsNotBuildYet(); }
void loadWorld() { std::cout << "load world" << std::endl; thisIsNotBuildYet(); }
void saveWorld() { std::cout << "save world" << std::endl; thisIsNotBuildYet(); }
void generateWorld() { std::cout << "generate world" << std::endl; thisIsNotBuildYet(); }
void tutorial() { std::cout << "tutorial" << std::endl; thisIsNotBuildYet(); }
void info() { std::cout << "info" << std::endl; int rectWidth = 300; int rectHeight = 300; int x1 =( screenWidth - rectWidth ) / 2; int x2 =( screenWidth + rectWidth ) / 2; int y1 =( screenHeight - rectHeight ) / 2; int y2 =( screenHeight + rectHeight ) / 2; rect < s32 > rectangle = rect < s32 >( x1, y1, x2, y2 ); IGUIWindow * window = GUI->addWindow( rectangle ); const wchar_t * t = L"Program created by tBane"; IGUIStaticText * text = GUI->addStaticText( t, rect < s32 >( 0, 20, rectWidth, rectHeight ), true, true, window, - 1, true ); text->setTextAlignment( EGUIA_CENTER, EGUIA_CENTER ); }
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 ) { switch( event.GUIEvent.EventType ) { case EGET_MENU_ITEM_SELECTED: { IGUIContextMenu * menu =( IGUIContextMenu * ) event.GUIEvent.Caller; s32 id = menu->getItemCommandId( menu->getSelectedItem() ); if( id == GUI_CREATEWORLD ) createWorld(); if( id == GUI_LOADWORLD ) loadWorld(); if( id == GUI_SAVEWORLD ) saveWorld(); if( id == GUI_GENERATEWORLD ) generateWorld(); if( id == GUI_TUTORIAL ) tutorial(); if( id == GUI_INFO ) info(); } break; case EGET_BUTTON_CLICKED: { s32 id = event.GUIEvent.Caller->getID(); if( id == BAR_BUTTON_WATER ) { paint = terrainType::water; hexMap->setTerrainType( paint ); std::cout << "setted a water to paint" << std::endl; } if( id == BAR_BUTTON_SANDS ) { paint = terrainType::sands; hexMap->setTerrainType( paint ); std::cout << "setted a sands to paint" << std::endl; } if( id == BAR_BUTTON_GRASS ) { paint = terrainType::grass; hexMap->setTerrainType( paint ); std::cout << "setted a grass to paint" << std::endl; } if( id == BAR_BUTTON_ROCKS ) { paint = terrainType::rocks; hexMap->setTerrainType( paint ); std::cout << "setted a rocks to paint" << std::endl; } if( id == BAR_BUTTON_HIGHLANDS ) { paint = terrainType::highlands; hexMap->setTerrainType( paint ); std::cout << "setted a highlands to paint" << std::endl; } if( id == BAR_BUTTON_DARKNESS ) { paint = terrainType::darkness; hexMap->setTerrainType( paint ); std::cout << "setted a darkness to paint" << std::endl; } } break; default: break; } } return false; }
bool MyEventReceiver::IsKeyDown( EKEY_CODE keyCode ) { return KeyIsDown[ keyCode ]; }
line3d < f32 > calculateRayFromScreenCoordinates( const position2d < s32 > & mousePos, ISceneManager * smgr ) { ICameraSceneNode * camera = smgr->getActiveCamera(); line3d < f32 > ray; if( camera ) { ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates( mousePos, camera ); } return ray; }
vector3df getIntersectionWithTerrain( const core::line3d < f32 > & ray, ISceneManager * smgr ) { vector3df intersection; triangle3df hitTriangle; ISceneNode * terrainNode = smgr->getSceneNodeFromType( scene::ESNT_TERRAIN ); ITriangleSelector * selector = 0; if( terrainNode ) { selector = smgr->createTriangleSelectorFromBoundingBox( terrainNode ); } if( selector ) { scene::ISceneCollisionManager * collMan = smgr->getSceneCollisionManager(); if( collMan->getCollisionPoint( ray, selector, intersection, hitTriangle, terrainNode ) ) { selector->drop(); return intersection; } selector->drop(); } return vector3df( 0, 0, 0 ); }
vector2di convert3DPositionToTileCoordinates( const core::vector3df & position, f32 tileSize ) { int x =( int ) floor( position.X / tileSize ); int z =( int ) floor( position.Z / tileSize ); return vector2di( x, z ); }
int main() { MyEventReceiver receiver; device = createDevice( EDT_SOFTWARE, dimension2d < u32 >( screenWidth, screenHeight ), bitsPerPixel, fullscreen, stencilbuffer, vsync, & receiver ); if( !device ) return 1; driver = device->getVideoDriver(); smgr = 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_CREATEWORLD ); worldMenu->addItem( L"Load World", GUI_LOADWORLD ); worldMenu->addItem( L"Save world", GUI_SAVEWORLD ); worldMenu->addItem( L"Generate World", GUI_GENERATEWORLD ); IGUIContextMenu * helpMenu = menu->getSubMenu( 1 ); helpMenu->addItem( L"Tutorial", GUI_TUTORIAL ); helpMenu->addItem( L"Info", GUI_INFO ); gui::IGUIToolBar * bar = GUI->addToolBar(); bar->setMinSize( dimension2du( screenWidth, 48 ) ); IGUIButton * water = bar->addButton( BAR_BUTTON_WATER, 0, L"water", driver->getTexture( "Media/GUI/water.png" ), 0, false, true ); IGUIButton * sands = bar->addButton( BAR_BUTTON_SANDS, 0, L"sands", driver->getTexture( "Media/GUI/sands.png" ), 0, false, true ); IGUIButton * grass = bar->addButton( BAR_BUTTON_GRASS, 0, L"grass", driver->getTexture( "Media/GUI/grass.png" ), 0, false, true ); IGUIButton * rocks = bar->addButton( BAR_BUTTON_ROCKS, 0, L"rocks", driver->getTexture( "Media/GUI/rocks.png" ), 0, false, true ); IGUIButton * highlands = bar->addButton( BAR_BUTTON_HIGHLANDS, 0, L"highlands", driver->getTexture( "Media/GUI/highlands.png" ), 0, false, true ); IGUIButton * darkness = bar->addButton( BAR_BUTTON_DARKNESS, 0, L"darkness", driver->getTexture( "Media/GUI/darkness.png" ), 0, false, true ); TWTexture = driver->getTexture( "Media/TW.png" ); cam_x = 0; cam_y = 100; cam_z = - 40; ICameraSceneNode * cam = smgr->addCameraSceneNode( 0, vector3df( cam_x, 30, cam_z ), vector3df( 0, 5, 0 ) ); cam->setTarget( vector3df( cam_x, cam_y, cam_z ) ); device->getCursorControl()->setVisible( true ); modelMesh = smgr->getMesh( modelPathfile.c_str() ); if( !modelMesh ) device->drop(); animModel1 = smgr->addAnimatedMeshSceneNode( modelMesh ); animModel1->setScale( vector3df( 10, 10, 10 ) ); animModel1->setPosition( vector3df( hexToGlobalX( 0, 0 ), 0, hexToGlobalZ( 0 ) ) ); animModel1->setRotation( vector3df( 0, 180, 0 ) ); animModel1->setMaterialFlag( EMF_LIGHTING, false ); animModel1->setMD2Animation( scene::EMAT_STAND ); animModel1->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) ); animModel2 = smgr->addAnimatedMeshSceneNode( modelMesh ); animModel2->setScale( vector3df( 10, 10, 10 ) ); animModel2->setPosition( vector3df( hexToGlobalX( 3, 4 ), 0, hexToGlobalZ( 4 ) ) ); animModel2->setRotation( vector3df( 0, 180, 0 ) ); animModel2->setMaterialFlag( EMF_LIGHTING, false ); animModel2->setMD2Animation( scene::EMAT_STAND ); animModel2->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) ); animModel3 = smgr->addAnimatedMeshSceneNode( modelMesh ); animModel3->setScale( vector3df( 10, 10, 10 ) ); animModel3->setPosition( vector3df( hexToGlobalX( 7, 5 ), 0, hexToGlobalZ( 5 ) ) ); animModel3->setRotation( vector3df( 0, 180, 0 ) ); animModel3->setMaterialFlag( EMF_LIGHTING, false ); animModel3->setMD2Animation( scene::EMAT_STAND ); animModel3->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) ); hexMap = new HexMap(); for( int z = 0; z < 60; z++ ) { for( int x = 0; x < 60; x++ ) { HexTile * tile = new HexTile( smgr->getRootSceneNode(), smgr, - 1 ); tile->setPosition( vector3df( hexToGlobalX( x, z ), 0, hexToGlobalZ( z ) ) ); hexMap->addTile( tile ); } } while( device->run() ) { if( device->isWindowActive() ) { if( receiver.IsKeyDown( irr::KEY_ESCAPE ) ) { device->drop(); return 0; } if( receiver.IsKeyDown( irr::KEY_KEY_A ) || receiver.IsKeyDown( irr::KEY_LEFT ) ) cam_x -= 2.0f; if( receiver.IsKeyDown( irr::KEY_KEY_D ) || receiver.IsKeyDown( irr::KEY_RIGHT ) ) cam_x += 2.0f; if( receiver.IsKeyDown( irr::KEY_KEY_W ) || receiver.IsKeyDown( irr::KEY_UP ) ) cam_z += 2.0f; if( receiver.IsKeyDown( irr::KEY_KEY_S ) || receiver.IsKeyDown( irr::KEY_DOWN ) ) cam_z -= 2.0f; cam->setPosition( vector3df( cam_x, cam_y, cam_z ) ); cam->setTarget( vector3df( cam_x, 30, cam_z + 50 ) ); position2d < s32 > mousePos = device->getCursorControl()->getPosition(); std::cout << mousePos.X << "," << mousePos.Y << std::endl; line3d < f32 > ray = calculateRayFromScreenCoordinates( mousePos, smgr ); vector3df intersection = getIntersectionWithTerrain( ray, smgr ); vector2di tileCoords = convert3DPositionToTileCoordinates( intersection, 100 ); std::cout << tileCoords.X << ", " << tileCoords.Y << std::endl << std::endl; driver->beginScene( true, true, SColor( clear_a, clear_r, clear_g, clear_b ) ); smgr->drawAll(); driver->draw2DImage( TWTexture, position2d < s32 >( 0, screenHeight - 128 - 20 ), rect < s32 >( 0, 0, 128, 128 ) ); boldFont->draw( L"TW World Editor v0.1", recti( 20, screenHeight - 20, 100, screenHeight ), 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-20 19:59:04 No to sprawdź w kursach Irrlichta na oficjalnej stronie - zapewne tam jest pokazane jak to osiągnąć. Wiesz przynajmniej czego szukać. |
|
« 1 » 2 |