我有一個帶有 cpp 的 qt 應用程式。該應用程式是落球游戲,當球被籃筐接住時,需要增加分數。應用程式使用一些 timerEvent 來更新分數。每 10 毫秒呼叫一次超時槽。我的問題是分數更新不止一次,并且在增量方面非常隨機。我怎么解決這個問題。
主視窗.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
qDebug() <<"mainWindow constructor";
basket = new Basket(this);
sprite = new Sprite(this);
timer=new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::onTimer);
timer->start(3000);
scoreTimer=new QTimer(this);
connect(scoreTimer, &QTimer::timeout, this, &MainWindow::onScoreTimer);
scoreTimer->start(10);
timerIdForScoreTimer=scoreTimer->timerId();
score = 0;
}
MainWindow::~MainWindow()
{
qDebug() <<"mainWindow destructor";
delete ui;
}
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(rect(), QBrush(QColor(Qt::white)));
painter.setPen(Qt::black);
painter.setBrush(QBrush(QColor(Qt::darkBlue)));
emit draw(painter);
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Right)
{
emit move(1);
}
if(event->key() == Qt::Key_Left)
{
emit move(0);
}
}
void MainWindow::on_actionStart_triggered()
{
connect(this, &MainWindow::draw, sprite, &Sprite::drawBall);
connect(this, &MainWindow::draw, basket, &Basket::drawBar);
connect(this, &MainWindow::move, basket, &Basket::move);
}
void MainWindow::onTimer()
{
std::cout << "Tick!-----------------------------------------------------------------------------" << std::endl;
sprite = new Sprite(this);
connect(this, &MainWindow::draw, sprite, &Sprite::drawBall);
}
void MainWindow::onScoreTimer()
{
// qDebug() <<"Timer event called in Mainwindow.cpp";
if( (((sprite->y - 15) >= 500)&& sprite->y <530 ) && ( (sprite->x <= (basket->x1 80)) && (sprite->x >= (basket->x1 - 80)) ) )
{
// qDebug("x and y position when condition is met and also x1 and y1");
// qDebug()<<x;
// qDebug()<<y;
// qDebug()<<x1;
// qDebug()<<y1;
sprite->dy *= -1;
sprite->dx *= -1;
qDebug() << "score update";
qDebug() <<score;
score ;
// ui->lcdNumber->setDigitCount(score);
ui->score_label->setText(QVariant(score).toString());
}
}
在 MainWindow::onScoreTimer() 中,“score”變數隨機遞增且不止一次。我該如何防止這種情況。
uj5u.com熱心網友回復:
因此,洗掉所有除錯雜亂無章后,onScoreTimer()看起來像這樣:
void MainWindow::onScoreTimer()
{
if( (((sprite->y - 15) >= 500)&& sprite->y <530 ) && ( (sprite->x <= (basket->x1 80)) && (sprite->x >= (basket->x1 - 80)) ) )
{
sprite->dy *= -1;
sprite->dx *= -1;
score ;
ui->score_label->setText(QVariant(score).toString());
}
}
它反轉精靈的方向,增加分數,并更新score_label. 一切都很好,但請注意,它不會做任何會阻止相同if的 -test (在方法的頂部)在下一次onScoreTimer()被呼叫時再次成功。
因此,完全有可能當精靈到達目標區域時,onScoreTimer()(每10mS呼叫一次)會連續多次執行上述所有操作,每次改變精靈的方向,并隨著精靈增加分數來回振動。
至于如何避免這種行為,我可以想到兩種可能的解決方案:
- 除了您在上述代碼塊中所做的事情外,還要更改
sprite->x和sprite->y到目標區域之外的某個位置,以便下一次呼叫onScoreTimer不會再次觸發相同的例程。
或者
- 添加一個布爾成員變數來跟蹤精靈的當前目標內/非目標狀態,并且僅在該變數的狀態從 false 變為 true 時運行例程
例如:
class MainWindow {
[...]
private:
bool spriteWasInTarget = false;
};
void MainWindow::onScoreTimer()
{
const bool spriteIsInTarget = ( (((sprite->y - 15) >= 500)&& sprite->y <530 ) && ( (sprite->x <= (basket->x1 80)) && (sprite->x >= (basket->x1 - 80)) ) );
if ((spriteIsInTarget)&&(!spriteWasInTarget))
{
sprite->dy *= -1;
sprite->dx *= -1;
score ;
ui->score_label->setText(QVariant(score).toString());
}
spriteWasInTarget = spriteIsInTarget;
}
...這樣例程只在精靈(重新)進入目標區域后的第一次呼叫時執行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/476831.html
上一篇:帶有QSortFilterProxyModel的QTableView找不到正確的行,因為已訂購
下一篇:Nginx 開源版編譯安裝教程
