int main(int argc, char *argv[]) { QGuiApplication a(argc, argv); a.setOrganizationDomain(QLatin1String("mapeditor.org")); a.setApplicationName(QLatin1String("TerrainGenerator")); a.setApplicationVersion(QLatin1String("1.0")); CommandLineOptions options; if (!parseCommandLineArguments(options)) { // Something went wrong, abort. return 1; } if (options.showVersion) showVersion(); if (options.showHelp) showHelp(); if (options.showVersion || options.showHelp) return 0; if (options.target.isEmpty()) { qWarning() << "Error: No target tileset provided"; showHelp(); return 1; } if (options.sources.isEmpty()) { qWarning() << "Error: No source tilesets provided"; showHelp(); return 1; } // Check terrain priorities. if (options.terrainPriority.isEmpty()) { qWarning("Error: No terrain priorities set (option -p)."); showHelp(); return 1; } MapReader reader; SharedTileset targetTileset; QList<SharedTileset> sources; if (!options.overwrite && QFile::exists(options.target)) { targetTileset = reader.readTileset(options.target); if (!targetTileset) { qCritical("Error reading target tileset:\n%s", qUtf8Printable(reader.errorString())); } // Remove empty tiles from the end of the tileset int nextTileId = targetTileset->nextTileId(); for (int id = nextTileId - 1; id >= 0; --id) { if (Tile *tile = targetTileset->findTile(id)) { if (isEmpty(tile->image().toImage())) { targetTileset->deleteTile(id); nextTileId = id; continue; } } break; } targetTileset->setNextTileId(nextTileId); // If the target tileset already exists, it is also a source tileset sources.append(targetTileset); } // Read source tilesets. for (const QString &sourceFileName : options.sources) { SharedTileset source = reader.readTileset(sourceFileName); if (!source) { qCritical("Error reading source tileset '%s':\n%s", qUtf8Printable(sourceFileName), qUtf8Printable(reader.errorString())); } sources.append(source); } // If the target tileset does not exist yet, create it if (!targetTileset) { QString name = QFileInfo(options.target).completeBaseName(); const SharedTileset &firstSource = sources.first(); int tileWidth = firstSource->tileWidth(); int tileHeight = firstSource->tileHeight(); targetTileset = Tileset::create(name, tileWidth, tileHeight); } // Set up a mapping from terrain to tile, for quick lookup QMap<TileTerrainNames, Tile*> terrainToTile; for (const SharedTileset &tileset : sources) for (Tile *tile : tileset->tiles()) if (tile->terrain() != 0xFFFFFFFF) if (!terrainToTile.contains(TileTerrainNames(tile))) // TODO: Optimize terrainToTile.insert(TileTerrainNames(tile), tile); // Set up the list of all terrains, mapped by name. QMap<QString, Terrain*> terrains; for (const SharedTileset &tileset : sources) for (Terrain *terrain : tileset->terrains()) if (!terrains.contains(terrain->name())) terrains.insert(terrain->name(), terrain); // Check if there is anything to combine. if (options.combineList.size() == 0) { qWarning() << "No terrain specified to combine (-c option)."; } else { // Dump the combine lists. qWarning() << "Terrains to combine:"; for (const QStringList &combine : options.combineList) { if (combine.isEmpty()) { qCritical("Empty combine set"); } qWarning() << combine; // Make sure every terrain from this set was defined. for (const QString &terrainName : combine) if (!terrains.contains(terrainName)) qCritical("Terrain %s is in combine list, however it wasn't defined by any tileset.", qUtf8Printable(terrainName)); } } // Setup terrain priorities. TerrainLessThan lessThan; int priority = 0; for (const QString &terrainName : options.terrainPriority) { lessThan.terrainPriority.insert(terrainName, priority); ++priority; } qDebug() << "Terrains found:" << terrains.keys(); // Check if all terrains from priority list were found and loaded. for (const QString &terrainName : lessThan.terrainPriority.keys()) if (!terrains.contains(terrainName)) qWarning() << "Terrain" << terrainName << "from priority list not found."; // Add terrain names not specified from command line. for (const QString &terrainName : terrains.keys()) { if (!lessThan.terrainPriority.contains(terrainName)) { qWarning() << "No priority set for" << terrainName; lessThan.terrainPriority.insert(terrainName, priority); ++priority; } } // Add terrains that are not defined in the target tileset yet // TODO: This step should be more configurable for (Terrain *terrain : terrains) { if (!hasTerrain(*targetTileset, terrain->name())) { Tile *terrainTile = terrain->imageTile(); QPixmap terrainImage = terrainTile->image(); Tile *newTerrainTile = targetTileset->addTile(terrainImage); newTerrainTile->setProperties(terrainTile->properties()); Terrain *newTerrain = targetTileset->addTerrain(terrain->name(), newTerrainTile->id()); // WARNING: This assumes the terrain tile has this terrain on all // its corners. newTerrainTile->setTerrain(makeTerrain(newTerrain->id())); terrainToTile.insert(TileTerrainNames(newTerrainTile), newTerrainTile); } } // Prepare a list of terrain combinations. QVector<TileTerrainNames> process; for (const QStringList &combine : options.combineList) { QList<Terrain*> terrainList; // Get the terrains to combine for (const QString &terrainName : combine) terrainList.append(terrains[terrainName]); // Construct a vector with all terrain combinations to process for (Terrain *topLeft : terrainList) { for (Terrain *topRight : terrainList) { for (Terrain *bottomLeft : terrainList) { for (Terrain *bottomRight : terrainList) { process.append(TileTerrainNames(topLeft->name(), topRight->name(), bottomLeft->name(), bottomRight->name())); } } } } } // Go through each combination of terrains and add the tile to the target // tileset if it's not in there yet. for (const TileTerrainNames &terrainNames : process) { Tile *tile = terrainToTile.value(terrainNames); if (tile && tile->tileset() == targetTileset) continue; QPixmap image; Properties properties; if (!tile) { qWarning() << "Generating" << terrainNames; // Start a new image QImage tileImage = QImage(targetTileset->tileWidth(), targetTileset->tileHeight(), QImage::Format_ARGB32); tileImage.fill(Qt::transparent); QPainter painter(&tileImage); QStringList terrainList = terrainNames.terrainList(); qSort(terrainList.begin(), terrainList.end(), lessThan); // Draw the lowest terrain to avoid pixel gaps QString baseTerrain = terrainList.first(); QPixmap baseImage = terrains[baseTerrain]->imageTile()->image(); painter.drawPixmap(0, 0, baseImage); for (const QString &terrainName : terrainList) { TileTerrainNames filtered = terrainNames.filter(terrainName); Tile *tile = terrainToTile.value(filtered); if (!tile) { qWarning() << "Missing" << filtered; continue; } painter.drawPixmap(0, 0, tile->image()); properties.merge(tile->properties()); } image = QPixmap::fromImage(tileImage); } else { qWarning() << "Copying" << terrainNames << "from" << QFileInfo(tile->tileset()->fileName()).fileName(); image = tile->image(); properties = tile->properties(); } Tile *newTile = targetTileset->addTile(image); newTile->setTerrain(terrainNames.toTerrain(*targetTileset)); newTile->setProperties(properties); terrainToTile.insert(terrainNames, newTile); } if (targetTileset->tileCount() == 0) qCritical("Target tileset is empty"); if (options.embedImage) { // Make sure there is no source name, this way the image will be saved in the TSX file. targetTileset->setImageSource(QString()); } else { // Save the target tileset image as separate file. int columns = qMin(options.columns, targetTileset->tileCount()); int rows = targetTileset->tileCount() / options.columns; if (targetTileset->tileCount() % options.columns > 0) ++rows; qWarning() << "Writing external tileset image."; // Save the target tileset image QImage image(targetTileset->tileWidth() * columns, targetTileset->tileHeight() * rows, QImage::Format_ARGB32); image.fill(Qt::transparent); QPainter painter(&image); for (Tile *tile : targetTileset->tiles()) { int x = (tile->id() % options.columns) * targetTileset->tileWidth(); int y = (tile->id() / options.columns) * targetTileset->tileHeight(); painter.drawPixmap(x, y, tile->image()); } QString imageFileName = QFileInfo(options.target).completeBaseName(); imageFileName += ".png"; image.save(imageFileName); targetTileset->setImageSource(imageFileName); targetTileset->setColumnCount(options.columns); } // Save the target tileset MapWriter writer; targetTileset->setFileName(QString()); writer.writeTileset(*targetTileset, options.target); return 0; }
int TmxRasterizer::render(const QString &mapFileName, const QString &imageFileName) { MapReader reader; std::unique_ptr<Map> map { reader.readMap(mapFileName) }; if (!map) { qWarning("Error while reading \"%s\":\n%s", qUtf8Printable(mapFileName), qUtf8Printable(reader.errorString())); return 1; } std::unique_ptr<MapRenderer> renderer; switch (map->orientation()) { case Map::Isometric: renderer.reset(new IsometricRenderer(map.get())); break; case Map::Staggered: renderer.reset(new StaggeredRenderer(map.get())); break; case Map::Hexagonal: renderer.reset(new HexagonalRenderer(map.get())); break; case Map::Orthogonal: default: renderer.reset(new OrthogonalRenderer(map.get())); break; } QRect mapBoundingRect = renderer->mapBoundingRect(); QSize mapSize = mapBoundingRect.size(); QPoint mapOffset = mapBoundingRect.topLeft(); qreal xScale, yScale; if (mSize > 0) { xScale = (qreal) mSize / mapSize.width(); yScale = (qreal) mSize / mapSize.height(); xScale = yScale = qMin(1.0, qMin(xScale, yScale)); } else if (mTileSize > 0) { xScale = (qreal) mTileSize / map->tileWidth(); yScale = (qreal) mTileSize / map->tileHeight(); } else { xScale = yScale = mScale; } QMargins margins = map->computeLayerOffsetMargins(); mapSize.setWidth(mapSize.width() + margins.left() + margins.right()); mapSize.setHeight(mapSize.height() + margins.top() + margins.bottom()); mapSize.rwidth() *= xScale; mapSize.rheight() *= yScale; QImage image(mapSize, QImage::Format_ARGB32); image.fill(Qt::transparent); QPainter painter(&image); painter.setRenderHint(QPainter::Antialiasing, mUseAntiAliasing); painter.setRenderHint(QPainter::SmoothPixmapTransform, mSmoothImages); painter.setTransform(QTransform::fromScale(xScale, yScale)); painter.translate(margins.left(), margins.top()); painter.translate(-mapOffset); // Perform a similar rendering than found in exportasimagedialog.cpp LayerIterator iterator(map.get()); while (const Layer *layer = iterator.next()) { if (!shouldDrawLayer(layer)) continue; const auto offset = layer->totalOffset(); painter.setOpacity(layer->effectiveOpacity()); painter.translate(offset); const TileLayer *tileLayer = dynamic_cast<const TileLayer*>(layer); const ImageLayer *imageLayer = dynamic_cast<const ImageLayer*>(layer); if (tileLayer) { renderer->drawTileLayer(&painter, tileLayer); } else if (imageLayer) { renderer->drawImageLayer(&painter, imageLayer); } painter.translate(-offset); } map.reset(); // Save image QImageWriter imageWriter(imageFileName); if (!imageWriter.canWrite()) imageWriter.setFormat("png"); if (!imageWriter.write(image)) { qWarning("Error while writing \"%s\": %s", qUtf8Printable(imageFileName), qUtf8Printable(imageWriter.errorString())); return 1; } return 0; }
void GameCore::initializeItems() { if(mapMode) { MapReader* mapReader = mazeBuilder->getMapReader(); int itemId = 0; if (mapReader != NULL) { float scaleFactor = mapReader->getScaleFactor(); MapEntity2_t* ent; std::string meshName="LaserRifle.mesh"; std::string materialName="LaserRifleItem"; Ogre::Vector3 meshScale(2,2,2); while ((ent = mapReader->getItem()) != NULL) { if (ent->type == ItemType::LASER_MACHINE_GUN) { meshName = "LaserRifle.mesh"; materialName = "LaserRifleItem"; meshScale=Ogre::Vector3(2,2,2); } else if(ent->type==ItemType::LASER_PISTOL) { meshName="cube.mesh"; materialName="LaserPistolItem"; meshScale=Ogre::Vector3(.05,.05,.05); } else if(ent->type==ItemType::EAGLE_EYE) { meshName="EagleEye.mesh"; materialName="NULL"; meshScale=Ogre::Vector3(4,4,4); } else if(ent->type==ItemType::EXTRA_HEALTH) { meshName="Medkit.mesh"; materialName="NULL"; meshScale=Ogre::Vector3(12,12,12); } else if(ent->type==ItemType::IMMORTALITY) { meshName="Immortality.mesh"; materialName="NULL"; meshScale=Ogre::Vector3(10,10,10); } else if(ent->type==ItemType::ONE_SHOT) { meshName="OneShot.mesh"; materialName="NULL"; meshScale=Ogre::Vector3(15,15,15); } else { Logger::getSingleton()->addLine("GameCore: unidentified item read", true); continue; } Ogre::Vector3 itemPos(-ent->entityPosition.startX*scaleFactor,0,ent->entityPosition.startZ*scaleFactor); Ogre::Vector3 startPos=itemPos; Ogre::Vector3 endPos=itemPos; startPos.y=mazeBuilder->getWallHeight()-10; endPos.y=-100; btCollisionObject object; Ogre::Vector3 hitPos; if(PhysicsHandler::performRaycastTest(startPos,endPos,dynamics,&object,&hitPos)) { CollisionObjectInfo* info=(CollisionObjectInfo*)object.getUserPointer(); std::cout<<"type: "<<info->getObjectType()<<std::endl; if(info->getObjectType()==CollisionObjectTypes::GROUND || info->getObjectType()==CollisionObjectTypes::STATIC_OBJECT) itemPos.y=hitPos.y; else if(info->getObjectType()==CollisionObjectTypes::WALL) { Logger::getSingleton()->addLine("GameCoreInitializer: item-wall collision detected; item removed",true); continue; } } itemPos.y+=10; createItem(itemId++, (ItemType::ItemTypes)ent->type, meshName, materialName, meshScale, itemPos); } } } }
// ----------------------------------------------------------------- // Name : autoStartGame // ----------------------------------------------------------------- void DebugManager::autoStartGame() { // Build client data int nbClients = 1; ClientData * clients = new ClientData[nbClients]; int iClient = 0; clients[iClient].bLocal = true; // Re-init map data MapReader * pMapReader = new MapReader(m_pLocalClient); pMapReader->init("standard.lua"); ObjectList * pMapParameters = new ObjectList(true); pMapReader->getMapParameters(pMapParameters, LABEL_MAX_CHARS); int * pCustomParams = NULL; if (pMapParameters->size > 0) pCustomParams = new int[pMapParameters->size]; // Map custom parameters int i = 0; MapReader::MapParameters * pParam = (MapReader::MapParameters*) pMapParameters->getFirst(0); while (pParam != NULL) { pCustomParams[i++] = pParam->defaultValueIndex; pParam = (MapReader::MapParameters*) pMapParameters->getNext(0); } // Init map generator (we will not delete it here, as the pointer now belong to Server object) pMapReader->setMapParameters(pCustomParams, pMapParameters->size, 2); delete[] pCustomParams; MapReader::deleteMapParameters(pMapParameters); delete pMapParameters; // Init server Server * pServer = m_pLocalClient->initServer("", 1, clients, pMapReader, -1, -1); delete[] clients; if (pServer == NULL) { notifyErrorMessage("Error: server could not be initialized."); return; } // Build players data ObjectList * pServerPlayers = pServer->getSolver()->getPlayersList(); // Create neutral player char sName[NAME_MAX_CHARS]; i18n->getText("NEUTRA", sName, NAME_MAX_CHARS); Player * pPlayer = new Player(0, 0, pServer->getSolver()->getGlobalSpellsPtr()); wsafecpy(pPlayer->m_sProfileName, NAME_MAX_CHARS, sName); pPlayer->m_Color = rgb(0.5, 0.5, 0.5); wsafecpy(pPlayer->m_sBanner, 64, "blason1"); pServer->getSolver()->setNeutralPlayer(pPlayer); // Human players int playerId = 1; for (int fdfdf = 0; fdfdf < 2; fdfdf++) { // Create player object pPlayer = new Player(playerId, 0, pServer->getSolver()->getGlobalSpellsPtr()); snprintf(pPlayer->m_sProfileName, NAME_MAX_CHARS, "test%d", playerId); Profile * pProfile = m_pLocalClient->getDataFactory()->findProfile(pPlayer->m_sProfileName); AvatarData * pAvatar = (AvatarData*) pProfile->getAvatarsList()->getFirst(0); pPlayer->m_Color = rgb(1, 1, 1); pAvatar->getBanner(pPlayer->m_sBanner, 64); pServerPlayers->addLast(pPlayer); // Set Avatar CoordsMap pos = pMapReader->getPlayerPosition(playerId-1); pServer->getSolver()->setInitialAvatar(pAvatar->clone(m_pLocalClient), pPlayer, pos); // Add spells that are equipped Profile::SpellData * pSpellDesc = (Profile::SpellData*) pProfile->getSpellsList()->getFirst(0); while (pSpellDesc != NULL) { AvatarData * pOwner = pSpellDesc->m_pOwner; if (pOwner != NULL && strcmp(pAvatar->m_sEdition, pOwner->m_sEdition) == 0 && strcmp(pAvatar->m_sObjectId, pOwner->m_sObjectId) == 0) pServer->getSolver()->addInitialPlayerSpell(pPlayer, pSpellDesc->m_sEdition, pSpellDesc->m_sName); pSpellDesc = (Profile::SpellData*) pProfile->getSpellsList()->getNext(0); } // Add equipped artifacts Artifact * pArtifact = (Artifact*) pProfile->getArtifactsList()->getFirst(0); while (pArtifact != NULL) { AvatarData * pOwner = pArtifact->m_pOwner; if (pOwner != NULL && strcmp(pAvatar->m_sEdition, pOwner->m_sEdition) == 0 && strcmp(pAvatar->m_sObjectId, pOwner->m_sObjectId) == 0) { Unit * pAvatarInGame = pPlayer->getAvatar(); assert(pAvatarInGame != NULL); ArtifactEffect * pEffect = (ArtifactEffect*) pArtifact->getArtifactEffects()->getFirst(0); while (pEffect != NULL) { switch (pEffect->getType()) { case ARTIFACT_EFFECT_CHARAC: { bool bFound = true; long val = pAvatarInGame->getValue(((ArtifactEffect_Charac*)pEffect)->m_sKey, false, &bFound); if (bFound) pAvatarInGame->setBaseValue(((ArtifactEffect_Charac*)pEffect)->m_sKey, max(0, val + ((ArtifactEffect_Charac*)pEffect)->m_iModifier)); else { char sError[1024]; snprintf(sError, 1024, "Warning: artifact %s tries to modify characteristic that doesn't exist (%s)", pArtifact->m_sObjectId, ((ArtifactEffect_Charac*)pEffect)->m_sKey); m_pLocalClient->getDebug()->notifyErrorMessage(sError); } break; } case ARTIFACT_EFFECT_SPELL: { Spell * pSpell = m_pLocalClient->getDataFactory()->findSpell(((ArtifactEffect_Spell*)pEffect)->m_sSpellEdition, ((ArtifactEffect_Spell*)pEffect)->m_sSpellName); if (pSpell != NULL) pServer->getSolver()->addInitialPlayerSpell(pPlayer, ((ArtifactEffect_Spell*)pEffect)->m_sSpellEdition, ((ArtifactEffect_Spell*)pEffect)->m_sSpellName); else { char sError[1024]; snprintf(sError, 1024, "Warning: artifact %s tries to add spell that doesn't exist (%s)", pArtifact->m_sObjectId, ((ArtifactEffect_Spell*)pEffect)->m_sSpellName); m_pLocalClient->getDebug()->notifyErrorMessage(sError); } break; } case ARTIFACT_EFFECT_SKILL: { Skill * pSkill = new Skill(((ArtifactEffect_Skill*)pEffect)->m_sSkillEdition, ((ArtifactEffect_Skill*)pEffect)->m_sSkillName, ((ArtifactEffect_Skill*)pEffect)->m_sSkillParameters, pServer->getDebug()); if (pSkill != NULL && pSkill->isLoaded()) pAvatarInGame->addSkill(pSkill); else { char sError[1024]; snprintf(sError, 1024, "Warning: artifact %s tries to add skill that doesn't exist or that can't be loaded (%s)", pArtifact->m_sObjectId, ((ArtifactEffect_Skill*)pEffect)->m_sSkillName); m_pLocalClient->getDebug()->notifyErrorMessage(sError); } break; } } pEffect = (ArtifactEffect*) pArtifact->getArtifactEffects()->getNext(0); } } pArtifact = (Artifact*) pProfile->getArtifactsList()->getNext(0); } playerId++; } delete pMapReader; pServer->onInitFinished(); }
int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); int timer = 0; MapReader mr = MapReader(); //Map data string* map = nullptr; //map = mr.ReadMap("Maps/Randomized128x128-29-0.map"); map = mr.ReadMap("Maps/maze512-1-1.map"); //map = mr.ReadMap("Maps/adaptive-depth-1.map"); //map = mr.ReadMap("Maps/32room_008.map"); //map = GenerateMap(10, 10, 1.0f, mr); int width = mr.GetWidth(); int height = mr.GetHeight(); int nrOfWalls = mr.GetNrOfWalls(map); Vec2D startPos = {1, 1}; Vec2D goalPos = {width-1, height-1}; int clusterSize = 16; Vec2D* wallPos = new Vec2D[nrOfWalls]; sf::RectangleShape* walls = new sf::RectangleShape[nrOfWalls]; AStarNode** grid = nullptr; if (map != nullptr) { if (width > 0 && height > 0) { grid = new AStarNode*[width]; //Initiate the grid** with walkable or non-walkable tiles int wallCounter = 0; for (int i = 0; i < width; i++) { grid[i] = new AStarNode[height]; for (int j = 0; j < height; j++) { grid[i][j] = AStarNode(i, j); if (map[j*width + i] != "@") { grid[i][j]._traversable = true; } else { grid[i][j]._traversable = false; walls[wallCounter] = sf::RectangleShape(sf::Vector2f((float)tileWidth, (float)tileHeight)); walls[wallCounter].setFillColor(sf::Color::White); walls[wallCounter].setPosition(sf::Vector2f(10.0f + (float)(tileWidth * i), 10.0f + (float)(tileHeight * j))); wallCounter++; } } } } } sf::View view; view.setCenter(0.5f * width * tileWidth, 0.5f * height * tileHeight); view.setSize(1.6f * width * tileWidth, 1.2f * height * tileHeight); sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight), "AI test"); window.setFramerateLimit(60); window.setView(view); ImGui::SFML::SetRenderTarget(window); ImGui::SFML::InitImGuiRendering(); ImGui::SFML::SetWindow(window); ImGui::SFML::InitImGuiEvents(); sf::RectangleShape* openedTiles = nullptr; sf::RectangleShape* expandedTiles = nullptr; sf::Vertex* pathTiles = nullptr; //Mainly for the highlevel graph of HPA* sf::Vertex* abstractGraph = nullptr; sf::Vertex* openedGraph = nullptr; sf::Vertex* expandedGraph = nullptr; Metrics metrics; sf::CircleShape startNode = sf::CircleShape(0.4f*tileHeight); startNode.setPosition(sf::Vector2f(10.0f + startPos._x * (float)tileWidth, 10.0f + startPos._y * (float)tileHeight)); startNode.setFillColor(sf::Color::Red); sf::CircleShape goalNode = sf::CircleShape(0.4f*tileHeight);; goalNode.setPosition(sf::Vector2f(10.0f + goalPos._x * (float)tileWidth, 10.0f + goalPos._y * (float)tileHeight)); goalNode.setFillColor(sf::Color::Yellow); //Other variables bool calculatePaths = false; int choosePathfinding = 0; int chooseHeuristic = 0; //Movement variable int delta = width * 0.05f; float blockSize = 32.0f; //Randomize map variables bool randomizeMap = false; char widthBuffer[4] = "512"; char heightBuffer[4] = "512"; char densityBuffer[3] = "30"; //Set start/goal position variables int startOrGoal = 0; //0 == start pos, 1 == goal pos char xBuffer[4] = "0"; char yBuffer[4] = "0"; //What should be drawn? bool showWalls = false; bool showExpandedNodes = false; bool showOpenedNodes = false; while (window.isOpen()) { ImGui::SFML::UpdateImGui(); ImGui::SFML::UpdateImGuiRendering(); sf::Event event; while (window.pollEvent(event)) { ImGui::SFML::ProcessEvent(event); if (event.type == sf::Event::Closed) { window.close(); } } ImGuiIO &io = ImGui::GetIO(); //ImGui::ShowTestWindow(); window.clear(); /**************************************/ /* Start of GUI code */ /**************************************/ if (ImGui::CollapsingHeader("Choose pathfinding")) { ImGui::RadioButton("A*", &choosePathfinding, 0); ImGui::SameLine(); ImGui::RadioButton("Theta*", &choosePathfinding, 1); ImGui::SameLine(); ImGui::RadioButton("HPA*", &choosePathfinding, 2); ImGui::SameLine(); ImGui::RadioButton("IDA*", &choosePathfinding, 3); ImGui::SameLine(); ImGui::RadioButton("Dijkstra", &choosePathfinding, 4); ImGui::RadioButton("Manhattan", &chooseHeuristic, 0); ImGui::SameLine(); ImGui::RadioButton("Chebyshev", &chooseHeuristic, 1); ImGui::SameLine(); ImGui::RadioButton("Octile", &chooseHeuristic, 2); ImGui::SameLine(); ImGui::RadioButton("Euclidean", &chooseHeuristic, 3); } if (ImGui::CollapsingHeader("Randomize a map")) { //Set width, height and obstacle density ImGui::InputText("Width", widthBuffer, IM_ARRAYSIZE(widthBuffer)); ImGui::InputText("Height", heightBuffer, IM_ARRAYSIZE(heightBuffer)); ImGui::InputText("Density (%)", densityBuffer, IM_ARRAYSIZE(densityBuffer)); if (ImGui::SmallButton("Generate map")) { mr.GenerateRandomMap(stoi(string(widthBuffer)), stoi(string(heightBuffer)), 0.01f*stof(string(densityBuffer))); } } if (ImGui::CollapsingHeader("Set start/goal")) { ImGui::RadioButton("Set start position", &startOrGoal, 0); ImGui::SameLine(); ImGui::RadioButton("Set goal position", &startOrGoal, 1); //Set xPos and yPos ImGui::InputText("X position", xBuffer, IM_ARRAYSIZE(xBuffer)); ImGui::InputText("Y position", yBuffer, IM_ARRAYSIZE(yBuffer)); if (ImGui::SmallButton("Set position")) { Vec2D pos = {stoi(string(xBuffer)), stoi(string(yBuffer))}; if (startOrGoal == 0) //Start pos { startPos = pos; startNode.setPosition(sf::Vector2f(10.0f + startPos._x * (float)tileWidth, 10.0f + startPos._y * (float)tileHeight)); } else if (startOrGoal == 1) //Goal pos { goalPos = pos; goalNode.setPosition(sf::Vector2f(10.0f + goalPos._x * (float)tileWidth, 10.0f + goalPos._y * (float)tileHeight)); } } } if (ImGui::CollapsingHeader("Choose what will be drawn")) { ImGui::Checkbox("Walls", &showWalls); ImGui::Checkbox("Opened nodes", &showOpenedNodes); ImGui::Checkbox("Expanded nodes", &showExpandedNodes); } if (ImGui::SmallButton("Calculate paths")) { calculatePaths = !calculatePaths; } /**************************************/ /* End of GUI code */ /**************************************/ //Moving of the camera if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) //Move camera west { view.setCenter(view.getCenter().x, view.getCenter().y - delta); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) //Move camera east { view.setCenter(view.getCenter().x - delta, view.getCenter().y); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) //Move camera south { view.setCenter(view.getCenter().x, view.getCenter().y + delta); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) //Move camera north { view.setCenter(view.getCenter().x + delta, view.getCenter().y); } //Zooming with the camera if (sf::Keyboard::isKeyPressed(sf::Keyboard::PageUp) && blockSize <= 32.0f) //Zoom out { view.setSize(sf::Vector2f(width * tileWidth * blockSize++ * 0.05f, height * tileHeight * blockSize++ * 0.0375f)); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::PageDown) && blockSize >= 1.0f) //Zoom in { view.setSize(sf::Vector2f(width * tileWidth * blockSize-- * 0.05f, height * tileHeight * blockSize-- * 0.0375f)); } window.setView(view); //Calculate pathfinding if (calculatePaths) { metrics.clean(); switch (choosePathfinding) { case 0: //A* CalculateAStar(metrics, (Pathfinding::Heuristic)chooseHeuristic, width, height, startPos, goalPos, grid); break; case 1: //Theta* CalculateThetaStar(metrics, (Pathfinding::Heuristic)chooseHeuristic, width, height, startPos, goalPos, grid); break; case 2: //HPA* CalculateHPAStar(metrics, (Pathfinding::Heuristic)chooseHeuristic, width, height, startPos, goalPos, grid, clusterSize); break; case 3: //IDA* CalculateIDAStar(metrics, (Pathfinding::Heuristic)chooseHeuristic, width, height, startPos, goalPos, grid); break; case 4: CalculateDijkstra(metrics, (Pathfinding::Heuristic)chooseHeuristic, width, height, startPos, goalPos, grid); default: break; } if (showOpenedNodes) { if (openedTiles != nullptr) { delete[] openedTiles; } openedTiles = new sf::RectangleShape[metrics.getNrOfOpenedNodes()]; for (int i = 0; i < metrics.getNrOfOpenedNodes(); i++) { openedTiles[i] = sf::RectangleShape(sf::Vector2f((float)tileWidth, (float)tileHeight)); openedTiles[i].setFillColor(sf::Color(0, 200, 200, 120)); openedTiles[i].setPosition(sf::Vector2f(10.0f + (float)tileWidth * metrics.getOpenedNodes()[i]._x, 10.0f + (float)tileHeight * metrics.getOpenedNodes()[i]._y)); window.draw(openedTiles[i]); } } if (showExpandedNodes) { if (expandedTiles != nullptr) { delete[] expandedTiles; } expandedTiles = new sf::RectangleShape[metrics.getNrOfExpandedNodes()]; for (int i = 0; i < metrics.getNrOfExpandedNodes(); i++) { expandedTiles[i] = sf::RectangleShape(sf::Vector2f((float)tileWidth, (float)tileHeight)); expandedTiles[i].setFillColor(sf::Color(200, 0, 0, 120)); expandedTiles[i].setPosition(sf::Vector2f(10.0f + (float)tileWidth * metrics.getExpandedNodes()[i]._x, 10.0f + (float)tileHeight * metrics.getExpandedNodes()[i]._y)); window.draw(expandedTiles[i]); } } if (pathTiles != nullptr) { delete[] pathTiles; } pathTiles = new sf::Vertex[metrics.getNrOfPathNodes() + 1]; for (int i = 0; i < metrics.getNrOfPathNodes(); i++) { pathTiles[i] = sf::Vertex(sf::Vector2f(10.0f + (float)tileWidth * (metrics.getPathNodes()[i]._x + 0.5f), 10.0f + (float)tileHeight * (metrics.getPathNodes()[i]._y + 0.5f))); pathTiles[i].color = sf::Color(200, 0, 200, 255); } pathTiles[metrics.getNrOfPathNodes()] = sf::Vector2f(10.0f + (float)tileWidth * (startPos._x + 0.5f), 10.0f + (float)tileHeight * (startPos._y + 0.5f)); SaveDataToFile(metrics, choosePathfinding, chooseHeuristic); calculatePaths = false; } //Draw the start and goal node(s) window.draw(startNode); window.draw(goalNode); if (choosePathfinding == 2) //Special case for HPA* { window.draw(abstractGraph, metrics.getNrOfGraphNodes(), sf::Lines); if (showOpenedNodes) { window.draw(openedGraph, metrics.getNrOfOpenedNodes(), sf::Lines); } if (showExpandedNodes) { window.draw(expandedGraph, metrics.getNrOfExpandedNodes(), sf::Lines); } } else { if (showOpenedNodes && openedTiles != nullptr) { for (int i = 0; i < metrics.getNrOfOpenedNodes(); i++) { window.draw(openedTiles[i]); } } if (showExpandedNodes) { for (int i = 0; i < metrics.getNrOfExpandedNodes(); i++) { window.draw(expandedTiles[i]); } } } window.draw(pathTiles, metrics.getNrOfPathNodes() + 1, sf::LinesStrip); //Draw all the walls if (showWalls) { for (int i = 0; i < nrOfWalls; i++) { window.draw(walls[i]); } } ImGui::Render(); window.display(); } delete[] expandedTiles; delete[] openedTiles; delete[] pathTiles; delete[] walls; delete[] map; delete[] wallPos; for (__int16 i = 0; i < width; i++) { delete[] grid[i]; } delete[] grid; ImGui::SFML::Shutdown(); return 0; }