Making moving 2D object in Qt OpenGL

1.3k views Asked by At

I write a deathmatch multiplayer "tanks" game where players can join to server and run a Tank, shoot etc. At the moment I want to make the mechanism of movement around the map (2D). I've tried some methods but they are not satisfying.

Right now I'm using QTimer which works perfectly with one player on map, but when I join second they both start to lag.

keyPressEvent method

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    switch(event->key())
    {
        case Qt::Key_Up:
            keyUp = true;
            break;
        case Qt::Key_Down:
            keyDown = true;
            break;
    }
 }

keyPressEvent and keyReleaseEvent are similar instead of in release event there is f.e. keyUp = false statement.

movePlayer method

void MainWindow::movePlayer()
{
    if(keyUp)
        ui->widget->playerList[playerID]->move(0.2);
    else if(keyDown)
        ui->widget->playerList[playerID]->move(-0.1);
    if(keyLeft)
        ui->widget->playerList[playerID]->rotate(-5);
    else if(keyRight)
        ui->widget->playerList[playerID]->rotate(5);
    if(keyE)
        ui->widget->playerList[playerID]->rotateCannon(-3);
    else if(keyQ)
        ui->widget->playerList[playerID]->rotateCannon(3);
}

onTimer method (sends a message to the server with a location of tank)

void MainWindow::onTimer()
{
    movePlayer();
    QTextStream out(socket);
    out << QString::number(ui->widget->playerList[playerID]->id)
           + " " + QString::number(ui->widget->playerList[playerID]->getXPos())
           + " " + QString::number(ui->widget->playerList[playerID]->getYPos())
           + " " + QString::number(ui->widget->playerList[playerID]->getRotation()) << endl;
    ui->widget->updateGL();
}

How can I write/rewrite code to achieve my goal of running 2 and more tanks smoothly?

1

There are 1 answers

2
mrVoid On

one render, one update

The problem might be that you handle players independently.

The simple game loop should handle every part in one go. You would prefer to have logic code on one timer and the rendering might be on the other. Or just go with one timer and do all at once every timer step. This should smooth out the gameplay.

// pseudo code
clockTick() {
  // do logic
  for (player : players)
    movePlayer(player);
  // Update graphics
  updateGL();
}

Be sure to check this fantastic article on The Game Loop.