问题描述
上下文
我正在使用c ++ / Qt5开发跨平台游戏。它必须可以在Windows,Linux,Macos,Android和iOS上运行。到目前为止,我已经在Windows上开发了该游戏,并且没有任何问题。但是,昨天在Android上进行部署时,QGraphicsView
上存在性能和停顿的巨大问题。经过调查,我发现删除动画gif可以解决我的表演问题。
此外,我在QGraphicsView
上做的动画也口吃。现在已经解决了,但是口吃动画的代码可能会提示问题:
void Renderer::move(QGraphicsItem *item,const QPoint &destination,int totalTime)
{
if (totalTime >= 0 && item->pos() != destination) {
QVector2D diff = QVector2D(destination - item->pos());
float time = (float)totalTime / 10;
if (time < 1)
time = 1;
float speed = (std::sqrt(std::pow(diff.x(),2) + std::pow(diff.y(),2))) / time;
diff.normalize();
QPointF nextPos = item->pos() + (diff.toPoint() * speed);
item->setPos(nextPos);
QTimer::singleShot(10,[this,item,destination,totalTime]() {
move(item,totalTime - 10);
});
}
}
对于那些感兴趣的人,我已经按照this question
的答案解决了这个问题问题
我已从资产中删除了所有动画gif,以制作演示版本。但是它已经变得真正静止了。动态的gif文件使游戏看起来非常酷。我该如何解决性能问题?
我尝试过的事情
这是QGraphicsView
内第一个动画gif的实现:
// pixmapitem.hxx
class PixmapItem : public QObject,public QGraphicsPixmapItem {
Q_OBJECT
public:
explicit PixmapItem(const Sprite::Asset asset,const QSize &size,QGraphicsItem *parent = nullptr);
~PixmapItem();
private:
QMovie *_gif;
};
// pixmapitem.cxx
PixmapItem::PixmapItem(const Sprite::Asset asset,QSize const &size,QGraphicsItem *parent)
: QObject(),QGraphicsPixmapItem(parent),_gif(nullptr)
{
// Sprite is a class that manages the assets. It loads a bunch of things from a folder,and it
// verifies the extension to load the right asset. This way,the graphists can provide me
// PNG,GIF,or JPG,and the Sprite class will load it automatically.
auto sprite = new Sprite(asset);
sprite->setLoadPixmap(false);
sprite->setFixedSize(size);
sprite->tryLoad();
if (sprite->format() == Sprite::Extension::GIF) {
_gif = new QMovie(sprite->imagePath());
_gif->setScaledSize(size);
_gif->start();
connect(_gif,&QMovie::frameChanged,[this] {
setPixmap(_gif->currentPixmap());
update();
});
}
else {
setPixmap(QPixmap(sprite->imagePath())
.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation));
}
}
~PixmapItem()
{
if (_gif != nullptr && _gif->isValid()) {
_gif->stop();
_gif->deleteLater();
}
}
我认为重新粉刷QGraphicsView
的矩形不会造成任何问题,我是错的。
我尝试做的第一件事是遵循here发布的优化。它改善了性能,但结结声仍在发生。因此,我改变了处理 gif 的方式,从重新绘制QGraphicsPixmapItem
到只设置QGraphicsProxyWidget
的 widget (注意: Sprite
是QLabel
的子代):
// pixmapitem.hxx
class PixmapItem : public QGraphicsProxyWidget {
Q_OBJECT
public:
explicit PixmapItem(const Sprite::Asset asset,QGraphicsItem *parent = nullptr);
QPixmap pixmap();
private:
Sprite *_sprite;
};
// pixmapitem.cxx
PixmapItem::PixmapItem(const Sprite::Asset asset,QGraphicsItem *parent)
: QGraphicsProxyWidget(parent),_sprite(nullptr)
{
_sprite = new Sprite(asset);
_sprite->setFixedSize(size);
_sprite->tryLoad();
// Without it,transparent assets were white on Android. It wasn't needed on PC.
_sprite->setAttribute(Qt::WA_NoSystemBackground);
setWidget(_sprite);
}
QPixmap PixmapItem::pixmap()
{
if (_sprite->movie() != nullptr) {
return _sprite->movie()->currentPixmap();
}
else {
return _sprite->pixmap(Qt::ReturnByValueConstant());
}
}
它仍然不能解决我的问题。有人建议我,在QGraphicsPixmapItem
内加载gif的所有像素图后,性能可能会得到改善。这是我的实现:
// pixmapitem.hxx
class PixmapItem : public QObject,public QGraphicsPixmapItem {
Q_OBJECT
public:
explicit PixmapItem(
const Sprite::Asset asset,QGraphicsItem *parent = nullptr);
~PixmapItem();
QPixmap pixmap() const;
private:
QList<QGraphicsPixmapItem *> _items;
int _currentItem;
int _fps;
QTimer *_timer;
};
// pixmapitem.cxx
// ----------------------------------------------------------------------------
// Constructor.
PixmapItem::PixmapItem(const Sprite::Asset asset,_items(),_currentItem(0),_fps(30),_timer()
{
auto sprite = new Sprite(asset);
sprite->setLoadPixmap(false);
sprite->tryLoad();
if (sprite->format() == Sprite::Extension::GIF) {
auto movie = new QMovie(sprite->imagePath());
movie->setScaledSize(size);
_timer = new QTimer;
connect(_timer,&QTimer::timeout,[this] {
if (++_currentItem >= _items.count())
_currentItem = 0;
setPixmap(pixmap());
});
for (int i = 0; i < movie->frameCount(); ++i) {
movie->jumpToFrame(i);
_items.push_back(new QGraphicsPixmapItem(movie->currentPixmap(),parent));
}
setPixmap(pixmap());
_timer->start(1000.0 / _fps);
movie->deleteLater();
}
else {
_items.push_back(new QGraphicsPixmapItem(
QPixmap(sprite->imagePath())
.scaled(size,Qt::SmoothTransformation),parent));
setPixmap(pixmap());
}
setCacheMode(QGraphicsItem::ItemCoordinateCache);
sprite->deleteLater();
}
// ----------------------------------------------------------------------------
// Destructor.
PixmapItem::~PixmapItem()
{
if (_timer) {
if (_timer->isActive())
_timer->stop();
delete _timer;
}
}
// ----------------------------------------------------------------------------
// Public method.
QPixmap PixmapItem::pixmap() const
{
return _items.at(_currentItem)->pixmap();
}
您可能已经猜到了,我仍然遇到表演问题(如果没有的话,我不会在这里发布)。我现在不知道该怎么做才能优化我的游戏。任何帮助将不胜感激。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)