2D 瓦片图的正确数据模型(C++,Qt)

Proper data model for a 2D Tilemap (C++, Qt)

本文关键字:C++ Qt 数据模型 2D      更新时间:2023-10-16

我做了一个小的2D关卡编辑器,你可以在其中创建基于2D瓷砖的地图。但是,我的应用程序内部的性能确实非常糟糕。我目前正在考虑重新开始。

问题是,我目前使用 QGraphicsItem 来表示 QGraphicsScene 中的单个磁贴。磁贴具有一些属性。包括图像。创建地图时,我为每个图块创建一个项目,为每个图块绘制一个图像。这基本上是很多图形项目,它会减慢整个应用程序的速度。这是在创建地图后填充地图的函数:

    for(int i=0;i<map->m_rows;i++)
    {
        for(int j=0;j<map->m_cols;j++)
        {
            Tile* thetile=map->getAt(i,j);
            if(thetile)
            {
                if(map->getType()==twoditor::RECTANGLETILE)
                {
                    QGraphicsItem* item= new TileGraphicsItem(thetile);
                    m_scene->addItem(item);
                }
                else if(map->getType()==twoditor::HEXAGONTILE)
                {
                    QGraphicsItem* item= new HexagonGraphicsItem(thetile);
                    m_scene->addItem(item);
                }
            }
        }
    }

这适用于具有 100x100 图块的地图。但是,如果我想创建更大的地图..加载时间真的难以忍受..有人可以给我建议以更好地表示切片地图吗?还有其他方便的方法来显示地图和编辑其中的单元格(图块)吗?

编辑:TileGraphicItem绘画功能:

void TileGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget){
setZValue(0);
if(!m_thetile->getImage().isNull())
{
  painter->drawImage(0,0,m_thetile->getImage());
}
QPainterPath circle_path;
QRect duwagrect(boundingRect().x(),boundingRect().y(),boundingRect().width(),boundingRect().height());
circle_path.addRect(duwagrect);
m_pen.setStyle(Qt::SolidLine);
m_pen.setColor(Qt::black);
m_pen.setWidth(1);
painter->setPen(m_pen);
painter->drawPath(circle_path);
if(m_thetile->getProperty()->getBlocks())
{
    QPainterPath circle_path;
    QRect duwagrect(boundingRect().x()+2,boundingRect().y()+2,boundingRect().width()-3,boundingRect().height()-3);
    circle_path.addRect(duwagrect);
    m_pen.setStyle(Qt::DotLine);
    m_pen.setColor(Qt::red);
    m_pen.setWidth(2);
    painter->setPen(m_pen);
    painter->drawPath(circle_path);
}
if(this->isSelected())
{
  QPainterPath circle_path;
  QRect duwagrect(boundingRect().x()+2,boundingRect().y()+2,boundingRect().width()-3,boundingRect().height()-3);
  circle_path.addRect(duwagrect);
  m_pen.setStyle(Qt::SolidLine);
  m_pen.setColor(Qt::green);
  m_pen.setWidth(3);
  painter->setPen(m_pen);
  painter->drawPath(circle_path);
}
if(option->state & QStyle::State_MouseOver)
{
  QPainterPath circle_path;
  QRect duwagrect(boundingRect().x()+2,boundingRect().y()+2,boundingRect().width()-3,boundingRect().height()-3);
  circle_path.addRect(duwagrect);
  m_pen.setStyle(Qt::SolidLine);
  m_pen.setColor(Qt::cyan);
  m_pen.setWidth(2);
  painter->setPen(m_pen);
  painter->drawPath(circle_path);
}

}

问题是你正在显示所有内容,甚至是不需要的东西。
应仅创建可见项目(某个可见区域中的项目)。

另一种更快的方法是创建自定义 QGraphicsItem 来绘制孔贴图,并仅绘制可见的瓷砖(没有瓷砖作为子项目)。