示例#1
0
文件: tilestamp.cpp 项目: bjorn/tiled
/**
 * 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();
}
示例#3
0
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();
	}
}