/** * Returns a new stamp where all variations have been rotated in the given * \a direction. */ TileStamp TileStamp::rotated(RotateDirection direction) const { TileStamp rotated(*this); rotated.d.detach(); for (const TileStampVariation &variation : rotated.variations()) { const QRect mapRect(QPoint(), variation.map->size()); QSize rotatedSize; for (auto layer : variation.map->tileLayers()) { TileLayer *tileLayer = static_cast<TileLayer*>(layer); // Synchronize tile layer size to map size (assumes map contains all layers) if (tileLayer->rect() != mapRect) { tileLayer->resize(mapRect.size(), tileLayer->position()); tileLayer->setPosition(0, 0); } if (variation.map->orientation() == Map::Hexagonal) tileLayer->rotateHexagonal(direction, variation.map); else tileLayer->rotate(direction); rotatedSize = tileLayer->size(); } variation.map->setWidth(rotatedSize.width()); variation.map->setHeight(rotatedSize.height()); } return rotated; }
void Editor::Render() { window->clear(); for (TileLayer::size_type y = 0; y < tileLayerBottom.size(); y++) { for (TileRow::size_type x = 0; x < tileLayerBottom[y].size(); x++) { tileLayerBottom[y][x]->Render(); } } selector->Render(); sidebar->Render(); saveUI->Render(); sidebarTiles->Render(); sidebarSelection->Render(); window->display(); }
void BucketFillTool::tilePositionChanged(const QPoint &tilePos) { AbstractTileFillTool::tilePositionChanged(tilePos); if (isCapturing()) return; // Skip filling if the stamp is empty and not in wangFill mode if (mStamp.isEmpty() && mFillMethod != WangFill) return; // Make sure that a tile layer is selected TileLayer *tileLayer = currentTileLayer(); if (!tileLayer) return; bool shiftPressed = QApplication::keyboardModifiers() & Qt::ShiftModifier; bool fillRegionChanged = false; TilePainter regionComputer(mapDocument(), tileLayer); // This clears the connections so we don't get callbacks clearConnections(mapDocument()); // Optimization: we don't need to recalculate the fill area // if the new mouse position is still over the filled region // and the shift modifier hasn't changed. if (!mFillRegion.contains(tilePos) || shiftPressed != mLastShiftStatus) { // Clear overlay to make way for a new one AbstractTileFillTool::clearOverlay(); // Cache information about how the fill region was created mLastShiftStatus = shiftPressed; // Get the new fill region if (!shiftPressed) { // If not holding shift, a region is computed from the current pos bool computeRegion = true; // If the stamp is a single tile, ignore that tile when making the region if (mFillMethod != WangFill && mStamp.variations().size() == 1) { const TileStampVariation &variation = mStamp.variations().first(); TileLayer *stampLayer = variation.tileLayer(); if (stampLayer->size() == QSize(1, 1) && stampLayer->cellAt(0, 0) == regionComputer.cellAt(tilePos)) computeRegion = false; } if (computeRegion) mFillRegion = regionComputer.computePaintableFillRegion(tilePos); } else { // If holding shift, the region is the selection bounds mFillRegion = mapDocument()->selectedArea(); // Fill region is the whole map if there is no selection if (mFillRegion.isEmpty()) mFillRegion = tileLayer->rect(); // The mouse needs to be in the region if (!mFillRegion.contains(tilePos)) mFillRegion = QRegion(); } fillRegionChanged = true; } // Ensure that a fill region was created before making an overlay layer if (mFillRegion.isEmpty()) return; if (mLastFillMethod != mFillMethod) { mLastFillMethod = mFillMethod; fillRegionChanged = true; } if (!mFillOverlay) { // Create a new overlay region const QRect fillBounds = mFillRegion.boundingRect(); mFillOverlay = SharedTileLayer::create(QString(), fillBounds.x(), fillBounds.y(), fillBounds.width(), fillBounds.height()); } // Paint the new overlay switch (mFillMethod) { case TileFill: if (fillRegionChanged || mStamp.variations().size() > 1) { fillWithStamp(*mFillOverlay, mStamp, mFillRegion.translated(-mFillOverlay->position())); fillRegionChanged = true; } break; case RandomFill: randomFill(*mFillOverlay, mFillRegion); fillRegionChanged = true; break; case WangFill: wangFill(*mFillOverlay, *tileLayer, mFillRegion); fillRegionChanged = true; break; } if (fillRegionChanged) { // Update the brush item to draw the overlay brushItem()->setTileLayer(mFillOverlay); } // Create connections to know when the overlay should be cleared makeConnections(); }
void Editor::Update() { sf::Vector2f viewCenter = view->getCenter(); sf::Vector2f viewChange = viewCenter; if (currentMapSizeX > (screenWidth - 200) / Tile::GetSize().x) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { viewCenter.x += 5; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { viewCenter.x -= 5; } if (viewCenter.x < screenWidth / 2) viewCenter.x = screenWidth / 2; if (viewCenter.x > (currentMapSizeX * Tile::GetSize().x) + 200 - screenWidth / 2) viewCenter.x = (currentMapSizeX * Tile::GetSize().x) + 200 - screenWidth / 2; } if (currentMapSizeY > screenHeight / Tile::GetSize().y) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { viewCenter.y += 5; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { viewCenter.y -= 5; } if (viewCenter.y < screenHeight / 2) viewCenter.y = screenHeight / 2; if (viewCenter.y >(currentMapSizeY * Tile::GetSize().y) - screenHeight / 2) viewCenter.y = (currentMapSizeY * Tile::GetSize().y) - screenHeight / 2; } if (viewCenter != view->getCenter()) view->setCenter(viewCenter); window->setView(*view); viewChange -= viewCenter; mousePosition = sf::Mouse::getPosition(*window); mousePosition.x += viewCenter.x - (screenWidth / 2); mousePosition.y += viewCenter.y - (screenHeight / 2); sidebar->ChangePosition(sf::Vector2i(viewChange.x, viewChange.y)); sidebar->Update(mousePosition); sidebarTiles->ChangePosition(sf::Vector2i(viewChange.x, viewChange.y)); sidebarSelection->ChangePosition(sf::Vector2i(viewChange.x, viewChange.y)); Tile::IDChangeInfo(selectedTileID, sidebar->GetMouseover()); for (TileLayer::size_type y = 0; y < tileLayerBottom.size(); y++) { for (TileRow::size_type x = 0; x < tileLayerBottom[y].size(); x++) { tileLayerBottom[y][x]->Update(mousePosition); if (tileLayerBottom[y][x]->GetMouseover()) { sf::Vector2i newSelectPos = tileLayerBottom[y][x]->GetPosition(); newSelectPos += Tile::GetSize() / 2; selector->SetPosition(newSelectPos); } } } for (vector<vector<Button*>>::size_type y = 0; y < sidebarTilesY; y++) { for (vector<Button*>::size_type x = 0; x < sidebarTilesX; x++) { sidebarTileButtons[y][x]->ChangePosition(sf::Vector2i(viewChange.x, viewChange.y)); sidebarTileButtons[y][x]->Update(mousePosition); if (sidebarTileButtons[y][x]->GetPressed()) { sf::Vector2i newSelectPos = sidebarTileButtons[y][x]->GetPosition(); newSelectPos += Tile::GetSize() / 2; sidebarSelection->SetPosition(newSelectPos); selectedTileID = sidebarTilesX * y + x; } } } saveUI->ChangePosition(sf::Vector2i(viewChange.x, viewChange.y)); saveUI->Update(mousePosition); saveButton->ChangePosition(sf::Vector2i(viewChange.x, viewChange.y)); saveButton->Update(mousePosition); if (saveButton->GetPressed()) { SaveMap(); } }