From 197708500f3adaaa50bc1a5a94aec0db8ea621e5 Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 14 Apr 2011 19:18:48 +0200 Subject: add dynamic player count for client. currently works only with 1 player as server doesn't send the initial map to the clients --- pacman-c++/constants.h | 30 +++++++++++++++--------------- pacman-c++/mainwidget.cpp | 41 +++++++++++++++++++++++------------------ pacman-c++/mainwidget.h | 1 + pacman-c++/pacman.proto | 12 +++++++++--- pacman-c++/server.cpp | 18 ++++++++---------- pacman-c++/util.cpp | 7 ++++--- 6 files changed, 60 insertions(+), 49 deletions(-) (limited to 'pacman-c++') diff --git a/pacman-c++/constants.h b/pacman-c++/constants.h index 15eba86..7ce26ad 100644 --- a/pacman-c++/constants.h +++ b/pacman-c++/constants.h @@ -34,16 +34,16 @@ namespace Color { enum Color { - none = 0, - red = (1 << 0), - blue = (1 << 1), - green = (1 << 2), - max = (1 << 2), + none = 0, + red = (1 << 0), + blue = (1 << 1), + green = (1 << 2), + yellow = (1 << 3) }; /* colororder used in protocol and gui */ const Color order[] = - { Color::red, Color::blue, Color::green, Color::none }; + { Color::red, Color::blue, Color::green, Color::yellow, Color::none }; } // constants for data transmission to client @@ -53,17 +53,17 @@ namespace Transmission typedef unsigned int mask_t; const field_t none = 0; - const field_t block = (1 << 3); - const field_t point = (1 << 4); - const field_t bonuspoint = (1 << 5); - const field_t pacman = (1 << 6); - const field_t empty = (1 << 7); // explicit empty for update + const field_t block = (1 << 4); + const field_t point = (1 << 5); + const field_t bonuspoint = (1 << 6); + const field_t pacman = (1 << 7); + const field_t empty = (1 << 8); // explicit empty for update const field_t direction_none = 0; - const field_t direction_left = (1 << 8); - const field_t direction_right = (1 << 9); - const field_t direction_up = (1 << 10); - const field_t direction_down = (1 << 11); + const field_t direction_left = (1 << 9); + const field_t direction_right = (1 << 10); + const field_t direction_up = (1 << 11); + const field_t direction_down = (1 << 12); const mask_t color_mask = Color::none | Color::red | Color::blue | Color::green; const mask_t type_mask = block | bonuspoint; diff --git a/pacman-c++/mainwidget.cpp b/pacman-c++/mainwidget.cpp index 6930b1a..a77daab 100644 --- a/pacman-c++/mainwidget.cpp +++ b/pacman-c++/mainwidget.cpp @@ -6,7 +6,7 @@ #include "pacman.pb.h" MainWidget::MainWidget(QWidget *parent) - : QWidget(parent), m_currentKey(Transmission::none), m_running(false) + : QWidget(parent), m_currentKey(Transmission::none), m_running(false), m_maxplayers(0) { /* create audio player */ m_ambientPlayer = new GaplessAudioPlayer(Sound::Ambient, 100, this); @@ -54,51 +54,55 @@ void MainWidget::createGui() setFocusPolicy(Qt::StrongFocus); /* first one is always the own score */ + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setAlignment(Qt::AlignHCenter | Qt::AlignTop); QHBoxLayout *scoreLayout = new QHBoxLayout(); - for (unsigned int i = 0; Color::order[i] != Color::none ; ++i) + for (unsigned int i = 0; Color::order[i] != Color::none; ++i) { - QGroupBox *scoreBox = new QGroupBox(QString("Spieler %1").arg(i + 1), this); + QGridLayout *playerLayout = new QGridLayout(); + playerLayout->addWidget(new QLabel("Current:", this), 0, 0); + playerLayout->addWidget(new QLabel("Total:", this), 1, 0); + playerLayout->addWidget(new QLabel("0", this), 0, 1); + playerLayout->addWidget(new QLabel("0", this), 1, 1); + + QGroupBox *scoreBox = new QGroupBox(QString("Player %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); + scoreBox->setDisabled(i >= m_maxplayers); + m_playerScoreLayouts.append(playerLayout); 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); + /* add some margin to scorebox hopefully won't resize the window */ + //setMinimumWidth(scoreLayout->minimumSize().width() + 50); 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); + layout->addWidget(window, 0, Qt::AlignCenter); QFile css(":/stylesheet"); css.open(QFile::ReadOnly); qApp->setStyleSheet(QLatin1String(css.readAll())); + /* add dummy layout at the end which gets streched when resizing */ + QHBoxLayout *spacer = new QHBoxLayout(); + layout->addLayout(spacer, 10); + setLayout(layout); } void MainWidget::updateScore(const ProtoBuf::MapUpdate& packet) { - for(unsigned i = 0; Color::order[i] != Color::none; ++i) + for(unsigned i = 0; i < m_maxplayers; ++i) { QGridLayout *score = m_playerScoreLayouts.at(i); QLabel *turnPointsLbl = dynamic_cast(score->itemAtPosition(0, 1)->widget()); @@ -233,10 +237,11 @@ Color::Color MainWidget::connectToServer() { /* receive color */ QSharedPointer data = Util::receivePacket(m_socket); - ProtoBuf::WhoAmI packet; + ProtoBuf::Init packet; bool worked = packet.ParseFromArray(data->data(), data->size()); Q_ASSERT(worked); Q_UNUSED(worked); + m_maxplayers = packet.maxplayers(); return static_cast(packet.color() & Transmission::color_mask); } } diff --git a/pacman-c++/mainwidget.h b/pacman-c++/mainwidget.h index 6ecd812..ef282c1 100644 --- a/pacman-c++/mainwidget.h +++ b/pacman-c++/mainwidget.h @@ -54,6 +54,7 @@ private: QTcpSocket *m_socket; SceneHolder *m_scene; + unsigned int m_maxplayers; /* allocate as member variable as this packet is large and used often */ ProtoBuf::MapUpdate m_updatepacket; diff --git a/pacman-c++/pacman.proto b/pacman-c++/pacman.proto index 98478a0..51bb239 100644 --- a/pacman-c++/pacman.proto +++ b/pacman-c++/pacman.proto @@ -4,12 +4,18 @@ message KeyPressUpdate { required uint32 newKey = 1; } +message Init { + required uint32 color = 1; + required uint32 maxplayers = 2; +} + +message MapInit { + repeated uint32 field = 1 [packed=true]; +} + message MapUpdate { repeated uint32 field = 1 [packed=true]; repeated uint32 round_points = 2; repeated uint32 game_points = 3; } -message WhoAmI { - required uint32 color = 1; -} diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp index 50ee3b7..e09d126 100644 --- a/pacman-c++/server.cpp +++ b/pacman-c++/server.cpp @@ -17,6 +17,9 @@ Server::Server(QWidget *parent) bool Server::run() { + qDebug() << "[Server] Running server..."; + qDebug() << "[Server] Max players:" << m_maxplayers; + qDebug() << "[Server] Number of bots:" << m_numbots; if (!waitForClientConnections()) return false; @@ -164,20 +167,14 @@ bool Server::waitForClientConnections() qCritical() << "Error while creating socket:" << qPrintable(tcpSrv->errorString()); return false; } - qDebug() << "[Server] Listening on:" << qPrintable(QString("%1:%2").arg(tcpSrv->serverAddress().toString()) .arg(tcpSrv->serverPort())); + qDebug() << "[Server] Waiting for clients"; - ProtoBuf::WhoAmI packet; -#define SINGLE -#ifdef SINGLE - for (unsigned int i = 0; i < 1; ++i) - { -#else - for (unsigned int i = 0; Color::order[i] != Color::none; ++i) + ProtoBuf::Init packet; + for (unsigned int i = 0; i < m_maxplayers; ++i) { -#endif bool connectionAvailable = tcpSrv->waitForNewConnection(-1); Q_ASSERT(connectionAvailable); Q_UNUSED(connectionAvailable); @@ -189,6 +186,7 @@ bool Server::waitForClientConnections() m_clientConnections[color] = socket; /* notify player of color */ packet.set_color(color); + packet.set_maxplayers(m_maxplayers); Util::sendPacket(packet, socket); qDebug() << "[Connect] New Player: color=" << color; @@ -208,7 +206,7 @@ void Server::sendUpdate(Transmission::map_t map) m_updatepacket.add_field(map[x][y]); } - for(unsigned i = 0; Color::order[i] != Color::none; ++i) + for(unsigned i = 0; i < m_maxplayers; ++i) { m_updatepacket.add_round_points(m_actors.value(Color::order[i])->getRoundPoints()); m_updatepacket.add_game_points(m_actors.value(Color::order[i])->getGamePoints()); diff --git a/pacman-c++/util.cpp b/pacman-c++/util.cpp index 2fb9f69..eaf18e4 100644 --- a/pacman-c++/util.cpp +++ b/pacman-c++/util.cpp @@ -75,9 +75,10 @@ namespace Util } map[0][0] |= Transmission::bonuspoint; - map[1][0] |= Color::red | Transmission::pacman | Transmission::direction_right; - map[23][0] = Color::blue | Transmission::pacman | Transmission::direction_none; - map[24][0] = Color::green | Transmission::pacman | Transmission::direction_none; + map[1][0] |= Color::red | Transmission::pacman | Transmission::direction_right; + //map[23][0] = Color::blue | Transmission::pacman | Transmission::direction_none; + //map[24][0] = Color::green | Transmission::pacman | Transmission::direction_none; + //map[25][0] = Color::yellow | Transmission::pacman | Transmission::direction_none; /* auto place normal points*/ for (unsigned int x = 0; x < Constants::map_size.width; ++x) -- cgit v1.2.3