我想要实现的类似于棋盘游戏。有一个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);
}
}
在中等优质的PC上超过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。
现代PC如何能够显示几千个非常基本的形状?它不应该是来自磁盘的加载时间,因为元素在资源文件中,甚至使用矩形而不是图像的测试也非常慢。
不保持所有这些显示,只加载可见屏幕边框附近的元素显然是一种方法,或者如果我有10000 * 10000的地图。我希望能够同时显示100 * 100个项目,特别是在具有良好分辨率的屏幕上,大部分都是可见的。
我是否遗漏了一些明显的东西,或者我是否应该完全忘记Qt Quick?我应该在OpenGL或某些2D引擎中手动完成所有操作吗?
修改
根据评论的建议,Qt.createQmlObject
非常慢。
因此我尝试了
var component = Qt.createComponent("field.qml");
component.createObject(mainScreen, {"x": i*32, "y": j*32 });
field.qml
只包含一个Rectangle{}
,或者在第二个测试中,只有空Item{}
。在这两种情况下,10000次迭代花费超过3秒。将svg添加到field.qml
只会使时间增加0.8秒。
那么,是不是应该缓存的图像?即使我有相同的简单svg(只包含3个简单的矩形)重复遍历,它需要大量的时间。
使用Repeater{}
可以让一切变得更快。空Rectangle
s渲染大约0.2到0.3秒,svg图像在一秒钟内渲染。 (然而,这种方法有其他缺点。当我完成不同方法的测试后,我会发布答案)
答案 0 :(得分:2)
(虽然它没有完全解决我的具体问题,但我会将此作为答案发布,因为它符合问题的范围,可能对其他人有用。)
虽然官方示例使用动态创建对象,但该方法仅在对象数量相当低时才有用。对于非常多的项目,flyway.baselineOnMigrate = true
或ListView
的优点是只渲染实际位于视图边界内的项目。
TableView
比TableView
{
anchors.fill: parent
model: ListModel {}
itemDelegate: MyField{}
Component.onCompleted:
{
var i;
for (i=0; i<10000; ++i)
{
model.append({});
}
}
或Qt.createQmlObject
快几个数量级,比Component.createObject