#include "mainwidget.h" #include "actor.h" #include "block.h" #include "constants.h" #include "util.h" #include "pacman.pb.h" MainWidget::MainWidget(QWidget *parent) : QWidget(parent), m_currentKey(Transmission::none), m_running(false) { /* create audio player */ m_sirenPlayer1 = new AudioPlayer(this); m_sirenPlayer2 = new AudioPlayer(this); if (m_sirenPlayer1->isWorking() && m_sirenPlayer2->isWorking()) { m_sirenPlayer1->setPrefinishMark(100); m_sirenPlayer2->setPrefinishMark(100); connect(m_sirenPlayer1, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer2())); connect(m_sirenPlayer2, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer1())); AudioManager::self()->registerAudioPlayer(m_sirenPlayer1); AudioManager::self()->registerAudioPlayer(m_sirenPlayer2); } Color::Color color = connectToServer(); if (color == Color::none) { QMessageBox::critical(this, "Error", "Failed to connect to server, falling back to local test mode"); // TODO: quit application here or sth return; } /* create our scene */ m_scene = new SceneHolder(this); m_scene->setColor(color); /* call updateMap after m_color ist set! */ createGui(); Transmission::map_t map = Util::createDemoMap(); m_scene->updateMap(map); Util::deleteMap(map); map = NULL; connect(m_socket, SIGNAL(readyRead()), this, SLOT(tick())); QTimer *sendTimer = new QTimer(this); connect(sendTimer, SIGNAL(timeout()), this, SLOT(sendKeyUpdate())); sendTimer->start(Constants::tick); qDebug() << "[Connect] mycolor=" << m_scene->color(); //TODO: play intro as soon as there are enough players //connect(AudioPlayer::self(), SIGNAL(finished()), this, SLOT(startGame())); //AudioPlayer::self()->play(AudioPlayer::Intro); startGame(); } bool MainWidget::connected() { return m_socket != NULL; } void MainWidget::createGui() { setFocusPolicy(Qt::StrongFocus); /* first one is always the own score */ QHBoxLayout *scoreLayout = new QHBoxLayout(); for (unsigned int i = 0; Color::order[i] != Color::none ; ++i) { QGroupBox *scoreBox = new QGroupBox(QString("Spieler %1").arg(i + 1), this); scoreBox->setObjectName(QString("actor%1").arg(i + 1)); scoreBox->setCheckable(true); connect(scoreBox, SIGNAL(clicked()), this, SLOT(playerScoreClicked())); QGridLayout *playerLayout = new QGridLayout(); scoreBox->setLayout(playerLayout); playerLayout->addWidget(new QLabel("Rundenpunkte:", this), 0, 0); playerLayout->addWidget(new QLabel("Gesamtpunkte:", this), 1, 0); playerLayout->addWidget(new QLabel("", this), 0, 1); playerLayout->addWidget(new QLabel("", this), 1, 1); if (Color::order[i] == m_scene->color()) scoreLayout->insertWidget(0, scoreBox); else scoreLayout->addWidget(scoreBox); m_playerScoreLayouts.append(playerLayout); } QVBoxLayout *layout = new QVBoxLayout(this); layout->addLayout(scoreLayout); QGraphicsView *window = new QGraphicsView(m_scene, this); window->setFrameStyle(0); window->setAlignment(Qt::AlignLeft | Qt::AlignTop); window->setFixedSize(Constants::map_size_pixel.width, Constants::map_size_pixel.height); window->setWindowFlags(window->windowFlags() & ~Qt::WindowMaximizeButtonHint); window->setFocusPolicy(Qt::NoFocus); layout->addWidget(window); QFile css(":/stylesheet"); css.open(QFile::ReadOnly); qApp->setStyleSheet(QLatin1String(css.readAll())); setLayout(layout); } void MainWidget::updateScore(const ProtoBuf::MapUpdate& packet) { for(unsigned i = 0; Color::order[i] != Color::none; ++i) { QGridLayout *score = m_playerScoreLayouts.at(i); QLabel *turnPointsLbl = dynamic_cast(score->itemAtPosition(0, 1)->widget()); turnPointsLbl->setText(QString::number(packet.round_points(i))); QLabel *allPointsLbl = dynamic_cast(score->itemAtPosition(1, 1)->widget()); allPointsLbl->setText(QString::number(packet.round_points(i))); } } Transmission::field_t MainWidget::translateKey(int key) { switch(key) { case Qt::Key_W: case Qt::Key_Up: return Transmission::direction_up; break; case Qt::Key_S: case Qt::Key_Down: return Transmission::direction_down; break; case Qt::Key_A: case Qt::Key_Left: return Transmission::direction_left; break; case Qt::Key_D: case Qt::Key_Right: return Transmission::direction_right; break; default: return Transmission::direction_none; } } void MainWidget::tick() { QSharedPointer data = Util::receivePacket(m_socket); bool worked = m_updatepacket.ParseFromArray(data->data(), data->size()); Q_ASSERT(worked); Q_UNUSED(worked); Transmission::map_t map = Util::createUninitialisedMap(); Q_ASSERT(m_updatepacket.field_size() == (int) (Constants::map_size.width * Constants::map_size.height)); int i = 0; for (unsigned int x = 0; x < Constants::map_size.width; ++x) { for (unsigned int y = 0; y < Constants::map_size.height; ++y) { map[x][y] = m_updatepacket.field(i); ++i; } } m_scene->updateMap(map); Util::deleteMap(map); updateScore(m_updatepacket); if (m_socket->bytesAvailable() > (qint64)sizeof(qint64)) tick(); } void MainWidget::keyPressEvent(QKeyEvent* event) { if (!m_running) return; QWidget::keyPressEvent(event); Transmission::field_t newKey = translateKey(event->key()); if (newKey == Transmission::direction_none) return; bool sendUpdate = (m_currentKey != newKey); m_currentKey = newKey; if (sendUpdate) sendKeyUpdate(); } void MainWidget::sendKeyUpdate() { if (!m_running) return; if (m_currentKey == Transmission::direction_none) return; qDebug() << "[SendKey] key=" << m_currentKey; ProtoBuf::KeyPressUpdate packet; packet.set_newkey(m_currentKey); Util::sendPacket(packet, m_socket); } void MainWidget::keyReleaseEvent(QKeyEvent* event) { if (!m_running) return; QWidget::keyReleaseEvent(event); m_currentKey = Transmission::none; return; } void MainWidget::startGame() { m_running = true; startPlayer1(); } void MainWidget::startPlayer1() { m_sirenPlayer1->play(Sound::Ambient); } void MainWidget::startPlayer2() { m_sirenPlayer2->play(Sound::Ambient); } void MainWidget::playerScoreClicked() { QGroupBox *tmp = qobject_cast(sender()); tmp->setChecked(true); return; } Color::Color MainWidget::connectToServer() { /* TODO: check command line arguments for server port */ const QStringList &args = QCoreApplication::arguments(); QString srv = args.value(1, "127.0.0.1"); qDebug() << "[Connect] server=" << srv; /* connect to server */ m_socket = new QTcpSocket(this); m_socket->connectToHost(srv, Constants::Networking::port); bool worked = m_socket->waitForConnected(Constants::Networking::connection_timeout); if (worked) { /* additional init: first packet is our color */ worked = m_socket->waitForReadyRead(); if (worked) { /* receive color */ QSharedPointer data = Util::receivePacket(m_socket); ProtoBuf::WhoAmI packet; bool worked = packet.ParseFromArray(data->data(), data->size()); Q_ASSERT(worked); Q_UNUSED(worked); return static_cast(packet.color() & Transmission::color_mask); } } return Color::none; }