防止计时器多次更新计数器变量
我有一个带有CPP的QT应用程序。当球被篮球捕获时,应用程序是落球的比赛,得分需要增加。 该应用程序使用一些时间探测来更新分数。每10毫秒都会调用超时的插槽。我的问题是分数不止一次更新 它的增量非常随机。我该如何解决这个问题。
mainwindow.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()“得分”变量被随机增量,不止一次。我该如何防止这种情况。
I have a qt application with cpp. The application is Falling ball game, when the ball is catched by basket the score needs to be incremented.
The application uses some timerEvent to update the score. The slot for timeout is called for every 10 msec. My problem is the score is updated more than once and
is very random in its incrementation. How can I solve this problem.
MainWindow.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());
}
}
In MainWindow::onScoreTimer() the "score" variable is incremented randomly and more than once. How can I prevent this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,删除了所有调试的cruft,
onscoreTimer()
看起来像这样:它逆转了精灵的方向,增加得分并更新
score_label
。一切都很好,但是请注意,如果 做的事情是阻止相同 -test(在方法的顶部)再次成功的任何事情下次调用onscoreTimer()
。因此,当精灵到达目标区域时,
onscoreTimer()
(每10ms称为每10ms)完全有可能执行上述所有次数,每次都会更改精灵的方向,随着雪橇振动的振动,增加得分很大。至于如何避免这种行为,我可以想到两种可能的解决方案:
sprite-&gt; x
和sprite- &gt; y
到目标区域外的某个位置,因此下一个呼叫onscoreTimer
不会再次触发相同的例程。或
运行
时才 例程Sprite(RE)进入目标区域后的第一个呼叫执行。
So with all the debugging cruft removed,
onScoreTimer()
looks like this:It reverses the sprite's direction, increments the score, and updates the
score_label
. All well and good, but note that what it doesn't do is anything that would prevent that sameif
-test (at the top of the method) from succeeding again the next timeonScoreTimer()
is called.Therefore, it's entirely likely that when the sprite reaches the target area,
onScoreTimer()
(which is called every 10mS) will do all of the above many times in a row, changing the sprite's direction every time, and increasing the score quite a bit as the sprite vibrates back-and-forth.As for how to avoid that behavior, I can think of two possible solutions:
sprite->x
andsprite->y
to some location outside of the target-area, so that the next call toonScoreTimer
won't trigger the same routine again.or
e.g.:
... so that way the routine only executes on the first call after the sprite (re)enters the target-area.