qt 写一个子线程里的跳跃函数用的是第二种线程方法 人物从585跳到470,并落回585,人物的整个跳跃过程持续1秒,每一帧都要向主线程发出坐标,所以你必须吧信号也写出来,全程注释
时间: 2023-10-11 14:09:31 浏览: 34
好的,以下是基于Qt的子线程跳跃函数实现:
```cpp
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
class JumpThread : public QThread
{
Q_OBJECT
public:
explicit JumpThread(QObject *parent = nullptr);
~JumpThread() override;
void startJump(); // 开始跳跃
void stopJump(); // 停止跳跃
signals:
void sendPosition(int x, int y); // 发送坐标信号
protected:
void run() override; // 线程执行函数
private:
QMutex m_mutex; // 互斥锁
QWaitCondition m_waitCondition; // 条件变量
bool m_isJumping; // 是否正在跳跃
};
JumpThread::JumpThread(QObject *parent)
: QThread(parent)
, m_isJumping(false)
{
}
JumpThread::~JumpThread()
{
stopJump();
}
void JumpThread::startJump()
{
QMutexLocker locker(&m_mutex);
m_isJumping = true;
m_waitCondition.wakeAll();
}
void JumpThread::stopJump()
{
QMutexLocker locker(&m_mutex);
m_isJumping = false;
m_waitCondition.wakeAll();
}
void JumpThread::run()
{
const int duration = 1000; // 跳跃过程持续1秒
const int frameTime = 16; // 每帧时间为16ms,即60帧/s
const float startPos = 585.0f; // 起跳位置
const float jumpHeight = 115.0f; // 跳跃高度
const float endPos = 470.0f; // 落地位置
int elapsed = 0; // 已经过去的时间
while (true)
{
QMutexLocker locker(&m_mutex);
if (!m_isJumping) // 如果停止跳跃
{
break; // 退出线程
}
const float pos = (elapsed < duration / 2) // 计算当前位置
? startPos - jumpHeight * (elapsed / static_cast<float>(duration / 2) - 1) * (elapsed / static_cast<float>(duration / 2))
: endPos + jumpHeight * (elapsed / static_cast<float>(duration / 2) - 2) * (elapsed / static_cast<float>(duration / 2));
emit sendPosition(0, static_cast<int>(pos)); // 发送坐标信号
elapsed += frameTime; // 更新已经过去的时间
if (elapsed >= duration) // 如果跳跃结束
{
m_isJumping = false; // 停止跳跃
}
m_waitCondition.wait(&m_mutex, frameTime); // 等待下一帧
}
}
```
使用方法如下:
```cpp
JumpThread *thread = new JumpThread(this);
connect(thread, &JumpThread::sendPosition, [this](int x, int y) {
// 更新人物坐标
});
thread->startJump(); // 开始跳跃
// ...
thread->stopJump(); // 停止跳跃
```
这里使用了一个互斥锁和一个条件变量来实现线程同步。在跳跃过程中,子线程会每隔16ms计算一次人物的位置,并发送坐标信号给主线程。如果需要停止跳跃,则设置`m_isJumping`为false,并通知条件变量,以便让子线程退出循环。