我想要实现的目标类似于棋盘游戏。有一个100*100的网格,放在一个Item
它驻留在一个Flickable
.
“游戏板”的各个矩形都是 svg 图像,目前大约有 20 种,可能会增加到数百种。
作为基准测试,我只是尝试用元素填充“世界”:
Component.onCompleted:
{
var i,j;
for (i=0; i<100; ++i)
for (j=0; j<100; ++j)
{
var type = (i+j) % 20;
Qt.createQmlObject('import QtQuick 2.0; Image {source:"qrc:///icons/img/symbol'+type+'.svg";
width: 32*scaling.factor;
height: 32*scaling.factor;
x:'+i*32+'*scaling.factor;
y:'+j*32+'*scaling.factor}',
mainScreen);
}
}
这需要超过5秒在一台性能较好的电脑上。
但是,加载所有内容后,它可以顺利运行,滚动和缩放(scaling.factor
是由滑块或旋转框设置的浮动值)。
svg 图像非常简单,仅包含一些基本形状。如果我尝试只加载一个简单的矩形而不是 svg 图像
Qt.createQmlObject('import QtQuick 2.0; Rectangle {color
: "red"; width: 32; height: 32; x:'+i*32+'; y:'+j*32+'}',
mainScreen);
仍然需要大约 3 秒。即使没有图像,也没有动态缩放。
我记得20年前,有一些策略游戏运行在单核、低于400 MHz CPU的计算机上,这些游戏有更大的地图、更复杂的图块、动画、寻路等。我们甚至没有谈论3d.
现代电脑怎么会因为显示几千个非常基本的形状而感到窒息呢?它不应该是从磁盘加载的时间,因为元素位于资源文件中,甚至使用矩形而不是图像进行的测试也非常慢。
不保持所有显示,并且只加载可见屏幕边界附近的元素显然是一种可行的方法,或者如果我有一张 10000*10000 的地图,那就是这样。我期望 100*100 个项目应该能够同时显示,特别是在具有良好分辨率的屏幕上,其中大多数项目都是可见的。
我是否错过了一些明显的事情,或者我应该完全忘记 Qt Quick,我应该在 OpenGL 或某些 2d 引擎中手动完成所有操作吗?
Edit:
正如评论所建议的,Qt.createQmlObject
非常慢。
因此我尝试了
var component = Qt.createComponent("field.qml");
component.createObject(mainScreen, {"x": i*32, "y": j*32 });
Where field.qml
仅包含一个Rectangle{}
,或者,在第二个测试中,只是一个空的Item{}
。在这两种情况下,10000 次迭代都花费了超过 3 秒的时间。将 svg 添加到field.qml
只增加了0.8秒的时间。
顺便问一下,图像不应该被缓存吗?即使我重复使用相同的简单 svg(仅包含 3 个简单的矩形),也会花费很多时间。
Using a Repeater{}
使一切变得更快。空的Rectangle
s 的渲染时间大约为 0.2 到 0.3 秒,svg 图像的渲染时间为 1 秒。 (但是,这种方法还有其他缺点。当我测试完不同的方法后,我会发布答案)