diff options
| author | manuel <manuel@mausz.at> | 2011-04-25 14:39:00 +0200 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2011-04-25 14:39:00 +0200 |
| commit | 41a31420cf091aeb4e986503387855d41e550106 (patch) | |
| tree | ffbe0be5f9630a0bab2deb0b5df37c174bf40db1 /pacman-c++ | |
| parent | bbd2a69a962d15f74a4afcb7b66462eac9fa5008 (diff) | |
| download | foop-41a31420cf091aeb4e986503387855d41e550106.tar.gz foop-41a31420cf091aeb4e986503387855d41e550106.tar.bz2 foop-41a31420cf091aeb4e986503387855d41e550106.zip | |
- add intro sound on every round
- add dieing sound
- add dieing animation
- add die on moving onto colorized block
Diffstat (limited to 'pacman-c++')
| -rw-r--r-- | pacman-c++/actor.cpp | 49 | ||||
| -rw-r--r-- | pacman-c++/actor.h | 7 | ||||
| -rw-r--r-- | pacman-c++/audio.cpp | 54 | ||||
| -rw-r--r-- | pacman-c++/audio.h | 9 | ||||
| -rw-r--r-- | pacman-c++/block.cpp | 19 | ||||
| -rw-r--r-- | pacman-c++/block.h | 3 | ||||
| -rw-r--r-- | pacman-c++/bonuspoint.cpp | 5 | ||||
| -rw-r--r-- | pacman-c++/bonuspoint.h | 2 | ||||
| -rw-r--r-- | pacman-c++/constants.h | 9 | ||||
| -rw-r--r-- | pacman-c++/gameentity.cpp | 4 | ||||
| -rw-r--r-- | pacman-c++/gameentity.h | 20 | ||||
| -rw-r--r-- | pacman-c++/mainwidget.cpp | 29 | ||||
| -rw-r--r-- | pacman-c++/mainwidget.h | 1 | ||||
| -rw-r--r-- | pacman-c++/pics/actor1.png | bin | 796 -> 1231 bytes | |||
| -rw-r--r-- | pacman-c++/pics/actor2.png | bin | 805 -> 1257 bytes | |||
| -rw-r--r-- | pacman-c++/pics/actor3.png | bin | 793 -> 1226 bytes | |||
| -rw-r--r-- | pacman-c++/pics/actor4.png | bin | 804 -> 1536 bytes | |||
| -rw-r--r-- | pacman-c++/point.cpp | 5 | ||||
| -rw-r--r-- | pacman-c++/point.h | 2 | ||||
| -rw-r--r-- | pacman-c++/sceneholder.cpp | 76 | ||||
| -rw-r--r-- | pacman-c++/sceneholder.h | 4 | ||||
| -rw-r--r-- | pacman-c++/server.cpp | 143 | ||||
| -rw-r--r-- | pacman-c++/server.h | 9 |
23 files changed, 286 insertions, 164 deletions
diff --git a/pacman-c++/actor.cpp b/pacman-c++/actor.cpp index c8922f7..2dced34 100644 --- a/pacman-c++/actor.cpp +++ b/pacman-c++/actor.cpp | |||
| @@ -57,6 +57,29 @@ Actor::Actor(Color::Color color, bool local, QGraphicsItem *parent) | |||
| 57 | m_eating.append(setupEatingAnimation(Actor::Up)); | 57 | m_eating.append(setupEatingAnimation(Actor::Up)); |
| 58 | m_eating.append(setupEatingAnimation(Actor::Down)); | 58 | m_eating.append(setupEatingAnimation(Actor::Down)); |
| 59 | 59 | ||
| 60 | /* dieing animation */ | ||
| 61 | m_dieing = new QSequentialAnimationGroup(this); | ||
| 62 | for (int i = 0; i < 11; i++) | ||
| 63 | { | ||
| 64 | PixmapItem *img = new PixmapItem(m_pix, this); | ||
| 65 | m_images.append(img); | ||
| 66 | int x = i * Constants::sprite_offset + Constants::sprite_margin; | ||
| 67 | int y = 5 * Constants::sprite_offset + Constants::sprite_margin; | ||
| 68 | img->setSprite(x, y, Constants::field_size.width, Constants::field_size.height); | ||
| 69 | img->setZValue(zValue()); | ||
| 70 | img->setVisible(false); | ||
| 71 | |||
| 72 | QPropertyAnimation *fadein = new QPropertyAnimation(img, "visible", m_dieing); | ||
| 73 | fadein->setDuration(0); | ||
| 74 | fadein->setEndValue(true); | ||
| 75 | |||
| 76 | m_dieing->addPause(130); | ||
| 77 | |||
| 78 | QPropertyAnimation *fadeout = new QPropertyAnimation(img, "visible", m_dieing); | ||
| 79 | fadeout->setDuration(0); | ||
| 80 | fadeout->setEndValue(false); | ||
| 81 | } | ||
| 82 | |||
| 60 | /* setup waka sound */ | 83 | /* setup waka sound */ |
| 61 | if (local) | 84 | if (local) |
| 62 | m_wakaPlayer = new GaplessAudioPlayer(Sound::WakaWaka, 100, this); | 85 | m_wakaPlayer = new GaplessAudioPlayer(Sound::WakaWaka, 100, this); |
| @@ -112,11 +135,21 @@ bool Actor::isLocal() | |||
| 112 | return m_local; | 135 | return m_local; |
| 113 | } | 136 | } |
| 114 | 137 | ||
| 115 | void Actor::resetDirection() | 138 | void Actor::resetAnimation() |
| 116 | { | 139 | { |
| 140 | if (Constants::server) | ||
| 141 | return; | ||
| 142 | |||
| 143 | stopEating(); | ||
| 144 | m_moving->stop(); | ||
| 145 | m_dieing->stop(); | ||
| 117 | /* hide all pictures */ | 146 | /* hide all pictures */ |
| 118 | for (int i = 0; i < m_images.size(); ++i) | 147 | for (int i = 0; i < m_images.size(); ++i) |
| 119 | m_images.at(i)->setVisible(false); | 148 | m_images.at(i)->setVisible(false); |
| 149 | |||
| 150 | if (m_eating[m_direction] != NULL) | ||
| 151 | m_eating[m_direction]->stop(); | ||
| 152 | |||
| 120 | m_direction = Actor::None; | 153 | m_direction = Actor::None; |
| 121 | m_images[m_direction]->setVisible(true); | 154 | m_images[m_direction]->setVisible(true); |
| 122 | } | 155 | } |
| @@ -213,9 +246,14 @@ bool Actor::canEat(Actor *other, const QList<Color::Color> &order) | |||
| 213 | 246 | ||
| 214 | void Actor::die() | 247 | void Actor::die() |
| 215 | { | 248 | { |
| 216 | if (!m_local) | 249 | if (Constants::server) |
| 217 | return; | 250 | return; |
| 218 | AudioManager::self()->play(Sound::Die); | 251 | |
| 252 | resetAnimation(); | ||
| 253 | m_images[m_direction]->setVisible(false); | ||
| 254 | m_dieing->start(); | ||
| 255 | if (m_local) | ||
| 256 | AudioManager::self()->play(Sound::Die); | ||
| 219 | } | 257 | } |
| 220 | 258 | ||
| 221 | void Actor::eatingFruit() | 259 | void Actor::eatingFruit() |
| @@ -261,9 +299,10 @@ void Actor::addRoundPoints(unsigned int amount) | |||
| 261 | m_roundPoints += amount; | 299 | m_roundPoints += amount; |
| 262 | } | 300 | } |
| 263 | 301 | ||
| 264 | void Actor::finishRound() | 302 | void Actor::finishRound(bool died) |
| 265 | { | 303 | { |
| 266 | m_gamePoints += m_roundPoints; | 304 | if (!died) |
| 305 | m_gamePoints += m_roundPoints; | ||
| 267 | m_roundPoints = 0; | 306 | m_roundPoints = 0; |
| 268 | } | 307 | } |
| 269 | 308 | ||
diff --git a/pacman-c++/actor.h b/pacman-c++/actor.h index 389d7c6..eb04c71 100644 --- a/pacman-c++/actor.h +++ b/pacman-c++/actor.h | |||
| @@ -16,7 +16,7 @@ Q_OBJECT | |||
| 16 | public: | 16 | public: |
| 17 | enum Movement | 17 | enum Movement |
| 18 | { | 18 | { |
| 19 | None = 0, | 19 | None = 0, |
| 20 | Left, | 20 | Left, |
| 21 | Right, | 21 | Right, |
| 22 | Up, | 22 | Up, |
| @@ -34,7 +34,7 @@ public: | |||
| 34 | 34 | ||
| 35 | PixmapItem &icon(); | 35 | PixmapItem &icon(); |
| 36 | Movement direction(); | 36 | Movement direction(); |
| 37 | void resetDirection(); | 37 | void resetAnimation(); |
| 38 | bool isLocal(); | 38 | bool isLocal(); |
| 39 | void move(Movement direction); | 39 | void move(Movement direction); |
| 40 | bool isMoving(); | 40 | bool isMoving(); |
| @@ -48,7 +48,7 @@ public: | |||
| 48 | unsigned int getRoundPoints(); | 48 | unsigned int getRoundPoints(); |
| 49 | unsigned int getGamePoints(); | 49 | unsigned int getGamePoints(); |
| 50 | void addRoundPoints(unsigned int amount); | 50 | void addRoundPoints(unsigned int amount); |
| 51 | void finishRound(); | 51 | void finishRound(bool died = false); |
| 52 | 52 | ||
| 53 | static QPoint movementToPoint(const Actor::Movement direction); | 53 | static QPoint movementToPoint(const Actor::Movement direction); |
| 54 | 54 | ||
| @@ -69,6 +69,7 @@ private: | |||
| 69 | QList<PixmapItem *> m_images; | 69 | QList<PixmapItem *> m_images; |
| 70 | QList<QSequentialAnimationGroup *> m_eating; | 70 | QList<QSequentialAnimationGroup *> m_eating; |
| 71 | QParallelAnimationGroup *m_moving; | 71 | QParallelAnimationGroup *m_moving; |
| 72 | QSequentialAnimationGroup *m_dieing; | ||
| 72 | }; | 73 | }; |
| 73 | 74 | ||
| 74 | #endif // ACTOR_H | 75 | #endif // ACTOR_H |
diff --git a/pacman-c++/audio.cpp b/pacman-c++/audio.cpp index d627c75..5fb4416 100644 --- a/pacman-c++/audio.cpp +++ b/pacman-c++/audio.cpp | |||
| @@ -15,18 +15,19 @@ AudioManager::AudioManager() | |||
| 15 | : m_muted(true) | 15 | : m_muted(true) |
| 16 | { | 16 | { |
| 17 | if (Constants::server) | 17 | if (Constants::server) |
| 18 | { | ||
| 18 | qDebug() << "Server has no sound"; | 19 | qDebug() << "Server has no sound"; |
| 20 | m_players.append(new AudioPlayer(this)); | ||
| 21 | } | ||
| 19 | else | 22 | else |
| 20 | { | 23 | { |
| 21 | preload(); | 24 | preload(); |
| 22 | |||
| 23 | AudioPlayer *firstplayer = new AudioPlayer(this); | 25 | AudioPlayer *firstplayer = new AudioPlayer(this); |
| 24 | firstplayer->test(m_sounds[Sound::WakaWaka]); | 26 | firstplayer->test(m_sounds[Sound::WakaWaka]); |
| 25 | m_working = firstplayer->m_working; | 27 | m_working = firstplayer->m_working; |
| 26 | m_players.append(firstplayer); | 28 | m_players.append(firstplayer); |
| 27 | |||
| 28 | m_muted = false; | ||
| 29 | } | 29 | } |
| 30 | m_muted = false; | ||
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | AudioManager *AudioManager::self() | 33 | AudioManager *AudioManager::self() |
| @@ -97,15 +98,9 @@ AudioPlayer *AudioManager::audioPlayer() | |||
| 97 | return m_players.at(0); | 98 | return m_players.at(0); |
| 98 | } | 99 | } |
| 99 | 100 | ||
| 100 | void AudioManager::play(Sound::Type sound) | 101 | void AudioManager::play(Sound::Type sound, bool wait) |
| 101 | { | 102 | { |
| 102 | if (!isWorking()) | 103 | audioPlayer()->play(sound, wait); |
| 103 | { | ||
| 104 | emit audioPlayer()->finished(); | ||
| 105 | return; | ||
| 106 | } | ||
| 107 | |||
| 108 | audioPlayer()->play(sound); | ||
| 109 | } | 104 | } |
| 110 | 105 | ||
| 111 | void AudioManager::enqueue(Sound::Type sound) | 106 | void AudioManager::enqueue(Sound::Type sound) |
| @@ -151,11 +146,14 @@ QFile *AudioManager::sound(Sound::Type sound) | |||
| 151 | /* --------------------------------------------------------------- */ | 146 | /* --------------------------------------------------------------- */ |
| 152 | 147 | ||
| 153 | AudioPlayer::AudioPlayer(QObject *parent) | 148 | AudioPlayer::AudioPlayer(QObject *parent) |
| 154 | : Phonon::MediaObject(parent) | 149 | : Phonon::MediaObject(parent), m_working(false) |
| 155 | { | 150 | { |
| 156 | m_working = AudioManager::m_working; | 151 | if (!Constants::server) |
| 157 | m_output = new Phonon::AudioOutput(Phonon::MusicCategory, this); | 152 | { |
| 158 | Phonon::createPath(this, m_output); | 153 | m_working = AudioManager::m_working; |
| 154 | m_output = new Phonon::AudioOutput(Phonon::MusicCategory, this); | ||
| 155 | Phonon::createPath(this, m_output); | ||
| 156 | } | ||
| 159 | } | 157 | } |
| 160 | 158 | ||
| 161 | bool AudioPlayer::isWorking() const | 159 | bool AudioPlayer::isWorking() const |
| @@ -200,10 +198,25 @@ void AudioPlayer::play() | |||
| 200 | Phonon::MediaObject::play(); | 198 | Phonon::MediaObject::play(); |
| 201 | } | 199 | } |
| 202 | 200 | ||
| 203 | void AudioPlayer::play(Sound::Type sound) | 201 | void AudioPlayer::play(Sound::Type sound, bool wait) |
| 204 | { | 202 | { |
| 205 | setCurrentSource(Phonon::MediaSource(AudioManager::self()->sound(sound))); | 203 | if (m_working) |
| 206 | play(); | 204 | { |
| 205 | setCurrentSource(Phonon::MediaSource(AudioManager::self()->sound(sound))); | ||
| 206 | play(); | ||
| 207 | } | ||
| 208 | else if (wait) | ||
| 209 | { | ||
| 210 | QTimer *timer = new QTimer(this); | ||
| 211 | timer->setSingleShot(true); | ||
| 212 | unsigned int interval = Sound::length[sound]; | ||
| 213 | /* add a small delay server side only */ | ||
| 214 | if (Constants::server) | ||
| 215 | interval += Constants::tick; | ||
| 216 | timer->setInterval(interval); | ||
| 217 | connect(timer, SIGNAL(timeout()), this, SLOT(finished_ex())); | ||
| 218 | timer->start(); | ||
| 219 | } | ||
| 207 | } | 220 | } |
| 208 | 221 | ||
| 209 | /* this is a simple hack to check if phonon can actually play sounds.. */ | 222 | /* this is a simple hack to check if phonon can actually play sounds.. */ |
| @@ -227,6 +240,11 @@ void AudioPlayer::test(QFile *testsound) | |||
| 227 | clear(); | 240 | clear(); |
| 228 | } | 241 | } |
| 229 | 242 | ||
| 243 | void AudioPlayer::finished_ex() | ||
| 244 | { | ||
| 245 | emit finished(); | ||
| 246 | } | ||
| 247 | |||
| 230 | void AudioPlayer::stateChanged_ex(Phonon::State newstate, Phonon::State /* oldstate */) | 248 | void AudioPlayer::stateChanged_ex(Phonon::State newstate, Phonon::State /* oldstate */) |
| 231 | { | 249 | { |
| 232 | if (newstate != Phonon::ErrorState) | 250 | if (newstate != Phonon::ErrorState) |
diff --git a/pacman-c++/audio.h b/pacman-c++/audio.h index 3e76f50..9a4feec 100644 --- a/pacman-c++/audio.h +++ b/pacman-c++/audio.h | |||
| @@ -23,6 +23,10 @@ namespace Sound | |||
| 23 | Die, | 23 | Die, |
| 24 | Ambient | 24 | Ambient |
| 25 | }; | 25 | }; |
| 26 | |||
| 27 | const unsigned int length[] = { | ||
| 28 | 4310, 2090, 570, 570, 1720 | ||
| 29 | }; | ||
| 26 | }; | 30 | }; |
| 27 | 31 | ||
| 28 | /* --------------------------------------------------------------- */ | 32 | /* --------------------------------------------------------------- */ |
| @@ -50,7 +54,7 @@ public: | |||
| 50 | bool isMuted() const; | 54 | bool isMuted() const; |
| 51 | void setLoop(Sound::Type sound); | 55 | void setLoop(Sound::Type sound); |
| 52 | void play(); | 56 | void play(); |
| 53 | void play(Sound::Type sound); | 57 | void play(Sound::Type sound, bool wait = false); |
| 54 | 58 | ||
| 55 | protected: | 59 | protected: |
| 56 | void test(QFile *testsound); | 60 | void test(QFile *testsound); |
| @@ -60,6 +64,7 @@ public slots: | |||
| 60 | void loopEnqueue(); | 64 | void loopEnqueue(); |
| 61 | 65 | ||
| 62 | protected slots: | 66 | protected slots: |
| 67 | void finished_ex(); | ||
| 63 | void testFinished(); | 68 | void testFinished(); |
| 64 | void stateChanged_ex(Phonon::State newstate, Phonon::State oldstate); | 69 | void stateChanged_ex(Phonon::State newstate, Phonon::State oldstate); |
| 65 | 70 | ||
| @@ -116,7 +121,7 @@ public: | |||
| 116 | void clearQueue() const; | 121 | void clearQueue() const; |
| 117 | 122 | ||
| 118 | AudioPlayer *audioPlayer(); | 123 | AudioPlayer *audioPlayer(); |
| 119 | void play(Sound::Type sound); | 124 | void play(Sound::Type sound, bool wait = false); |
| 120 | void enqueue(Sound::Type sound); | 125 | void enqueue(Sound::Type sound); |
| 121 | 126 | ||
| 122 | void registerAudioPlayer(AudioPlayer *player); | 127 | void registerAudioPlayer(AudioPlayer *player); |
diff --git a/pacman-c++/block.cpp b/pacman-c++/block.cpp index 68dd735..7f9dd14 100644 --- a/pacman-c++/block.cpp +++ b/pacman-c++/block.cpp | |||
| @@ -36,18 +36,21 @@ void Block::setNeighbours(unsigned int neighbours) | |||
| 36 | setSprite(neighbours * Constants::sprite_offset, 0, Constants::field_size.width, Constants::field_size.height); | 36 | setSprite(neighbours * Constants::sprite_offset, 0, Constants::field_size.width, Constants::field_size.height); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | bool Block::checkEnter(Actor *actor) | 39 | bool Block::checkEnter(Actor * /* actor */) |
| 40 | { | 40 | { |
| 41 | if (m_color == Color::none) | 41 | if (m_color == Color::none) |
| 42 | return false; | 42 | return false; |
| 43 | return (m_color == actor->color()); | 43 | return true; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | bool Block::enter(Actor *actor) | 46 | GameEntity::EnteredState Block::enter(Actor *actor) |
| 47 | { | 47 | { |
| 48 | if (m_color != actor->color()) | 48 | if (m_color != Color::none && m_color != actor->color()) |
| 49 | { | 49 | return DestroyedActor; |
| 50 | //TODO: actor dies + game ends | 50 | return Nothing; |
| 51 | } | 51 | } |
| 52 | return true; | 52 | |
| 53 | void Block::onDie(Actor *actor) | ||
| 54 | { | ||
| 55 | actor->die(); | ||
| 53 | } | 56 | } |
diff --git a/pacman-c++/block.h b/pacman-c++/block.h index 2e47646..abfbc5a 100644 --- a/pacman-c++/block.h +++ b/pacman-c++/block.h | |||
| @@ -31,7 +31,8 @@ public: | |||
| 31 | unsigned int neighbours(); | 31 | unsigned int neighbours(); |
| 32 | void setNeighbours(unsigned int neighbours); | 32 | void setNeighbours(unsigned int neighbours); |
| 33 | virtual bool checkEnter(Actor *actor); | 33 | virtual bool checkEnter(Actor *actor); |
| 34 | virtual bool enter(Actor *actor); | 34 | virtual EnteredState enter(Actor *actor); |
| 35 | virtual void onDie(Actor *); | ||
| 35 | 36 | ||
| 36 | private: | 37 | private: |
| 37 | // map for saving QPixmaps for reuse | 38 | // map for saving QPixmaps for reuse |
diff --git a/pacman-c++/bonuspoint.cpp b/pacman-c++/bonuspoint.cpp index c90cccc..a6736c4 100644 --- a/pacman-c++/bonuspoint.cpp +++ b/pacman-c++/bonuspoint.cpp | |||
| @@ -26,11 +26,10 @@ BonusPoint::BonusPoint(QGraphicsItem *parent) | |||
| 26 | setSprite(rand * 20 + Constants::sprite_margin, Constants::sprite_margin, Constants::field_size.width, Constants::field_size.height); | 26 | setSprite(rand * 20 + Constants::sprite_margin, Constants::sprite_margin, Constants::field_size.width, Constants::field_size.height); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | bool BonusPoint::enter(Actor *actor) | 29 | GameEntity::EnteredState BonusPoint::enter(Actor *actor) |
| 30 | { | 30 | { |
| 31 | actor->addRoundPoints(Constants::Game::bonus_point_value); | 31 | actor->addRoundPoints(Constants::Game::bonus_point_value); |
| 32 | m_eaten = true; | 32 | return DestroyedEntity; |
| 33 | return false; | ||
| 34 | } | 33 | } |
| 35 | 34 | ||
| 36 | void BonusPoint::onDie(Actor *actor) | 35 | void BonusPoint::onDie(Actor *actor) |
diff --git a/pacman-c++/bonuspoint.h b/pacman-c++/bonuspoint.h index fbb5ba2..a72a4db 100644 --- a/pacman-c++/bonuspoint.h +++ b/pacman-c++/bonuspoint.h | |||
| @@ -17,7 +17,7 @@ public: | |||
| 17 | virtual ~BonusPoint() | 17 | virtual ~BonusPoint() |
| 18 | {}; | 18 | {}; |
| 19 | 19 | ||
| 20 | virtual bool enter(Actor *actor); | 20 | virtual EnteredState enter(Actor *actor); |
| 21 | virtual void onDie(Actor *actor); | 21 | virtual void onDie(Actor *actor); |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
diff --git a/pacman-c++/constants.h b/pacman-c++/constants.h index f9f40f9..e7dedbf 100644 --- a/pacman-c++/constants.h +++ b/pacman-c++/constants.h | |||
| @@ -83,12 +83,13 @@ namespace Transmission | |||
| 83 | const field_t bonuspoint = (1 << 6); | 83 | const field_t bonuspoint = (1 << 6); |
| 84 | const field_t pacman = (1 << 7); | 84 | const field_t pacman = (1 << 7); |
| 85 | const field_t empty = (1 << 8); // explicit empty for update | 85 | const field_t empty = (1 << 8); // explicit empty for update |
| 86 | const field_t death = (1 << 9); | ||
| 86 | 87 | ||
| 87 | const field_t direction_none = 0; | 88 | const field_t direction_none = 0; |
| 88 | const field_t direction_left = (1 << 9); | 89 | const field_t direction_left = (1 << 10); |
| 89 | const field_t direction_right = (1 << 10); | 90 | const field_t direction_right = (1 << 11); |
| 90 | const field_t direction_up = (1 << 11); | 91 | const field_t direction_up = (1 << 12); |
| 91 | const field_t direction_down = (1 << 12); | 92 | const field_t direction_down = (1 << 13); |
| 92 | 93 | ||
| 93 | const mask_t color_mask = Color::none | Color::red | Color::blue | Color::green | Color::yellow; | 94 | const mask_t color_mask = Color::none | Color::red | Color::blue | Color::green | Color::yellow; |
| 94 | const mask_t type_mask = block | bonuspoint; | 95 | const mask_t type_mask = block | bonuspoint; |
diff --git a/pacman-c++/gameentity.cpp b/pacman-c++/gameentity.cpp index 156deda..e73e759 100644 --- a/pacman-c++/gameentity.cpp +++ b/pacman-c++/gameentity.cpp | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | #include "gameentity.h" | 1 | #include "gameentity.h" |
| 2 | 2 | ||
| 3 | GameEntity::GameEntity(Color::Color color, QGraphicsItem *parent) | 3 | GameEntity::GameEntity(Color::Color color, QGraphicsItem *parent) |
| 4 | : PixmapItem(parent), m_type(Type), m_eaten(false), m_color(color) | 4 | : PixmapItem(parent), m_type(Type), m_color(color) |
| 5 | {} | 5 | {} |
| 6 | 6 | ||
| 7 | GameEntity::GameEntity(QGraphicsItem *parent) | 7 | GameEntity::GameEntity(QGraphicsItem *parent) |
| 8 | : PixmapItem(parent), m_type(Type), m_eaten(false), m_color(Color::none) | 8 | : PixmapItem(parent), m_type(Type), m_color(Color::none) |
| 9 | {} | 9 | {} |
diff --git a/pacman-c++/gameentity.h b/pacman-c++/gameentity.h index 92b485e..116fae5 100644 --- a/pacman-c++/gameentity.h +++ b/pacman-c++/gameentity.h | |||
| @@ -20,6 +20,13 @@ public: | |||
| 20 | Type = UserType + 1 | 20 | Type = UserType + 1 |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | enum EnteredState | ||
| 24 | { | ||
| 25 | Nothing, | ||
| 26 | DestroyedEntity, | ||
| 27 | DestroyedActor | ||
| 28 | }; | ||
| 29 | |||
| 23 | public: | 30 | public: |
| 24 | GameEntity(Color::Color color = Color::none, QGraphicsItem *parent = 0); | 31 | GameEntity(Color::Color color = Color::none, QGraphicsItem *parent = 0); |
| 25 | GameEntity(QGraphicsItem *parent); | 32 | GameEntity(QGraphicsItem *parent); |
| @@ -41,18 +48,10 @@ public: | |||
| 41 | /* performs action when this actor acctually enters | 48 | /* performs action when this actor acctually enters |
| 42 | * returns whether this entity survives the entering | 49 | * returns whether this entity survives the entering |
| 43 | */ | 50 | */ |
| 44 | virtual bool enter(Actor *) | 51 | virtual EnteredState enter(Actor *) |
| 45 | { | 52 | { |
| 46 | /* default to no action/survive */ | 53 | /* default to no action/survive */ |
| 47 | return true; | 54 | return Nothing; |
| 48 | } | ||
| 49 | |||
| 50 | /* check whether this entity is regarded as eaten | ||
| 51 | * (and can be removed in the next tick) | ||
| 52 | */ | ||
| 53 | virtual bool eaten() | ||
| 54 | { | ||
| 55 | return m_eaten; | ||
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | /* called when an instance acctually dies for creating effects */ | 57 | /* called when an instance acctually dies for creating effects */ |
| @@ -67,7 +66,6 @@ public: | |||
| 67 | 66 | ||
| 68 | protected: | 67 | protected: |
| 69 | int m_type; | 68 | int m_type; |
| 70 | bool m_eaten; | ||
| 71 | Color::Color m_color; | 69 | Color::Color m_color; |
| 72 | }; | 70 | }; |
| 73 | 71 | ||
diff --git a/pacman-c++/mainwidget.cpp b/pacman-c++/mainwidget.cpp index eb032bd..f164219 100644 --- a/pacman-c++/mainwidget.cpp +++ b/pacman-c++/mainwidget.cpp | |||
| @@ -33,13 +33,8 @@ MainWidget::MainWidget(QWidget *parent) | |||
| 33 | m_socket->waitForReadyRead(); | 33 | m_socket->waitForReadyRead(); |
| 34 | tick(); | 34 | tick(); |
| 35 | 35 | ||
| 36 | connect(m_socket, SIGNAL(readyRead()), this, SLOT(tick())); | ||
| 37 | qDebug() << "[Connect] mycolor=" << m_scene->color(); | 36 | qDebug() << "[Connect] mycolor=" << m_scene->color(); |
| 38 | 37 | connect(m_socket, SIGNAL(readyRead()), this, SLOT(tick())); | |
| 39 | //TODO: play intro as soon as there are enough players | ||
| 40 | //connect(AudioPlayer::self(), SIGNAL(finished()), this, SLOT(startGame())); | ||
| 41 | //AudioPlayer::self()->play(AudioPlayer::Intro); | ||
| 42 | startGame(); | ||
| 43 | } | 38 | } |
| 44 | 39 | ||
| 45 | bool MainWidget::connected() | 40 | bool MainWidget::connected() |
| @@ -146,6 +141,7 @@ void MainWidget::tick() | |||
| 146 | Q_ASSERT(worked); | 141 | Q_ASSERT(worked); |
| 147 | Q_UNUSED(worked); | 142 | Q_UNUSED(worked); |
| 148 | 143 | ||
| 144 | /* eating order data set inidicates a new round */ | ||
| 149 | if (m_updatepacket.eating_order_size() > 0) | 145 | if (m_updatepacket.eating_order_size() > 0) |
| 150 | { | 146 | { |
| 151 | Q_ASSERT(m_scene != NULL); | 147 | Q_ASSERT(m_scene != NULL); |
| @@ -156,6 +152,11 @@ void MainWidget::tick() | |||
| 156 | for(int i = 0; i < m_updatepacket.eating_order_size(); ++i) | 152 | for(int i = 0; i < m_updatepacket.eating_order_size(); ++i) |
| 157 | order.append(static_cast<Color::Color>(m_updatepacket.eating_order(i) & Transmission::color_mask)); | 153 | order.append(static_cast<Color::Color>(m_updatepacket.eating_order(i) & Transmission::color_mask)); |
| 158 | m_scene->setEatingOrder(order); | 154 | m_scene->setEatingOrder(order); |
| 155 | |||
| 156 | /* stop and restart game */ | ||
| 157 | stopGame(); | ||
| 158 | connect(AudioManager::self()->audioPlayer(), SIGNAL(finished()), this, SLOT(startGame())); | ||
| 159 | AudioManager::self()->play(Sound::Intro, true); | ||
| 159 | } | 160 | } |
| 160 | 161 | ||
| 161 | Transmission::map_t map = Util::createUninitialisedMap(); | 162 | Transmission::map_t map = Util::createUninitialisedMap(); |
| @@ -177,8 +178,6 @@ void MainWidget::tick() | |||
| 177 | 178 | ||
| 178 | void MainWidget::keyPressEvent(QKeyEvent* event) | 179 | void MainWidget::keyPressEvent(QKeyEvent* event) |
| 179 | { | 180 | { |
| 180 | if (!m_running) | ||
| 181 | return; | ||
| 182 | if (event->isAutoRepeat()) | 181 | if (event->isAutoRepeat()) |
| 183 | return; | 182 | return; |
| 184 | 183 | ||
| @@ -194,8 +193,6 @@ void MainWidget::keyPressEvent(QKeyEvent* event) | |||
| 194 | 193 | ||
| 195 | void MainWidget::sendKeyUpdate() | 194 | void MainWidget::sendKeyUpdate() |
| 196 | { | 195 | { |
| 197 | if (!m_running) | ||
| 198 | return; | ||
| 199 | if (m_currentKey == Transmission::direction_none) | 196 | if (m_currentKey == Transmission::direction_none) |
| 200 | return; | 197 | return; |
| 201 | qDebug() << "[SendKey] key=" << m_currentKey; | 198 | qDebug() << "[SendKey] key=" << m_currentKey; |
| @@ -206,10 +203,8 @@ void MainWidget::sendKeyUpdate() | |||
| 206 | 203 | ||
| 207 | void MainWidget::keyReleaseEvent(QKeyEvent* event) | 204 | void MainWidget::keyReleaseEvent(QKeyEvent* event) |
| 208 | { | 205 | { |
| 209 | if (!m_running) | ||
| 210 | return; | ||
| 211 | if (event->isAutoRepeat()) | 206 | if (event->isAutoRepeat()) |
| 212 | return; | 207 | return; |
| 213 | 208 | ||
| 214 | QWidget::keyReleaseEvent(event); | 209 | QWidget::keyReleaseEvent(event); |
| 215 | m_currentKey = Transmission::none; | 210 | m_currentKey = Transmission::none; |
| @@ -218,10 +213,18 @@ void MainWidget::keyReleaseEvent(QKeyEvent* event) | |||
| 218 | 213 | ||
| 219 | void MainWidget::startGame() | 214 | void MainWidget::startGame() |
| 220 | { | 215 | { |
| 216 | disconnect(AudioManager::self()->audioPlayer(), NULL, this, SLOT(startGame())); | ||
| 221 | m_running = true; | 217 | m_running = true; |
| 218 | sendKeyUpdate(); | ||
| 222 | m_ambientPlayer->play(); | 219 | m_ambientPlayer->play(); |
| 223 | } | 220 | } |
| 224 | 221 | ||
| 222 | void MainWidget::stopGame() | ||
| 223 | { | ||
| 224 | m_running = false; | ||
| 225 | m_ambientPlayer->pause(); | ||
| 226 | } | ||
| 227 | |||
| 225 | void MainWidget::setAmbientMuted(bool muted) | 228 | void MainWidget::setAmbientMuted(bool muted) |
| 226 | { | 229 | { |
| 227 | m_ambientPlayer->setMuted(muted); | 230 | m_ambientPlayer->setMuted(muted); |
diff --git a/pacman-c++/mainwidget.h b/pacman-c++/mainwidget.h index ef282c1..d5695ed 100644 --- a/pacman-c++/mainwidget.h +++ b/pacman-c++/mainwidget.h | |||
| @@ -28,6 +28,7 @@ protected: | |||
| 28 | 28 | ||
| 29 | private slots: | 29 | private slots: |
| 30 | void startGame(); | 30 | void startGame(); |
| 31 | void stopGame(); | ||
| 31 | void playerScoreClicked(); | 32 | void playerScoreClicked(); |
| 32 | void tick(); | 33 | void tick(); |
| 33 | void sendKeyUpdate(); | 34 | void sendKeyUpdate(); |
diff --git a/pacman-c++/pics/actor1.png b/pacman-c++/pics/actor1.png index ae9f172..5a37b4f 100644 --- a/pacman-c++/pics/actor1.png +++ b/pacman-c++/pics/actor1.png | |||
| Binary files differ | |||
diff --git a/pacman-c++/pics/actor2.png b/pacman-c++/pics/actor2.png index 07ecb3f..736a6e7 100644 --- a/pacman-c++/pics/actor2.png +++ b/pacman-c++/pics/actor2.png | |||
| Binary files differ | |||
diff --git a/pacman-c++/pics/actor3.png b/pacman-c++/pics/actor3.png index 486fd37..f963cff 100644 --- a/pacman-c++/pics/actor3.png +++ b/pacman-c++/pics/actor3.png | |||
| Binary files differ | |||
diff --git a/pacman-c++/pics/actor4.png b/pacman-c++/pics/actor4.png index 9684fc0..e500dc5 100644 --- a/pacman-c++/pics/actor4.png +++ b/pacman-c++/pics/actor4.png | |||
| Binary files differ | |||
diff --git a/pacman-c++/point.cpp b/pacman-c++/point.cpp index 2257b12..d7ebdb1 100644 --- a/pacman-c++/point.cpp +++ b/pacman-c++/point.cpp | |||
| @@ -21,11 +21,10 @@ Point::Point(QGraphicsItem *parent) | |||
| 21 | setPixmap(*pixmap); | 21 | setPixmap(*pixmap); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | bool Point::enter(Actor *actor) | 24 | GameEntity::EnteredState Point::enter(Actor *actor) |
| 25 | { | 25 | { |
| 26 | actor->addRoundPoints(Constants::Game::point_value); | 26 | actor->addRoundPoints(Constants::Game::point_value); |
| 27 | m_eaten = true; | 27 | return DestroyedEntity; |
| 28 | return false; | ||
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | void Point::onDie(Actor *actor) | 30 | void Point::onDie(Actor *actor) |
diff --git a/pacman-c++/point.h b/pacman-c++/point.h index a406194..7739554 100644 --- a/pacman-c++/point.h +++ b/pacman-c++/point.h | |||
| @@ -17,7 +17,7 @@ public: | |||
| 17 | virtual ~Point() | 17 | virtual ~Point() |
| 18 | {}; | 18 | {}; |
| 19 | 19 | ||
| 20 | virtual bool enter(Actor *actor); | 20 | virtual EnteredState enter(Actor *actor); |
| 21 | virtual void onDie(Actor *actor); | 21 | virtual void onDie(Actor *actor); |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
diff --git a/pacman-c++/sceneholder.cpp b/pacman-c++/sceneholder.cpp index 56e0fff..1ecf31b 100644 --- a/pacman-c++/sceneholder.cpp +++ b/pacman-c++/sceneholder.cpp | |||
| @@ -20,23 +20,51 @@ SceneHolder::SceneHolder(QObject *parent) | |||
| 20 | 20 | ||
| 21 | void SceneHolder::reset() | 21 | void SceneHolder::reset() |
| 22 | { | 22 | { |
| 23 | /* reset actor directions */ | 23 | processDelayedItems(); |
| 24 | |||
| 25 | /* remove actors from scene so they don't get deleted during clear */ | ||
| 24 | foreach(Actor *actor, m_actors) | 26 | foreach(Actor *actor, m_actors) |
| 25 | actor->resetDirection(); | 27 | { |
| 28 | actor->resetAnimation(); | ||
| 29 | removeItem(actor); | ||
| 30 | } | ||
| 31 | |||
| 32 | /* clear our stuff */ | ||
| 33 | clear(); | ||
| 34 | m_pointsLeft = 0; | ||
| 35 | for (int i = 0; i < visualMap.size(); ++i) | ||
| 36 | { | ||
| 37 | visualMap[i].clear(); | ||
| 38 | visualMap[i].resize(Constants::map_size.height); | ||
| 39 | } | ||
| 40 | |||
| 41 | /* add actors again */ | ||
| 42 | foreach(Actor *actor, m_actors) | ||
| 43 | addItem(actor); | ||
| 26 | } | 44 | } |
| 27 | 45 | ||
| 28 | void SceneHolder::updateMap(const Transmission::map_t& map) | 46 | void SceneHolder::processDelayedItems() |
| 29 | { | 47 | { |
| 30 | /* remove items that got marked for removal from scene */ | 48 | /* remove items that got marked for removal from scene */ |
| 31 | QMutableListIterator<GameEntity *> i(m_oldItems); | 49 | foreach(GameEntity *item, m_oldItems) |
| 32 | while(i.hasNext()) | ||
| 33 | { | 50 | { |
| 34 | i.next(); | ||
| 35 | GameEntity *item = i.value(); | ||
| 36 | removeItem(item); | 51 | removeItem(item); |
| 37 | i.remove(); | ||
| 38 | delete item; | 52 | delete item; |
| 39 | } | 53 | } |
| 54 | m_oldItems.clear(); | ||
| 55 | |||
| 56 | /* process death */ | ||
| 57 | foreach(const Color::Color color, m_death.keys()) | ||
| 58 | { | ||
| 59 | Q_ASSERT(m_death[color] != NULL); | ||
| 60 | m_death[color]->onDie(m_actors[color]); | ||
| 61 | } | ||
| 62 | m_death.clear(); | ||
| 63 | } | ||
| 64 | |||
| 65 | void SceneHolder::updateMap(const Transmission::map_t& map) | ||
| 66 | { | ||
| 67 | processDelayedItems(); | ||
| 40 | 68 | ||
| 41 | /* process update */ | 69 | /* process update */ |
| 42 | for (unsigned int x = 0; x < Constants::map_size.width; ++x) | 70 | for (unsigned int x = 0; x < Constants::map_size.width; ++x) |
| @@ -66,28 +94,18 @@ void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x | |||
| 66 | if (cur & Transmission::empty) | 94 | if (cur & Transmission::empty) |
| 67 | { | 95 | { |
| 68 | GameEntity *oldItem = visualMap[x][y]; | 96 | GameEntity *oldItem = visualMap[x][y]; |
| 69 | /* special handling for purging field | 97 | /* special handling for purging field */ |
| 70 | */ | ||
| 71 | if (oldItem != NULL) | 98 | if (oldItem != NULL) |
| 72 | { | 99 | { |
| 100 | /* remove item from visualmap and register item for removal in next update */ | ||
| 73 | visualMap[x][y] = NULL; | 101 | visualMap[x][y] = NULL; |
| 74 | Actor *actor = NULL; | 102 | m_oldItems.append(oldItem); |
| 75 | foreach (Actor *tmp, m_actors) | ||
| 76 | { | ||
| 77 | if (cur & tmp->color()) | ||
| 78 | { | ||
| 79 | actor = tmp; | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | 103 | ||
| 84 | /* an item must be removed by an actor */ | 104 | /* an item must be removed by an actor */ |
| 105 | Actor *actor = m_actors[color]; | ||
| 85 | if (actor == NULL) | 106 | if (actor == NULL) |
| 86 | Q_ASSERT(false); | 107 | Q_ASSERT(false); |
| 87 | oldItem->onDie(actor); | 108 | oldItem->onDie(actor); |
| 88 | |||
| 89 | /* register item for removal in next update */ | ||
| 90 | m_oldItems.append(oldItem); | ||
| 91 | } | 109 | } |
| 92 | } | 110 | } |
| 93 | 111 | ||
| @@ -165,6 +183,10 @@ void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x | |||
| 165 | qDebug() << "[SceneUpdate] actor moves: color=" << color | 183 | qDebug() << "[SceneUpdate] actor moves: color=" << color |
| 166 | << "direction=" << direction << "newpos=" << QPoint(x, y); | 184 | << "direction=" << direction << "newpos=" << QPoint(x, y); |
| 167 | } | 185 | } |
| 186 | |||
| 187 | |||
| 188 | if (cur & Transmission::death) | ||
| 189 | m_death[color] = visualMap[x][y]; | ||
| 168 | } | 190 | } |
| 169 | 191 | ||
| 170 | if (cur & Transmission::empty) | 192 | if (cur & Transmission::empty) |
| @@ -221,16 +243,6 @@ QList<Color::Color> &SceneHolder::eatingOrder() | |||
| 221 | return m_eatingorder; | 243 | return m_eatingorder; |
| 222 | } | 244 | } |
| 223 | 245 | ||
| 224 | void SceneHolder::removeActors() | ||
| 225 | { | ||
| 226 | foreach(Actor *actor, m_actors) | ||
| 227 | { | ||
| 228 | removeItem(actor); | ||
| 229 | delete actor; | ||
| 230 | } | ||
| 231 | m_actors.clear(); | ||
| 232 | } | ||
| 233 | |||
| 234 | QPoint SceneHolder::mapPositionToCoord(unsigned int x, unsigned int y) | 246 | QPoint SceneHolder::mapPositionToCoord(unsigned int x, unsigned int y) |
| 235 | { | 247 | { |
| 236 | return QPoint(x * Constants::field_size.width, y * Constants::field_size.height); | 248 | return QPoint(x * Constants::field_size.width, y * Constants::field_size.height); |
diff --git a/pacman-c++/sceneholder.h b/pacman-c++/sceneholder.h index 9340850..f36c31e 100644 --- a/pacman-c++/sceneholder.h +++ b/pacman-c++/sceneholder.h | |||
| @@ -24,7 +24,6 @@ public: | |||
| 24 | Color::Color color(); | 24 | Color::Color color(); |
| 25 | void setEatingOrder(QList<Color::Color> &order); | 25 | void setEatingOrder(QList<Color::Color> &order); |
| 26 | QList<Color::Color> &eatingOrder(); | 26 | QList<Color::Color> &eatingOrder(); |
| 27 | void removeActors(); | ||
| 28 | 27 | ||
| 29 | signals: | 28 | signals: |
| 30 | void allPointsRemoved(); | 29 | void allPointsRemoved(); |
| @@ -33,6 +32,8 @@ private slots: | |||
| 33 | void decrementPoints(); | 32 | void decrementPoints(); |
| 34 | 33 | ||
| 35 | protected: | 34 | protected: |
| 35 | /* process items that got delayed by one tick */ | ||
| 36 | void processDelayedItems(); | ||
| 36 | /* data conversion */ | 37 | /* data conversion */ |
| 37 | QPoint mapPositionToCoord(unsigned int x, unsigned int y); | 38 | QPoint mapPositionToCoord(unsigned int x, unsigned int y); |
| 38 | QPoint mapPositionToCoord(QPoint point); | 39 | QPoint mapPositionToCoord(QPoint point); |
| @@ -50,6 +51,7 @@ protected: | |||
| 50 | * must be remove one tick later | 51 | * must be remove one tick later |
| 51 | */ | 52 | */ |
| 52 | QList<GameEntity *> m_oldItems; | 53 | QList<GameEntity *> m_oldItems; |
| 54 | QMap<Color::Color, GameEntity *> m_death; | ||
| 53 | 55 | ||
| 54 | /* my local color */ | 56 | /* my local color */ |
| 55 | Color::Color m_color; | 57 | Color::Color m_color; |
diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp index be45a66..ef271f0 100644 --- a/pacman-c++/server.cpp +++ b/pacman-c++/server.cpp | |||
| @@ -8,11 +8,12 @@ | |||
| 8 | #include <QtNetwork/QTcpServer> | 8 | #include <QtNetwork/QTcpServer> |
| 9 | #include <QtNetwork/QTcpSocket> | 9 | #include <QtNetwork/QTcpSocket> |
| 10 | #include <QTextStream> | 10 | #include <QTextStream> |
| 11 | #include <sys/types.h> | ||
| 11 | 12 | ||
| 12 | Server::Server(QWidget *parent) | 13 | Server::Server(QWidget *parent) |
| 13 | : SceneHolder(parent), m_bindaddress(QHostAddress::Any), | 14 | : SceneHolder(parent), m_bindaddress(QHostAddress::Any), |
| 14 | m_port(Constants::Networking::port), m_numbots(0), | 15 | m_port(Constants::Networking::port), m_numbots(0), |
| 15 | m_rounds(3), m_curRound(0), m_roundFinished(false) | 16 | m_rounds(3), m_curRound(0), m_running(false), m_finishRound(false) |
| 16 | { | 17 | { |
| 17 | /* determine max players by using order array */ | 18 | /* determine max players by using order array */ |
| 18 | for(m_maxplayers = 0; Color::order[m_maxplayers] != Color::none; ++m_maxplayers); | 19 | for(m_maxplayers = 0; Color::order[m_maxplayers] != Color::none; ++m_maxplayers); |
| @@ -36,54 +37,43 @@ bool Server::run() | |||
| 36 | if (!waitForClientConnections()) | 37 | if (!waitForClientConnections()) |
| 37 | return false; | 38 | return false; |
| 38 | 39 | ||
| 39 | connect(this, SIGNAL(allPointsRemoved()), this, SLOT(setRoundFinished())); | 40 | connect(this, SIGNAL(allPointsRemoved()), this, SLOT(setFinishRound())); |
| 40 | initRoundMap(); | 41 | initRoundMap(); |
| 41 | return true; | 42 | return true; |
| 42 | } | 43 | } |
| 43 | 44 | ||
| 44 | void Server::tick() | 45 | void Server::tick() |
| 45 | { | 46 | { |
| 46 | //qDebug() << "[Tick] Doing server update"; | 47 | qDebug() << "[Tick] Doing server update"; |
| 47 | if (m_roundFinished) | 48 | if (m_finishRound) |
| 49 | stopGame(true); | ||
| 50 | if (!m_running) | ||
| 48 | { | 51 | { |
| 49 | // TODO: call this when a pacman get's eaten | 52 | Transmission::map_t map = Util::createEmptyMap(); |
| 50 | /* first finish previous round */ | 53 | sendUpdate(map); |
| 51 | foreach(Actor *actor, m_actors) | 54 | Util::deleteMap(map); |
| 52 | actor->finishRound(); | 55 | return; |
| 53 | |||
| 54 | ++m_curRound; | ||
| 55 | if(m_curRound < m_rounds) | ||
| 56 | initRoundMap(); | ||
| 57 | else | ||
| 58 | { | ||
| 59 | /* end of game */ | ||
| 60 | qDebug() << "All round finished. Exiting..."; | ||
| 61 | m_tickTimer->stop(); | ||
| 62 | qApp->quit(); | ||
| 63 | } | ||
| 64 | } | 56 | } |
| 65 | else | ||
| 66 | { | ||
| 67 | /* let the bots move */ | ||
| 68 | foreach (Color::Color color, m_bots) | ||
| 69 | botCalculate(m_actors[color]); | ||
| 70 | 57 | ||
| 71 | /* move on the virtual map */ | 58 | /* let the bots move */ |
| 72 | Transmission::map_t map = calculateUpdates(); | 59 | foreach (Color::Color color, m_bots) |
| 73 | updateMap(map); | 60 | botCalculate(m_actors[color]); |
| 74 | 61 | ||
| 75 | /* add a random bonus point */ | 62 | /* move on the virtual map */ |
| 76 | QPoint pos = addRandomPoint(map, Transmission::bonuspoint); | 63 | Transmission::map_t map = calculateUpdates(); |
| 77 | if (!pos.isNull()) | 64 | updateMap(map); |
| 78 | updateMap(map, pos.x(), pos.y()); | ||
| 79 | 65 | ||
| 80 | /* add/remove random colorized block */ | 66 | /* add a random bonus point */ |
| 81 | if (this->property("coloredblocks").toBool()) | 67 | QPoint pos = addRandomPoint(map, Transmission::bonuspoint); |
| 82 | colorizeBlocks(map); | 68 | if (!pos.isNull()) |
| 69 | updateMap(map, pos.x(), pos.y()); | ||
| 83 | 70 | ||
| 84 | sendUpdate(map); | 71 | /* add/remove random colorized block */ |
| 85 | Util::deleteMap(map); | 72 | if (this->property("coloredblocks").toBool()) |
| 86 | } | 73 | colorizeBlocks(map); |
| 74 | |||
| 75 | sendUpdate(map); | ||
| 76 | Util::deleteMap(map); | ||
| 87 | } | 77 | } |
| 88 | 78 | ||
| 89 | Transmission::map_t Server::calculateUpdates() | 79 | Transmission::map_t Server::calculateUpdates() |
| @@ -94,14 +84,15 @@ Transmission::map_t Server::calculateUpdates() | |||
| 94 | while (i.hasNext()) | 84 | while (i.hasNext()) |
| 95 | { | 85 | { |
| 96 | i.next(); | 86 | i.next(); |
| 97 | Actor *actor = m_actors.value(i.key()); | 87 | Color::Color color = i.key(); |
| 88 | Actor *actor = m_actors[color]; | ||
| 98 | QPoint mapPosition = CoordToMapPosition(actor->pos().toPoint()); | 89 | QPoint mapPosition = CoordToMapPosition(actor->pos().toPoint()); |
| 99 | Actor::Movement direction = i.value(); | 90 | Actor::Movement direction = i.value(); |
| 100 | int turn = 0; | 91 | int turn = 0; |
| 101 | 92 | ||
| 102 | invalid_direction: | 93 | invalid_direction: |
| 103 | ++turn; | 94 | ++turn; |
| 104 | qDebug() << "[Calc] Actor wants to move: color=" << i.key() | 95 | qDebug() << "[Calc] Actor wants to move: color=" << color |
| 105 | << "pos=" << mapPosition << "direction=" << direction; | 96 | << "pos=" << mapPosition << "direction=" << direction; |
| 106 | 97 | ||
| 107 | QPoint newMapPosition = mapPosition + Actor::movementToPoint(direction); | 98 | QPoint newMapPosition = mapPosition + Actor::movementToPoint(direction); |
| @@ -132,10 +123,15 @@ invalid_direction: | |||
| 132 | else | 123 | else |
| 133 | { | 124 | { |
| 134 | /* apply actions of entering this field */ | 125 | /* apply actions of entering this field */ |
| 135 | bool survive = item->enter(actor); | 126 | GameEntity::EnteredState survive = item->enter(actor); |
| 136 | if (!survive) | 127 | if (survive == GameEntity::DestroyedEntity) |
| 137 | { | ||
| 138 | map[newMapPosition.x()][newMapPosition.y()] = Transmission::empty | actor->color(); | 128 | map[newMapPosition.x()][newMapPosition.y()] = Transmission::empty | actor->color(); |
| 129 | else if (survive == GameEntity::DestroyedActor) | ||
| 130 | { | ||
| 131 | m_actors[item->color()]->addRoundPoints(actor->getRoundPoints()); | ||
| 132 | actor->finishRound(true); | ||
| 133 | map[newMapPosition.x()][newMapPosition.y()] = Transmission::death | actor->color(); | ||
| 134 | setFinishRound(); | ||
| 139 | } | 135 | } |
| 140 | } | 136 | } |
| 141 | } | 137 | } |
| @@ -161,7 +157,7 @@ invalid_direction: | |||
| 161 | } | 157 | } |
| 162 | 158 | ||
| 163 | map[newMapPosition.x()][newMapPosition.y()] |= Transmission::pacman | | 159 | map[newMapPosition.x()][newMapPosition.y()] |= Transmission::pacman | |
| 164 | i.key() | Util::actorMovementToTransmission(direction); | 160 | color | Util::actorMovementToTransmission(direction); |
| 165 | 161 | ||
| 166 | /* DEBUG: uncomments to disable auto-movement */ | 162 | /* DEBUG: uncomments to disable auto-movement */ |
| 167 | //direction = Actor::None; | 163 | //direction = Actor::None; |
| @@ -169,7 +165,7 @@ invalid_direction: | |||
| 169 | if (direction == Actor::None) | 165 | if (direction == Actor::None) |
| 170 | { | 166 | { |
| 171 | /* set actor to non-moving */ | 167 | /* set actor to non-moving */ |
| 172 | m_actorMovements[i.key()] = Actor::None; | 168 | m_actorMovements[color] = Actor::None; |
| 173 | i.remove(); | 169 | i.remove(); |
| 174 | } | 170 | } |
| 175 | } | 171 | } |
| @@ -228,11 +224,12 @@ void Server::colorizeBlocks(Transmission::map_t map) | |||
| 228 | i.setValue(--val); | 224 | i.setValue(--val); |
| 229 | else | 225 | else |
| 230 | { | 226 | { |
| 227 | QPoint block = i.key(); | ||
| 231 | /* check for actor collision */ | 228 | /* check for actor collision */ |
| 232 | bool skip = false; | 229 | bool skip = false; |
| 233 | foreach (Actor *actor, m_actors) | 230 | foreach (Actor *actor, m_actors) |
| 234 | { | 231 | { |
| 235 | if (CoordToMapPosition(actor->pos().toPoint()) == i.key()) | 232 | if (CoordToMapPosition(actor->pos().toPoint()) == block) |
| 236 | skip = true; | 233 | skip = true; |
| 237 | if (skip) | 234 | if (skip) |
| 238 | break; | 235 | break; |
| @@ -240,7 +237,6 @@ void Server::colorizeBlocks(Transmission::map_t map) | |||
| 240 | if (skip) | 237 | if (skip) |
| 241 | continue; | 238 | continue; |
| 242 | 239 | ||
| 243 | QPoint block = i.key(); | ||
| 244 | map[block.x()][block.y()] |= Transmission::block | Color::none; | 240 | map[block.x()][block.y()] |= Transmission::block | Color::none; |
| 245 | updateMap(map, block.x(), block.y()); | 241 | updateMap(map, block.x(), block.y()); |
| 246 | m_blocks.append(block); | 242 | m_blocks.append(block); |
| @@ -510,16 +506,14 @@ void Server::keyPressUpdate() | |||
| 510 | } | 506 | } |
| 511 | } | 507 | } |
| 512 | 508 | ||
| 513 | void Server::setRoundFinished(bool value) | ||
| 514 | { | ||
| 515 | m_roundFinished = value; | ||
| 516 | } | ||
| 517 | |||
| 518 | void Server::initRoundMap() | 509 | void Server::initRoundMap() |
| 519 | { | 510 | { |
| 520 | qDebug() << "[initRoundMap] New round starts..."; | 511 | qDebug() << "[initRoundMap] New round starts..."; |
| 521 | m_tickTimer->stop(); | 512 | m_tickTimer->stop(); |
| 522 | 513 | ||
| 514 | /* reset scene and clean up items */ | ||
| 515 | reset(); | ||
| 516 | |||
| 523 | /* create new map */ | 517 | /* create new map */ |
| 524 | Transmission::map_t map = Util::createDemoMap(); | 518 | Transmission::map_t map = Util::createDemoMap(); |
| 525 | Util::placeActors(map, m_maxplayers, Color::order); | 519 | Util::placeActors(map, m_maxplayers, Color::order); |
| @@ -542,11 +536,54 @@ void Server::initRoundMap() | |||
| 542 | Util::deleteMap(map); | 536 | Util::deleteMap(map); |
| 543 | map = NULL; | 537 | map = NULL; |
| 544 | 538 | ||
| 545 | m_roundFinished = false; | ||
| 546 | m_actorMovements.clear(); | 539 | m_actorMovements.clear(); |
| 540 | |||
| 541 | disconnect(AudioManager::self()->audioPlayer(), NULL, this, NULL); | ||
| 542 | connect(AudioManager::self()->audioPlayer(), SIGNAL(finished()), this, SLOT(startGame())); | ||
| 543 | AudioManager::self()->play(Sound::Intro, true); | ||
| 547 | m_tickTimer->start(); | 544 | m_tickTimer->start(); |
| 548 | } | 545 | } |
| 549 | 546 | ||
| 547 | void Server::startGame() | ||
| 548 | { | ||
| 549 | m_running = true; | ||
| 550 | } | ||
| 551 | |||
| 552 | void Server::stopGame(bool delay) | ||
| 553 | { | ||
| 554 | /* first finish previous round */ | ||
| 555 | foreach(Actor *actor, m_actors) | ||
| 556 | actor->finishRound(); | ||
| 557 | m_finishRound = false; | ||
| 558 | m_running = false; | ||
| 559 | |||
| 560 | /* add delay if requested */ | ||
| 561 | if (delay) | ||
| 562 | { | ||
| 563 | disconnect(AudioManager::self()->audioPlayer(), NULL, this, NULL); | ||
| 564 | connect(AudioManager::self()->audioPlayer(), SIGNAL(finished()), this, SLOT(stopGame())); | ||
| 565 | AudioManager::self()->play(Sound::Die, true); | ||
| 566 | return; | ||
| 567 | } | ||
| 568 | |||
| 569 | /* do next-round work */ | ||
| 570 | ++m_curRound; | ||
| 571 | if(m_rounds == 0 || m_curRound < m_rounds) | ||
| 572 | initRoundMap(); | ||
| 573 | else | ||
| 574 | { | ||
| 575 | /* end of game */ | ||
| 576 | qDebug() << "All round finished. Exiting..."; | ||
| 577 | qApp->quit(); | ||
| 578 | } | ||
| 579 | } | ||
| 580 | |||
| 581 | |||
| 582 | void Server::setFinishRound() | ||
| 583 | { | ||
| 584 | m_finishRound = true; | ||
| 585 | } | ||
| 586 | |||
| 550 | bool Server::parseCommandline() | 587 | bool Server::parseCommandline() |
| 551 | { | 588 | { |
| 552 | AnyOption opt; | 589 | AnyOption opt; |
| @@ -583,7 +620,7 @@ bool Server::parseCommandline() | |||
| 583 | << " Disable random colorized blocks" << endl | 620 | << " Disable random colorized blocks" << endl |
| 584 | << endl; | 621 | << endl; |
| 585 | opt.setOption("rounds", 'r'); | 622 | opt.setOption("rounds", 'r'); |
| 586 | out << " -r, --rounds [1..n]" << endl | 623 | out << " -r, --rounds [0 | 1..n]" << endl |
| 587 | << " Number of rounds to play" << endl | 624 | << " Number of rounds to play" << endl |
| 588 | << " Default: " << m_rounds << endl | 625 | << " Default: " << m_rounds << endl |
| 589 | << endl; | 626 | << endl; |
diff --git a/pacman-c++/server.h b/pacman-c++/server.h index a5afbfe..41b800e 100644 --- a/pacman-c++/server.h +++ b/pacman-c++/server.h | |||
| @@ -40,8 +40,10 @@ protected: | |||
| 40 | void initRoundMap(); | 40 | void initRoundMap(); |
| 41 | 41 | ||
| 42 | protected slots: | 42 | protected slots: |
| 43 | /* called when a round is finished */ | 43 | /* called when a round is started/finished */ |
| 44 | void setRoundFinished(bool value = true); | 44 | void startGame(); |
| 45 | void stopGame(bool delay = false); | ||
| 46 | void setFinishRound(); | ||
| 45 | 47 | ||
| 46 | protected: | 48 | protected: |
| 47 | QMap<Color::Color, QTcpSocket *> m_clientConnections; | 49 | QMap<Color::Color, QTcpSocket *> m_clientConnections; |
| @@ -66,7 +68,8 @@ protected: | |||
| 66 | unsigned int m_rounds; | 68 | unsigned int m_rounds; |
| 67 | /* current round, starting at 0 */ | 69 | /* current round, starting at 0 */ |
| 68 | unsigned int m_curRound; | 70 | unsigned int m_curRound; |
| 69 | bool m_roundFinished; | 71 | bool m_running; |
| 72 | bool m_finishRound; | ||
| 70 | 73 | ||
| 71 | QTimer *m_tickTimer; | 74 | QTimer *m_tickTimer; |
| 72 | 75 | ||
