summaryrefslogtreecommitdiffstats
path: root/pacman-c++/mainwidget.cpp
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2011-05-05 00:57:07 +0200
committermanuel <manuel@mausz.at>2011-05-05 00:57:07 +0200
commitce48af53646cd9e7ec762fc1ac176b3aa620b11d (patch)
treef8fbf2cae8c7d0cbac2696a8f4cf94410bfb4928 /pacman-c++/mainwidget.cpp
parente54ccad07e256ba877bd41d70bd358bd0085bd1e (diff)
downloadfoop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.tar.gz
foop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.tar.bz2
foop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.zip
- refactorized the whole project and made a few subprojects
- replaced tcp with enet - added connect dialog - some smaller bugfixes
Diffstat (limited to 'pacman-c++/mainwidget.cpp')
-rw-r--r--pacman-c++/mainwidget.cpp279
1 files changed, 0 insertions, 279 deletions
diff --git a/pacman-c++/mainwidget.cpp b/pacman-c++/mainwidget.cpp
deleted file mode 100644
index 49ddf7a..0000000
--- a/pacman-c++/mainwidget.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
1#include "mainwidget.h"
2#include "actor.h"
3#include "block.h"
4#include "constants.h"
5#include "util.h"
6#include "pacman.pb.h"
7#include <QStringBuilder>
8
9MainWidget::MainWidget(QWidget *parent)
10 : QWidget(parent), m_currentKey(Transmission::none), m_running(false), m_scene(NULL),
11 m_maxplayers(0)
12{
13 /* create audio player */
14 m_ambientPlayer = new GaplessAudioPlayer(Sound::Ambient, 100, this);
15
16 Color::Color color = connectToServer();
17 if (color == Color::none)
18 {
19 QMessageBox::critical(this, "Error", "Failed to connect to server, falling back to local test mode");
20 // TODO: quit application here or sth
21 return;
22 }
23
24 /* create our scene */
25 m_scene = new SceneHolder(this);
26 m_scene->setColor(color);
27
28 /* call updateMap after m_color ist set! */
29 createGui();
30
31 /* wait for the server to send the first map update (initial map)
32 * WARNING: this will block the gui
33 */
34 m_socket->waitForReadyRead(-1);
35 tick();
36
37 qDebug() << "[Connect] mycolor=" << m_scene->color();
38 connect(m_socket, SIGNAL(readyRead()), this, SLOT(tick()));
39}
40
41bool MainWidget::connected()
42{
43 return m_socket != NULL;
44}
45
46void MainWidget::createGui()
47{
48 setFocusPolicy(Qt::StrongFocus);
49
50 /* first one is always the own score */
51 QVBoxLayout *layout = new QVBoxLayout(this);
52 layout->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
53 QHBoxLayout *scoreLayout = new QHBoxLayout();
54 for (unsigned int i = 0; i < m_maxplayers; ++i)
55 {
56 QGridLayout *playerLayout = new QGridLayout();
57 playerLayout->addWidget(new QLabel("Current:", this), 0, 0);
58 playerLayout->addWidget(new QLabel("Total:", this), 1, 0);
59 playerLayout->addWidget(new QLabel("0", this), 0, 1, Qt::AlignLeft);
60 playerLayout->addWidget(new QLabel("0", this), 1, 1, Qt::AlignLeft);
61 playerLayout->setColumnStretch(1, 10);
62 playerLayout->setSizeConstraint(QLayout::SetMinimumSize);
63
64 QGroupBox *scoreBox = new QGroupBox(QString("Player %1").arg(i + 1), this);
65 scoreBox->setObjectName(QString("actor%1").arg(i + 1));
66 scoreBox->setCheckable(true);
67 scoreBox->setDisabled(i >= m_maxplayers);
68 connect(scoreBox, SIGNAL(clicked()), this, SLOT(playerScoreClicked()));
69
70 scoreBox->setLayout(playerLayout);
71 m_playerScoreLayouts.append(playerLayout);
72
73 if (Color::order[i] == m_scene->color())
74 scoreLayout->insertWidget(0, scoreBox);
75 else
76 scoreLayout->addWidget(scoreBox);
77 }
78 layout->addLayout(scoreLayout);
79
80 QGraphicsView *window = new QGraphicsView(m_scene, this);
81 window->setFrameStyle(0);
82 window->setFixedSize(m_scene->sceneRect().size().toSize());
83 window->setWindowFlags(window->windowFlags() & ~Qt::WindowMaximizeButtonHint);
84 window->setFocusPolicy(Qt::NoFocus);
85 layout->addWidget(window, 0, Qt::AlignCenter);
86
87 QFile css(":/stylesheet");
88 css.open(QFile::ReadOnly);
89 qApp->setStyleSheet(QLatin1String(css.readAll()));
90
91 /* add dummy layout at the end which gets streched when resizing */
92 QHBoxLayout *spacer = new QHBoxLayout();
93 layout->addLayout(spacer, 10);
94
95 setLayout(layout);
96}
97
98void MainWidget::updateScore(const ProtoBuf::MapUpdate& packet)
99{
100 for(unsigned i = 0; i < m_maxplayers; ++i)
101 {
102 QGridLayout *score = m_playerScoreLayouts.at(i);
103 QLabel *turnPointsLbl = dynamic_cast<QLabel *>(score->itemAtPosition(0, 1)->widget());
104 turnPointsLbl->setText(QString::number(packet.round_points(i)));
105
106 QLabel *allPointsLbl = dynamic_cast<QLabel *>(score->itemAtPosition(1, 1)->widget());
107 allPointsLbl->setText(QString::number(packet.game_points(i)));
108 }
109}
110
111Transmission::field_t MainWidget::translateKey(int key)
112{
113 switch(key)
114 {
115 case Qt::Key_W:
116 case Qt::Key_Up:
117 return Transmission::direction_up;
118 break;
119 case Qt::Key_S:
120 case Qt::Key_Down:
121 return Transmission::direction_down;
122 break;
123 case Qt::Key_A:
124 case Qt::Key_Left:
125 return Transmission::direction_left;
126 break;
127 case Qt::Key_D:
128 case Qt::Key_Right:
129 return Transmission::direction_right;
130 break;
131 default:
132 return Transmission::direction_none;
133 }
134}
135
136void MainWidget::tick()
137{
138 while (m_socket->bytesAvailable() > (qint64)sizeof(qint64))
139 {
140 QSharedPointer<QByteArray> data = Util::receivePacket(m_socket);
141 bool worked = m_updatepacket.ParseFromArray(data->data(), data->size());
142 Q_ASSERT(worked);
143 Q_UNUSED(worked);
144
145 /* eating order data set indicates a new round */
146 if (m_updatepacket.eating_order_size() > 0)
147 {
148 Q_ASSERT(m_scene != NULL);
149 m_scene->reset();
150
151 /* fetch eating order */
152 QList<Color::Color> order;
153 for(int i = 0; i < m_updatepacket.eating_order_size(); ++i)
154 order.append(static_cast<Color::Color>(m_updatepacket.eating_order(i) & Transmission::color_mask));
155 m_scene->setEatingOrder(order);
156
157 /* stop game */
158 stopGame();
159
160 /* and restart game */
161 QTimer *timer = new QTimer(this);
162 timer->setSingleShot(true);
163 timer->setInterval(Sound::length[Sound::Intro] + Constants::tick);
164 connect(timer, SIGNAL(timeout()), this, SLOT(startGame()));
165 timer->start();
166 AudioManager::self()->play(Sound::Intro, true);
167 }
168
169 Transmission::map_t map = Util::createUninitialisedMap();
170 Q_ASSERT(m_updatepacket.field_size() == (int) (Constants::map_size.width * Constants::map_size.height));
171 int i = 0;
172 for (unsigned int x = 0; x < Constants::map_size.width; ++x)
173 {
174 for (unsigned int y = 0; y < Constants::map_size.height; ++y)
175 {
176 map[x][y] = m_updatepacket.field(i);
177 ++i;
178 }
179 }
180 m_scene->updateMap(map);
181 Util::deleteMap(map);
182 updateScore(m_updatepacket);
183
184 if (m_updatepacket.eating_order_size() > 0)
185 m_scene->showEatingText();
186 }
187}
188
189void MainWidget::keyPressEvent(QKeyEvent* event)
190{
191 if (event->isAutoRepeat())
192 return;
193
194 QWidget::keyPressEvent(event);
195 Transmission::field_t newKey = translateKey(event->key());
196 if (newKey == Transmission::direction_none)
197 return;
198 bool sendUpdate = (m_currentKey != newKey);
199 m_currentKey = newKey;
200 if (sendUpdate)
201 sendKeyUpdate();
202}
203
204void MainWidget::sendKeyUpdate()
205{
206 if (m_currentKey == Transmission::direction_none)
207 return;
208 qDebug() << "[SendKey] key=" << m_currentKey;
209 ProtoBuf::KeyPressUpdate packet;
210 packet.set_newkey(m_currentKey);
211 Util::sendPacket(packet, m_socket);
212}
213
214void MainWidget::keyReleaseEvent(QKeyEvent* event)
215{
216 if (event->isAutoRepeat())
217 return;
218
219 QWidget::keyReleaseEvent(event);
220 m_currentKey = Transmission::none;
221 return;
222}
223
224void MainWidget::startGame()
225{
226 disconnect(AudioManager::self()->audioPlayer(), NULL, this, SLOT(startGame()));
227 m_scene->showEatingText(false);
228 m_running = true;
229 sendKeyUpdate();
230 m_ambientPlayer->play();
231}
232
233void MainWidget::stopGame()
234{
235 m_running = false;
236 m_ambientPlayer->pause();
237}
238
239void MainWidget::setAmbientMuted(bool muted)
240{
241 m_ambientPlayer->setMuted(muted);
242}
243
244void MainWidget::playerScoreClicked()
245{
246 QGroupBox *tmp = qobject_cast<QGroupBox *>(sender());
247 tmp->setChecked(true);
248 return;
249}
250
251Color::Color MainWidget::connectToServer()
252{
253 /* TODO: check command line arguments for server port */
254 const QStringList &args = QCoreApplication::arguments();
255 QString srv = args.value(1, "127.0.0.1");
256 qDebug() << "[Connect] server=" << srv;
257
258 /* connect to server */
259 m_socket = new QTcpSocket(this);
260 m_socket->connectToHost(srv, Constants::Networking::port);
261 bool worked = m_socket->waitForConnected(Constants::Networking::connection_timeout);
262 if (worked)
263 {
264 /* additional init: first packet is our color */
265 worked = m_socket->waitForReadyRead();
266 if (worked)
267 {
268 /* receive color */
269 QSharedPointer<QByteArray> data = Util::receivePacket(m_socket);
270 ProtoBuf::Init packet;
271 bool worked = packet.ParseFromArray(data->data(), data->size());
272 Q_ASSERT(worked);
273 Q_UNUSED(worked);
274 m_maxplayers = packet.maxplayers();
275 return static_cast<Color::Color>(packet.color() & Transmission::color_mask);
276 }
277 }
278 return Color::none;
279}