Lee_Serena 2024-06-17 15:36 采纳率: 14.3%
浏览 3
已结题

我的背景不移动,是定时器有问题吗


#ifndef MAINSCENE_H
#define MAINSCENE_H

#include <QWidget>
#include"qtimer.h"
#include"qpainter.h"
#include"map.h"

namespace Ui {
class MainScene;
}

class MainScene : public QWidget
{
    Q_OBJECT

public:
    explicit MainScene(QWidget *parent = 0);
    ~MainScene();
    //初始化
    void initScene();
    //启动游戏
    void playGame();
    //设置定时器
    QTimer m_timer;
    //加入地图对象作为背景
    Map m_map;
    //地图中元素位置更新
    void updatePosition();
    //把地图对象绘制到地图中
    void paintEvent(QPaintEvent *event);

private:
    Ui::MainScene *ui;
};

#endif // MAINSCENE_H

```c++
#include "mainscene.h"
#include "ui_mainscene.h"
#include"config.h"
#include"qicon.h"


MainScene::MainScene(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainScene)
{
    ui->setupUi(this);
    initScene();
}

MainScene::~MainScene()
{
    delete ui;
    //启动游戏
    playGame();
}

//初始化游戏场景
void MainScene::initScene()
{
    //设置窗口大小
    setFixedSize(GAME_WIDTH,GAME_HEIGHT);
    //设置窗口标题
    setWindowTitle(GAME_TITLE);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/app.ico"));
    //设置刷新间隔
    m_timer.setInterval(GAME_RATE);
}

void MainScene::playGame()
{

    //启动定时器
    m_timer.start(10);

    //监听信号实现更新地图位置
    connect(&m_timer,&QTimer::timeout,[=](){
        //每隔一段时间更新游戏中元素的位置
        updatePosition();
        //每隔一段时间调用painterevent实现绘制
        update();
    });
}

void MainScene::updatePosition()
{
    //更新地图元素的坐标
    m_map.mapUpdate();
}

void MainScene::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    //直接画不了map这个对象,只能分别画map里的成员pixmap1、2
    painter.drawPixmap(0,m_map.m_map1_posY,m_map.m_pix1);
    painter.drawPixmap(0,m_map.m_map2_posY,m_map.m_pix2);
}



```c++
#ifndef MAP_H
#define MAP_H
#include"qpixmap.h"


class Map
{
public:
    Map();
    //地图滚动坐标计算
    void mapUpdate();

    //图片对象1
    QPixmap m_pix1;
    //图片对象2
    QPixmap m_pix2;

    //地图Y轴坐标
    int m_map1_posY;
    int m_map2_posY;

    //图片滚动
    int m_scroll_speed;

};

#endif // MAP_H


#include "map.h"
#include"config.h"

Map::Map()
{
    //初始化地图对象
    m_pix1.load(MAP_PATH);
    m_pix2.load(MAP_PATH);
    //初始化地图对象y轴坐标
    m_map1_posY=-GAME_HEIGHT;
    m_map2_posY=0;
    //设置地图滚动速度
    m_scroll_speed=M_SCROLL_SPEED;

}

void Map::mapUpdate()
{
    //地图对象滚动
    m_map1_posY+=m_scroll_speed;
    m_map2_posY+=m_scroll_speed;
    //设置重复滚动
    if(m_map1_posY>=0)
        m_map1_posY=-GAME_HEIGHT;
    if(m_map2_posY>=GAME_HEIGHT)
        m_map2_posY=0;
}


  • 写回答

2条回答 默认 最新

  • 专家-皆知 2024-06-17 15:36
    关注

    参考免费微信小程序:皆我百晓生 作答,经由专家-皆知整理回复,如问题解决,望采纳;如仍有疑问,请评论回复。

    从你提供的代码来看,你的MainScene类中确实设置了定时器,并且在定时器触发时更新了地图的位置并通过调用update()方法触发重绘事件。然而,如果你观察到背景没有移动,这可能是因为几个潜在的问题之一:

    1. 定时器是否正确启动:在MainScene的构造函数中,你调用了initScene(),但在~MainScene()析构函数中调用了playGame(),这显然是不正确的,因为析构函数是在对象销毁时调用的,而此时启动定时器已经没有任何意义。你应该确保playGame()initScene()之后被调用,并且是在构造函数中。

    2. 定时器的时间间隔:你设置了定时器的时间间隔为10毫秒,这可能太短了,导致CPU使用率高且可能由于刷新频率过高而无法看到明显的移动效果。考虑增加时间间隔,例如30-60毫秒,这通常可以提供更流畅的游戏体验。

    3. 更新位置的方法:在updatePosition()中,你调用了m_map.mapUpdate();,这应该没问题,只要Map类中的mapUpdate()方法正确地改变了地图的位置。

    4. paintEvent的绘制逻辑:在paintEvent中,你使用QPainter正确地绘制了地图,但是要确保m_map.m_map1_posYm_map.m_map2_posY的值确实按照预期改变,否则地图看起来就不会移动。

    基于上述分析,以下是修改后的MainScene.cpp文件,修正了构造函数和析构函数中的错误,并调整了定时器的时间间隔:

    #include "mainscene.h"
    #include "ui_mainscene.h"
    #include"config.h"
    #include"qicon.h"
    
    MainScene::MainScene(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::MainScene)
    {
        ui->setupUi(this);
        initScene();
        playGame(); // 确保在构造函数中调用playGame()
    }
    
    MainScene::~MainScene()
    {
        delete ui;
    }
    
    // 初始化游戏场景
    void MainScene::initScene()
    {
        setFixedSize(GAME_WIDTH, GAME_HEIGHT);
        setWindowTitle(GAME_TITLE);
        setWindowIcon(QIcon(":/res/app.ico"));
        m_timer.setInterval(30); // 调整时间间隔,例如30毫秒
    }
    
    void MainScene::playGame()
    {
        m_timer.start();
        connect(&m_timer, &QTimer::timeout, this, &MainScene::updatePosition);
        connect(&m_timer, &QTimer::timeout, this, &QWidget::update);
    }
    

    注意,在playGame()方法中,我直接将updatePositionupdate方法与定时器的超时信号连接,这样可以简化代码并确保每次超时时都会调用这两个方法。

    请检查这些修改是否解决了你的问题。如果还有其他疑问或需要进一步的帮助,请随时告诉我。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 6月25日
  • 已采纳回答 6月17日
  • 创建了问题 6月17日