void GameView::GenerateMap() { Vector2 mapCenter((float)m_pTilemap->getWidth() * .5f, (float)m_pTilemap->getHeight() * .5f); m_pStockpile = new Stockpile(this, m_pTilemap->getWidth() / 2 + 1, m_pTilemap->getHeight() / 2 - 4); AddEntity(m_pStockpile); // Spawn a bunch of trees for (int i = 0; i < TREE_DENSITY; ++i) { auto center = onut::rand2f(Vector2::Zero, Vector2((float)m_pTilemap->getWidth(), (float)m_pTilemap->getHeight())); int count = onut::randi(2, 12); for (int j = 0; j < count; ++j) { auto pos = center += onut::rand2f(Vector2(-3), Vector2(3)); pos.x = std::round(pos.x) + .5f; pos.y = std::round(pos.y) + .5f; if (pos.x >= mapCenter.x - 3 && pos.y >= mapCenter.y - 3 && pos.x <= mapCenter.x + 3 && pos.y <= mapCenter.y + 3) continue; if (pos.x < 1.f || pos.y < 1.f || pos.x >(float)m_pTilemap->getWidth() - 1.f || pos.y >(float)m_pTilemap->getHeight() - 1.f) continue; auto pTile = GetTileAt(pos); if (!pTile) continue; if (pTile->isOccupied) continue; pTile->isOccupied = true; auto pTree = new Tree(this, pos); AddEntity(pTree); } } // Spawn a bunch of rockz for (int i = 0; i < ROCK_DENSITY; ++i) { auto center = onut::rand2f(Vector2::Zero, Vector2((float)m_pTilemap->getWidth(), (float)m_pTilemap->getHeight())); int count = onut::randi(2, 6); for (int j = 0; j < count; ++j) { auto pos = center += onut::rand2f(Vector2(-3), Vector2(3)); pos.x = std::round(pos.x) + .5f; pos.y = std::round(pos.y) + .5f; if (pos.x >= mapCenter.x - 3 && pos.y >= mapCenter.y - 3 && pos.x <= mapCenter.x + 3 && pos.y <= mapCenter.y + 3) continue; if (pos.x < 1.f || pos.y < 1.f || pos.x >(float)m_pTilemap->getWidth() - 1.f || pos.y >(float)m_pTilemap->getHeight() - 1.f) continue; auto pTile = GetTileAt(pos); if (!pTile) continue; if (pTile->isOccupied) continue; pTile->isOccupied = true; auto pRock = new Rock(this, pos); AddEntity(pRock); } } for (int i = 0; i < m_pTilemap->getWidth(); ++i) { GetTileAt(i, 0)->isOccupied = true; GetTileAt(0, i)->isOccupied = true; GetTileAt(i, m_pTilemap->getHeight() - 1)->isOccupied = true; GetTileAt(m_pTilemap->getWidth() - 1, i)->isOccupied = true; } }
/*! \internal */ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QGeoMap &map) { if (!screenDirty_) return; if (map.width() == 0 || map.height() == 0) { clear(); return; } QPointF origin = map.coordinateToItemPosition(srcOrigin_, false).toPointF(); QPainterPath ppi = srcPath_; clear(); // a circle requires at least 3 points; if (ppi.elementCount() < 3) return; // translate the path into top-left-centric coordinates QRectF bb = ppi.boundingRect(); ppi.translate(-bb.left(), -bb.top()); firstPointOffset_ = -1 * bb.topLeft(); ppi.closeSubpath(); // calculate actual width of map on screen in pixels QGeoCoordinate mapCenter(0, map.cameraData().center().longitude()); QDoubleVector2D midPoint = map.coordinateToItemPosition(mapCenter, false); QDoubleVector2D midPointPlusOne = QDoubleVector2D(midPoint.x() + 1.0, midPoint.y()); QGeoCoordinate coord1 = map.itemPositionToCoordinate(midPointPlusOne, false); double geoDistance = coord1.longitude() - map.cameraData().center().longitude(); if ( geoDistance < 0 ) geoDistance += 360.0; double mapWidth = 360.0 / geoDistance; qreal leftOffset = origin.x() - (map.width()/2.0 - mapWidth/2.0) - firstPointOffset_.x(); qreal topOffset = origin.y() - (midPoint.y() - mapWidth/2.0) - firstPointOffset_.y(); QPainterPath ppiBorder; ppiBorder.moveTo(QPointF(-leftOffset, -topOffset)); ppiBorder.lineTo(QPointF(mapWidth - leftOffset, -topOffset)); ppiBorder.lineTo(QPointF(mapWidth - leftOffset, mapWidth - topOffset)); ppiBorder.lineTo(QPointF(-leftOffset, mapWidth - topOffset)); screenOutline_ = ppiBorder; std::vector<p2t::Point*> borderPts; borderPts.reserve(4); std::vector<p2t::Point*> curPts; curPts.reserve(ppi.elementCount()); for (int i = 0; i < ppi.elementCount(); ++i) { const QPainterPath::Element e = ppi.elementAt(i); if (e.isMoveTo() || i == ppi.elementCount() - 1 || (qAbs(e.x - curPts.front()->x) < 0.1 && qAbs(e.y - curPts.front()->y) < 0.1)) { if (curPts.size() > 2) { for (int j = 0; j < 4; ++j) { const QPainterPath::Element e2 = ppiBorder.elementAt(j); borderPts.push_back(new p2t::Point(e2.x, e2.y)); } p2t::CDT *cdt = new p2t::CDT(borderPts); cdt->AddHole(curPts); cdt->Triangulate(); std::vector<p2t::Triangle*> tris = cdt->GetTriangles(); screenVertices_.reserve(screenVertices_.size() + int(tris.size())); for (size_t i = 0; i < tris.size(); ++i) { p2t::Triangle *t = tris.at(i); for (int j = 0; j < 3; ++j) { p2t::Point *p = t->GetPoint(j); screenVertices_ << QPointF(p->x, p->y); } } delete cdt; } curPts.clear(); curPts.reserve(ppi.elementCount() - i); curPts.push_back(new p2t::Point(e.x, e.y)); } else if (e.isLineTo()) { curPts.push_back(new p2t::Point(e.x, e.y)); } else { qWarning("Unhandled element type in circle painterpath"); } } if (curPts.size() > 0) { qDeleteAll(curPts.begin(), curPts.end()); curPts.clear(); } if (borderPts.size() > 0) { qDeleteAll(borderPts.begin(), borderPts.end()); borderPts.clear(); } screenBounds_ = ppiBorder.boundingRect(); }