You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt C++气球游戏:从文本文件读取坐标生成对象异常排查

气球游戏生成异常问题排查

原有游戏情况

  • 气球从屏幕上方y=60固定位置、随机x坐标生成并向下移动
  • 玩家点击未出界的气球得分,未点击则失分
  • 30秒倒计时结束后显示命中数、失分数及最终得分

新增功能需求

  • 从konumlar.txt文本文件读取每行空格分隔的x、y坐标,存储为QPoint类型并放入QListcoordinatePool
  • 生成气球时从coordinatePool中随机选取坐标

遇到的问题

  • 气球仅在屏幕左上角出现
  • 部分气球瞬间消失

已排查内容

  • 调试确认coordinatePool已正确读取所有坐标,且坐标均在游戏屏幕(约1580x850)范围内
  • 移开背景UI后仍无正常气球生成

问题原因分析

1. 气球移动时x坐标未正确保存(导致左上角出现)

在balon.cpp的构造函数中,接收了传入的x参数并设置给label,但未将该x值赋值给类的成员变量。在move()函数中调用label->setGeometry(x, label->y() + 3, 50, 50)时,这里的x是未初始化的类成员变量(默认值为0),导致每次移动后气球的x坐标被重置为0,最终全部聚集在屏幕左上角。

2. 部分初始坐标接近屏幕底部(导致瞬间消失)

konumlar.txt中存在如400 700、1000 600这类y坐标较高的点,游戏屏幕高度约为850,move()函数中判断label->y() >= scrsize.height() - 30(即850-30=820)时就会触发气球消失。这些高y坐标的气球只需要移动几十次(每次+3)就会达到阈值,看起来像是瞬间消失。

修复方案

方案1:修正x坐标的保存与使用

修改balon.cpp的构造函数,将传入的x参数赋值给类成员变量:

balon::balon(QWidget *win,int x, int y)
{
    this->x = x; // 新增:保存x坐标到类成员变量
    scrsize = win->size();
    balon_num = QRandomGenerator::global()->bounded(0, 7);
    label = new QLabel(win);
    path = QString(":/images/images/") + QString::number(balon_num) + ".jpg";
    pic.load(path);
    label->setGeometry(x, y, 50, 50);
    label->setPixmap(pic.scaled(50, 50, Qt::KeepAspectRatio));
    label->installEventFilter(this);
    label->show();
    timer = new QTimer(this);
    timer->setInterval(15);
    connect(this, SIGNAL(status(int)), win, SLOT(checkstatus(int)));
    connect(timer, SIGNAL(timeout()), this, SLOT(move()));
    connect(win, SIGNAL(focusin()), this, SLOT(start()));
    connect(win, SIGNAL(focusout()), this, SLOT(stop()));
    timer->start();
}

同时,在balon.h中声明对应的成员变量:

class balon : public QObject
{
    Q_OBJECT
private:
    int x; // 新增x成员变量
    QSize scrsize;
    int balon_num;
    QLabel *label;
    QString path;
    QPixmap pic, pic2;
    QTimer *timer;
    bool stopped = false;
    // 其余原有成员/函数声明不变
};

方案2:处理高y坐标的初始点

可以根据需求选择以下两种方式之一:

  • 过滤konumlar.txt中y坐标过高的点,比如只保留y < scrsize.height() - 100的坐标,给气球留出足够的移动距离
  • 修改move()函数的消失判断逻辑,考虑气球自身高度,避免未完全显示就消失:
void balon::move() {
    scrsize = label->parentWidget()->size();
    // 判断气球底部是否超出屏幕边界
    if (label->y() + label->height() >= scrsize.height()) {
        emit status(0);
        delete label;
        delete this;
    } else {
        label->setGeometry(this->x, label->y() + 3, 50, 50);
        timer->start();
    }
}

额外验证点

  • 编译前确认balon.h中已正确声明x成员变量,避免编译错误
  • 可以在MainWindow::generate()中打印当前使用的坐标,验证坐标是否正确传递给balon对象

内容的提问来源于stack exchange,提问作者Berk Tezcan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:45:01