Piszę "Edytor Mapy". Potrzebuję uzyskać informacje, które pole (HexTile) zostało naduszone, aby móc za pomocą kliknięć myszy edytować mapę.
#include <irrlicht.h>
using namespace irr; // I don't want to use it irr::
using namespace core; // also ( irr::core:: )
using namespace scene; // also ( irr::scene::)
using namespace video; // also ...
using namespace io; // ...
using namespace gui; // ...
#include<iostream>
#include<set>
#include<vector>
// device
int screenWidth = 1080;
int screenHeight = 720;
int bitsPerPixel = 32;
bool fullscreen = false;
bool stencilbuffer = false; // Specifies if we want to use the stencil buffer (for drawing shadows)
bool vsync = false; // Specifies if we want to have vsync enabled, this is only useful in fullscreen mode.
int eventReceiver = 0; // An object to receive events.We do not want to use this parameter here, and set it to 0.
int cam_x, cam_y, cam_z;
// clearing screen colors
int clear_r = 48;
int clear_g = 48;
int clear_b = 48;
int clear_a = 256;
// Basic things
IrrlichtDevice* device;
IVideoDriver* driver;
ISceneManager* sceneManager;
IGUIEnvironment* GUI;
// Fonts
IGUIFont* basicFont;
IGUIFont* boldFont;
// Textures
ITexture* TWTexture;
// Model pathfiles
std::string modelPathfile = "Media/TT_RTS_Demo_Character.obj";
std::string modelTexturePathfile = "Media/TT_RTS_Units_blue.png";
// Meshes
IAnimatedMesh* modelMesh; // mesh
// Animators
IAnimatedMeshSceneNode* animModel1; // model1
IAnimatedMeshSceneNode* animModel2; // model2
IAnimatedMeshSceneNode* animModel3; // model3
// Textures
ITexture* modelTexture;
// Buttons ID's
enum
{
// World
GUI_CREATEWORLD, GUI_LOADWORLD, GUI_SAVEWORLD, GUI_GENERATEWORLD,
// Help
GUI_TUTORIAL, GUI_INFO,
// bar
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* 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);
// vertices of hexagons
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 = 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::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)
{
// Remember whether each key is down or up
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: // main menu events
{
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];
}
int main()
{
MyEventReceiver receiver;
// CREATE DEVICE ( OpenGL )
device = createDevice(EDT_SOFTWARE, dimension2d<u32>(screenWidth, screenHeight), bitsPerPixel, fullscreen, stencilbuffer, vsync, &receiver);
if (!device) // if no Device then error
return 1;
// GET THE BASIC THINGS
driver = device->getVideoDriver(); // get the Video Driver
sceneManager = device->getSceneManager(); // get the Scene
GUI = device->getGUIEnvironment(); // get the GUI Manager
// LOAD THE FONTS
basicFont = device->getGUIEnvironment()->getBuiltInFont(); // get the Default Font
boldFont = device->getGUIEnvironment()->getFont("media/fonthaettenschweiler.bmp"); // get the Bold Font
// STYLES FOR GUI
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)); // coloring the Background
GUIskin->setColor(EGDC_BUTTON_TEXT, SColor(255, 224, 224, 224)); // coloring the Text
GUIskin->setColor(EGDC_HIGH_LIGHT_TEXT, SColor(255, 128, 48, 48)); // coloring the Highlighed Text
}
// CREATE MAIN MENU
IGUIContextMenu* menu = GUI->addMenu();
menu->addItem(L"World", -1, true, true);
menu->addItem(L"Help", -1, true, true);
// Create World Menu
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);
// Create Help Menu
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);
// LOAD THE "TW Editor Logo"
TWTexture = driver->getTexture("Media/TW.png");
// ADD CAMERA
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));
// CURSOR IS HIDDEN
device->getCursorControl()->setVisible(true);
// LOAD THE MODEL
modelMesh = sceneManager->getMesh(modelPathfile.c_str());
if (!modelMesh)
device->drop();
animModel1 = sceneManager->addAnimatedMeshSceneNode(modelMesh); // Add Model1
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); // Add Model2
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); // Add Model3
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()));
// Create 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);
}
}
// MAIN "TW Editor" LOOP
while (device->run())
{
if (device->isWindowActive())
{
// EVENTS
if (receiver.IsKeyDown(irr::KEY_ESCAPE)) // if press ESCAPE then exit
{
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;
// UPDATE
cam->setPosition(vector3df(cam_x, cam_y, cam_z));
cam->setTarget(vector3df(cam_x, 30, cam_z+50));
// RENDER
driver->beginScene(true, true, SColor(clear_a, clear_r, clear_g, clear_b)); // clear screen
sceneManager->drawAll(); // render scene
driver->draw2DImage(TWTexture, position2d<s32>(0, screenHeight - 128 - 20), rect<s32>(0, 0, 128, 128)); // render TW Logo
boldFont->draw(L"TW World Editor v0.1", recti(20, screenHeight - 20, 100, screenHeight), SColor(256, 128, 48, 48), true, true); // render text on bottom
GUI->drawAll(); // render GUI
position2d<s32> m = device->getCursorControl()->getPosition(); // render cursor
driver->endScene(); // render submit
// FPS
int currentFPS = driver->getFPS();
core::stringw str = L"FPS: ";
str += currentFPS;
device->setWindowCaption(str.c_str());
}
else
device->yield(); // if window is inactive not use CPU
}
// In the end, delete the Irrlicht device.
device->drop();
return 0;
}