Qt快速游戏循环

时间:2018-06-14 07:21:18

标签: qt qml qt-quick

这是让我对QML / QtQuick感到困惑的事情之一:我该如何实现像pong一样使用循环的简单游戏?

我搜索了一下,在这里查看了类似的问题,但没有一个解决以下问题:

  • 我想创建一个像pong这样使用循环的简单游戏。在这个循环中,首先更新所有对象(如果是球和杆),然后渲染所有对象。对于渲染部分,我认为一旦设置了所有属性,QML就会完成工作。

  • 我想使用QML和QtQick而不是QGraphicsScene。

  • 我看过一些只使用计时器然后调整属性的例子,例如这一个:https://github.com/NicholasVanSickle/QtQuickTests/blob/master/Pong.qml但这真的是这样做的方法。在这种情况下,您将拥有更新QML属性和计时器的循环,并且我不了解如何协同工作。

  • 还有一些使用QML的游戏引擎。我想知道如何在游戏循环中使用QML。例如,您可以用C ++编写游戏循环,然后在其上面使用QML吗?或者推荐的方式是什么。可悲的是,我在任何Qt文档中都找不到这个。

2 个答案:

答案 0 :(得分:2)

当我第一次开始使用Qt时,我遇到了similar个问题,并得到了相同的答案(这是正确的)。与使用SDL来说,这是一种不同的思维方式。

我想添加一种方法,让您可以控制更新。已经有一段时间了,因为有人与我分享了这一点,但从我记忆中来看,它与确保一致的更新频率有关。

无论是否仅仅使用简单的计时器,它是否有所改进,拥有一些实际代码将有助于您入门。此外,拥有delta(计算球和桨的位置)是你必须自己做的事情,这段代码已经为你做了。

这里是GameTimer的肉:

void GameTimer::doUpdate()
{
    // Update by constant amount each loop until we've used the time elapsed since the last frame.
    static const qreal delta = 1.0 / mFps;
    // In seconds.
    qreal secondsSinceLastUpdate = mElapsedTimer.restart() * 0.001;
    mRemainder += secondsSinceLastUpdate;
    while (mRemainder > 0) {

        emit updated(delta);

        mDateTime = dateFromSimulatedTime();

        mRemainder -= delta;
        mSimulatedTime += delta;
    }
}

它在C ++中使用,如this

void DirectPather::timerUpdated(qreal delta)
{
    QHashIterator<QuickEntity*, DirectPathData> it(mData);
    while (it.hasNext()) {
        it.next();
        QuickEntity *entity = it.key();
        DirectPathData pathData = it.value();
        if (mSteeringAgent->steerTo(entity, pathData.targetPos, delta)) {
            mData.remove(entity);
        }
    }
}

由于此示例(quickpather)是基于QML的,因此它具有用于连接到计时器的复杂setter。如果你不需要像QML这样的东西,你可以用C ++创建定时器,并在必要时直接连接到它的更新信号:

connect(mTimer, &GameTimer::updated, foo, &MyGameObject::update);
// ...
connect(mTimer, &GameTimer::updated, bar, &MyOtherGameObject::update);

增量以秒为单位(1.0 == 1秒)。

您可以从示例中获取所需内容,以帮助您开始游戏。

直接回答您的一些问题:

  

我看过一些例子,只是使用计时器,然后调整属性,例如这一个:https://github.com/NicholasVanSickle/QtQuickTests/blob/master/Pong.qml但这真的是这样做的方法。在这种情况下,您将拥有更新QML属性和计时器的循环,并且我不理解它们如何协同工作。

我不推荐在这个游戏中使用QML / JavaScript中的逻辑。 C ++比JavaScript更适合这种(更快)。脚本之类的东西非常适合JavaScript。

  

还有一些游戏引擎使用QML。我想知道如何在游戏循环中使用QML。例如,您可以用C ++编写游戏循环,然后在其上面使用QML吗?或者推荐的方式是什么。可悲的是,我在任何Qt文档中都找不到这个。

我的&#34;引擎&#34;将C ++用于所有逻辑(除了脚本,保持相对较小)和QML用于GUI以及实体(动画,精灵等)。

我不认为有关于这个确切主题的任何文档(使用QML编写的游戏使用QML前端),但是有一些基于QML的游戏示例:

答案 1 :(得分:1)

你不需要在QML中进行游戏循环,整个过程都是事件驱动的,并且由底层事件循环提供支持。

你可以轻松利用它,使用定时器,信号,动画以及不开箱即用的东西。

游戏循环本质上是锁定的。在QML中,您只能使用主线程。并且你不能锁定主线程 - 它必须旋转或你的应用程序将停止响应。