I’ve made basic snake game on c++ with qt. I want to adjust the speed of snake by pressing buttons. But when I do this, the snake starts to move uneven, seems like it skipping frames. Initially it works fine with any speed initialised in ‘delay’ variable.
#include "model.h"
#include <QDebug>
s21::Model::Model(){
initGame();
}
bool s21::Model::getIsInGame(){
return isInGame;
}
QPoint s21::Model::getApple()
{
return apple;
}
QVector<QPoint> s21::Model::getDots()
{
return dots;
}
int s21::Model::getDelay()
{
return DELAY;
}
void s21::Model::setDelay(int delay)
{
DELAY = delay;
}
void s21::Model::increaseSpeed()
{
setDelay(getDelay() - 10);
restartTimer();
qDebug() << getDelay();
}
void s21::Model::decreaseSpeed()
{
setDelay(getDelay() + 10);
restartTimer();
qDebug() << getDelay();
}
void s21::Model::timerEvent(QTimerEvent *e)
{
Q_UNUSED(e);
if(isInGame){
checkApple();
move();
checkCollision();
}
}
void s21::Model::locateApple()
{
apple.rx() = arc4random() % 10;
apple.ry() = arc4random() % 20;
emit gameStateChanged();
}
void s21::Model::move()
{
// action = Right;
for(int i = dots.size() - 1; i > 0; --i ){
dots[i] = dots [i-1];
}
switch (action) {
case Left: { dots[0].rx() -= 1; break; }
case Right: { dots[0].rx() += 1; break; }
case Up: { dots[0].ry() -= 1; break; }
case Down: { dots[0].ry() += 1; break; }
}
emit gameStateChanged();
}
void s21::Model::checkCollision()
{
if(dots.size() > 4){
for(int i = 1; i < dots.size(); ++i){
if(dots[0] == dots[i]){
isInGame = false;
}
}
}
if(dots[0].x() >= 10) { isInGame = false; }
if(dots[0].x() < 0) { isInGame = false; }
if(dots[0].y() >= 20) { isInGame = false; }
if(dots[0].y() < 0) { isInGame = false; }
if(!isInGame){
killTimer(timerId );
}
}
void s21::Model::checkApple()
{
if (apple == dots[0]){
dots.push_back(QPoint(0,0));
locateApple();
}
}
void s21::Model::restartTimer()
{
killTimer(timerId);
timerId = startTimer(DELAY);
}
void s21::Model::initGame(){
isInGame = true;
dots.resize(4);
for(int i = 0; i < dots.size(); ++i){
dots[i].rx() = dots.size() - i - 1;
dots[i].ry() = 0;
}
timerId = startTimer(DELAY);
locateApple();
}
`
I’m reading the buttons in view.cpp by this function:
void s21::View::keyPressEvent(QKeyEvent *event)
{
int key = event->key();
switch(key) {
case Qt::Key_Left:
controller.setDirLeft(key);
break;
case Qt::Key_Right:
controller.setDirRight(key);
break;
case Qt::Key_Up:
controller.setDirUp(key);
break;
case Qt::Key_Down:
controller.setDirDown(key);
break;
case Qt::Key_E:
controller.speedUp(key);
break;
case Qt::Key_Q:
controller.slowDown(key);
break;
}
}
I also logged time on every move, originally it works fine but when i change speed by buttons, for example to delay = 240, the time doesn’t correspond to the delay:
QTime("15:51:36.607")
QTime("15:51:36.760")
QTime("15:51:36.832")
QTime("15:51:36.928")
QTime("15:51:37.083")
QTime("15:51:37.083")
QTime("15:51:37.235")
QTime("15:51:37.332")
QTime("15:51:37.403")