From 65195fdab6262d31056c74f922376de3b009943c Mon Sep 17 00:00:00 2001 From: manuel Date: Sun, 17 Apr 2011 19:19:56 +0200 Subject: a bigger commit again: - fix pacman movement. now more like real pacman (again). e.g. if you press a direction-key again: the pacman will move in that direction as soon as possible and no repeated keypress is needed - add random colorized blocks (without dieing yet) - add cmdline-option: --nocolorblocks to disable that --- pacman-c++/block.cpp | 10 +- pacman-c++/block.h | 2 + pacman-c++/client.cpp | 2 +- pacman-c++/constants.h | 15 ++- pacman-c++/mainwidget.cpp | 9 +- pacman-c++/sceneholder.cpp | 120 ++++++++++---------- pacman-c++/server.cpp | 122 ++++++++++++++++++--- pacman-c++/server.h | 6 + pacman-google/mp3/audacity/eating_fruit.aup | 31 ++++++ .../audacity/eating_fruit_data/e00/d00/e00009ad.au | Bin 0 -> 9732 bytes .../audacity/eating_fruit_data/e00/d00/e0000e7c.au | Bin 0 -> 90680 bytes 11 files changed, 231 insertions(+), 86 deletions(-) create mode 100644 pacman-google/mp3/audacity/eating_fruit.aup create mode 100644 pacman-google/mp3/audacity/eating_fruit_data/e00/d00/e00009ad.au create mode 100644 pacman-google/mp3/audacity/eating_fruit_data/e00/d00/e0000e7c.au diff --git a/pacman-c++/block.cpp b/pacman-c++/block.cpp index 16f62c4..eb51d89 100644 --- a/pacman-c++/block.cpp +++ b/pacman-c++/block.cpp @@ -7,7 +7,7 @@ QMap Block::m_pixmaps; Block::Block(Color::Color color, unsigned int neighbours, QGraphicsItem *parent) - : GameEntity(color, parent) + : GameEntity(color, parent), m_neighbours(neighbours) { /* empty object for servers */ if (Constants::server) @@ -20,11 +20,17 @@ Block::Block(Color::Color color, unsigned int neighbours, QGraphicsItem *parent) m_pixmaps[color] = QPixmap(pixmapName); } setPixmap(m_pixmaps.find(color).value()); - setNeighbours(neighbours); + setNeighbours(m_neighbours); +} + +unsigned int Block::neighbours() +{ + return m_neighbours; } void Block::setNeighbours(unsigned int neighbours) { + m_neighbours = neighbours; setSprite(neighbours * Constants::sprite_offset, 0, Constants::field_size.width, Constants::field_size.height); } diff --git a/pacman-c++/block.h b/pacman-c++/block.h index 2f388c8..6d97a9a 100644 --- a/pacman-c++/block.h +++ b/pacman-c++/block.h @@ -23,6 +23,7 @@ public: virtual ~Block() {}; + unsigned int neighbours(); void setNeighbours(unsigned int neighbours); virtual bool checkEnter(Actor *actor); virtual bool enter(Actor *actor); @@ -30,6 +31,7 @@ public: private: // map for saving QPixmaps for reuse static QMap m_pixmaps; + unsigned int m_neighbours; }; #endif // BLOCK_H diff --git a/pacman-c++/client.cpp b/pacman-c++/client.cpp index 7c428c5..581778e 100644 --- a/pacman-c++/client.cpp +++ b/pacman-c++/client.cpp @@ -152,7 +152,7 @@ void Client::showAbout() bool Constants::server = false; -int main(int argc, char ** argv) +int main(int argc, char **argv) { /* Verify that the version of the library that we linked against is * compatible with the version of the headers we compiled against. diff --git a/pacman-c++/constants.h b/pacman-c++/constants.h index 06b6561..dc72611 100644 --- a/pacman-c++/constants.h +++ b/pacman-c++/constants.h @@ -31,12 +31,15 @@ namespace Constants { const unsigned int player_minimum_distance = 5; /* if the distance above isn't possible, decrease the distance by this value */ const unsigned int player_distance_decr = 2; - } - - namespace Random - { - /* there's a chance of 1:20 that a bonus point will be added */ - const unsigned int bouns_point_chance = 20; + /* there's a chance of 1:30 that a bonus point will be added (with one actor) */ + const unsigned int bouns_point_chance = 30; + /* every additional player will raise the chance of a bonus point by that factor */ + const unsigned int bouns_point_chance_playerfactor = 3; + /* there's a chance of 1:5 that a block will be colorized */ + const unsigned int colorize_block_chance = 5; + /* how long colorized blocks will stay colorized */ + const unsigned int colorize_block_tickcount_min = 50; + const unsigned int colorize_block_tickcount_max = 100; } } diff --git a/pacman-c++/mainwidget.cpp b/pacman-c++/mainwidget.cpp index 705a3ca..c674c55 100644 --- a/pacman-c++/mainwidget.cpp +++ b/pacman-c++/mainwidget.cpp @@ -33,11 +33,6 @@ MainWidget::MainWidget(QWidget *parent) tick(); 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 @@ -172,6 +167,8 @@ void MainWidget::keyPressEvent(QKeyEvent* event) { if (!m_running) return; + if (event->isAutoRepeat()) + return; QWidget::keyPressEvent(event); Transmission::field_t newKey = translateKey(event->key()); @@ -199,6 +196,8 @@ void MainWidget::keyReleaseEvent(QKeyEvent* event) { if (!m_running) return; + if (event->isAutoRepeat()) + return; QWidget::keyReleaseEvent(event); m_currentKey = Transmission::none; diff --git a/pacman-c++/sceneholder.cpp b/pacman-c++/sceneholder.cpp index 11e0772..38b49e5 100644 --- a/pacman-c++/sceneholder.cpp +++ b/pacman-c++/sceneholder.cpp @@ -86,68 +86,77 @@ void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x { // no update } - else if (cur & Transmission::block) - { - unsigned int neighbours = Block::None; - // check left side - if (x > 0 && map[x - 1][y] & Transmission::block) - neighbours |= Block::Left; - // check right side - if (x < Constants::map_size.width && map[x + 1][y] & Transmission::block) - neighbours |= Block::Right; - // check upside - if (y > 0 && map[x][y - 1] & Transmission::block) - neighbours |= Block::Up; - // check down side - if (y < Constants::map_size.height && map[x][y + 1] & Transmission::block) - neighbours |= Block::Down; - item = new Block(color, neighbours); - } - else if (cur & Transmission::bonuspoint) - item = new BonusPoint(); - else if (cur & Transmission::point) - { - item = new Point(); - connect(item, SIGNAL(destroyed()), this, SLOT(decrementPoints())); - ++m_pointsLeft; - } - else if (cur & Transmission::pacman) + else { - Actor *actor = m_actors.value(color, NULL); - if (actor == NULL) + if (cur & Transmission::block) + { + unsigned int neighbours = Block::None; + // check for old block first + if (visualMap[x][y] != NULL) + { + Block *oldItem = dynamic_cast(visualMap[x][y]); + if (oldItem != NULL) + neighbours = oldItem->neighbours(); + } + // check left side + if (x > 0 && map[x - 1][y] & Transmission::block) + neighbours |= Block::Left; + // check right side + if (x < Constants::map_size.width && map[x + 1][y] & Transmission::block) + neighbours |= Block::Right; + // check upside + if (y > 0 && map[x][y - 1] & Transmission::block) + neighbours |= Block::Up; + // check down side + if (y < Constants::map_size.height && map[x][y + 1] & Transmission::block) + neighbours |= Block::Down; + item = new Block(color, neighbours); + } + + if (cur & Transmission::bonuspoint) + item = new BonusPoint(); + + if (cur & Transmission::point) { - actor = new Actor(color, (color == m_color)); - m_actors[color] = actor; - addItem(actor); - actor->setPos(mapPositionToCoord(x, y)); + item = new Point(); + connect(item, SIGNAL(destroyed()), this, SLOT(decrementPoints())); + ++m_pointsLeft; } - else + + if (cur & Transmission::pacman) { - Actor::Movement direction = Util::transmissionMovementToActor( - cur & Transmission::direction_mask); - /* WARNING: do NOT add actor to visualMap as visualMap-items may + Actor *actor = m_actors.value(color, NULL); + if (actor == NULL) + { + actor = new Actor(color, (color == m_color)); + m_actors[color] = actor; + addItem(actor); + actor->setPos(mapPositionToCoord(x, y)); + } + else + { + Actor::Movement direction = Util::transmissionMovementToActor( + cur & Transmission::direction_mask); + /* WARNING: do NOT add actor to visualMap as visualMap-items may * get deleted during update and actors are referenced in_mactors too * if you REALLY need that you need to changed updateMap so that all actors * will be moved before any new items get allocated (totally untested) */ - actor->move(direction); - /* that's kind a hack but working right now + actor->move(direction); + /* that's kind a hack but working right now * I think that will fall on our's hat sooner or later */ - if (!(cur & Transmission::empty)) - actor->stopEating(); - qDebug() << "[SceneUpdate] actor moves: color=" << color - << "direction=" << direction << "newpos=" << QPoint(x, y); + if (!(cur & Transmission::empty)) + actor->stopEating(); + qDebug() << "[SceneUpdate] actor moves: color=" << color + << "direction=" << direction << "newpos=" << QPoint(x, y); + } + } + + if (cur & Transmission::empty) + { + /* already handled */ } - } - else if (cur & Transmission::empty) - { - /* already handled */ - } - else - { - qWarning() << "Unknown data. value=" << cur; - Q_ASSERT(false); } /* add new created item to scene @@ -155,15 +164,16 @@ void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x */ if (item != NULL) { - addItem(item); - item->setPos(mapPositionToCoord(x, y)); GameEntity *oldItem = visualMap[x][y]; - visualMap[x][y] = item; if (oldItem != NULL) { - removeItem(item); + removeItem(oldItem); delete oldItem; } + + addItem(item); + item->setPos(mapPositionToCoord(x, y)); + visualMap[x][y] = item; } } diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp index 01c74c4..628faa2 100644 --- a/pacman-c++/server.cpp +++ b/pacman-c++/server.cpp @@ -28,6 +28,18 @@ bool Server::run() Transmission::map_t map = Util::createDemoMap(); Util::placeActors(map, m_maxplayers, Color::order); Util::fillPoints(map); + + /* save positions of blocks for later usage */ + for (unsigned int x = 0; x < Constants::map_size.width; ++x) + { + for (unsigned int y = 0; y < Constants::map_size.height; ++y) + { + Transmission::field_t &cur = map[x][y]; + if (cur & Transmission::block) + m_blocks.append(QPoint(x, y)); + } + } + updateMap(map); sendUpdate(map); Util::deleteMap(map); @@ -41,7 +53,7 @@ bool Server::run() void Server::tick() { - qDebug() << "[Tick] Doing server update"; + //qDebug() << "[Tick] Doing server update"; Transmission::map_t map = calculateUpdates(); updateMap(map); @@ -50,6 +62,10 @@ void Server::tick() if (!pos.isNull()) updateMap(map, pos.x(), pos.y()); + /* add/remove random colorized block */ + if (this->property("coloredblocks").toBool()) + colorizeBlocks(map); + sendUpdate(map); Util::deleteMap(map); } @@ -66,17 +82,18 @@ Transmission::map_t Server::calculateUpdates() while (i.hasNext()) { i.next(); + Actor *actor = m_actors.value(i.key()); + QPoint mapPosition = CoordToMapPosition(actor->pos().toPoint()); + Actor::Movement direction = i.value(); int turn = 0; invalid_direction: ++turn; - Actor *actor = m_actors.value(i.key()); - QPoint mapPosition = CoordToMapPosition(actor->pos().toPoint()); qDebug() << "[Calc] Actor wants to move: color=" << i.key() - << "pos=" << mapPosition << "direction=" << i.value(); + << "pos=" << mapPosition << "direction=" << direction; QPoint newMapPosition = mapPosition; - switch (i.value()) + switch (direction) { case Actor::Up: newMapPosition += QPoint(0, -1); @@ -136,29 +153,29 @@ invalid_direction: /* movement didn't work - e.g. was blocked */ if (mapPosition == newMapPosition) { - /* */ - if (turn == 1 && i.value() != actor->direction()) + /* check turn */ + if (turn == 1 && direction != actor->direction()) { /* set direction back to last known direction and try again */ qDebug() << "[Calc] Movement was blocked. Trying last known actor direction"; - m_actorMovements[i.key()] = actor->direction(); + direction = actor->direction(); goto invalid_direction; } else { /* second turn didn't work too -> stop movement */ - m_actorMovements[i.key()] = Actor::None; + direction = Actor::None; qDebug() << "[Calc] No good direction known. Movement stopped"; } } map[newMapPosition.x()][newMapPosition.y()] |= Transmission::pacman | - i.key() | Util::actorMovementToTransmission(i.value()); + i.key() | Util::actorMovementToTransmission(direction); /* DEBUG: uncomments to disable auto-movement */ - //m_actorMovements[i.key()] = Actor::None; + //direction = Actor::None; - if (i.value() == Actor::None) + if (direction == Actor::None) { /* set actor to non-moving */ m_actorMovements[i.key()] = Actor::None; @@ -170,7 +187,8 @@ invalid_direction: QPoint Server::addRandomPoint(Transmission::map_t map, Transmission::field_t type) { - int chance = Constants::Random::bouns_point_chance; + int chance = Constants::Game::bouns_point_chance + - Constants::Game::bouns_point_chance_playerfactor * (m_maxplayers - 1); int rand = (int) (chance * (qrand() / (RAND_MAX + 1.0))); if (rand != 0) return QPoint(); @@ -190,10 +208,10 @@ QPoint Server::addRandomPoint(Transmission::map_t map, Transmission::field_t typ * performance would be better if actors would be listed in visualMap too * but this isn't possible that easily. see comment in updateMap(map) */ - foreach (Actor *tmp, m_actors) + foreach (Actor *actor, m_actors) { - QPoint oldpos = CoordToMapPosition(tmp->pos().toPoint()); - validpos.removeAll(oldpos); + QPoint actorpos = CoordToMapPosition(actor->pos().toPoint()); + validpos.removeAll(actorpos); } if (validpos.empty()) @@ -205,6 +223,60 @@ QPoint Server::addRandomPoint(Transmission::map_t map, Transmission::field_t typ return pos; } +void Server::colorizeBlocks(Transmission::map_t map) +{ + /* decrement tickcount of colored blocks */ + if (!m_coloredBlocks.empty()) + { + QMutableMapIterator i(m_coloredBlocks); + while(i.hasNext()) + { + i.next(); + unsigned val = i.value(); + if (val > 0) + i.setValue(--val); + else + { + /* check for actor collision */ + bool skip = false; + foreach(Actor *actor, m_actors) + { + if (CoordToMapPosition(actor->pos().toPoint()) == i.key()) + skip = true; + if (skip) + break; + } + if (skip) + continue; + + QPoint block = i.key(); + map[block.x()][block.y()] |= Transmission::block | Color::none; + updateMap(map, block.x(), block.y()); + m_blocks.append(block); + i.remove(); + } + } + } + + /* colorize a random block */ + int rand = (int) (Constants::Game::colorize_block_chance * (qrand() / (RAND_MAX + 1.0))); + if (rand == 0) + { + rand = (int) (m_blocks.size() * (qrand() / (RAND_MAX + 1.0))); + QPoint block = m_blocks.at(rand); + m_blocks.removeAt(rand); + + unsigned int min = Constants::Game::colorize_block_tickcount_min; + unsigned int max = Constants::Game::colorize_block_tickcount_max; + int tickcount = min + (int) ((max - min + 1) * (qrand() / (RAND_MAX + 1.0))); + m_coloredBlocks.insert(block, tickcount); + + unsigned int color = (int) ((m_maxplayers - 1) * (qrand() / (RAND_MAX + 1.0))); + map[block.x()][block.y()] |= Transmission::block | Color::order[color]; + updateMap(map, block.x(), block.y()); + } +} + bool Server::waitForClientConnections() { // server must stay alive as long as sockets (qt parent mem mechanism) @@ -324,6 +396,10 @@ bool Server::parseCommandline() << " Default: " << m_numbots << endl << endl; opt.setOption("bots"); + out << " --nocolorblocks" << endl + << " Disable random colorized blocks" << endl + << endl; + opt.setFlag("nocolorblocks"); out << " -h, --help" << endl << " Prints this help message" << endl; opt.setFlag("help", 'h'); @@ -386,12 +462,24 @@ bool Server::parseCommandline() m_numbots = numbots; } + this->setProperty("coloredblocks", !opt.getFlag("nocolorblocks")); + return true; } +bool operator<(const QPoint& lhs, const QPoint& rhs) +{ + if (lhs.x() < rhs.x()) + return true; + else if (lhs.x() == rhs.x()) + return lhs.y() < rhs.y(); + else + return false; +} + bool Constants::server = true; -int main(int argc, char ** argv) +int main(int argc, char **argv) { /* Verify that the version of the library that we linked against is * compatible with the version of the headers we compiled against. diff --git a/pacman-c++/server.h b/pacman-c++/server.h index 0f2879d..a50cfe3 100644 --- a/pacman-c++/server.h +++ b/pacman-c++/server.h @@ -35,6 +35,7 @@ protected: void sendUpdate(Transmission::map_t map); QPoint addRandomPoint(Transmission::map_t map, Transmission::field_t type = Transmission::bonuspoint); + void colorizeBlocks(Transmission::map_t map); protected: QMap m_clientConnections; @@ -45,6 +46,11 @@ protected: /* allocate as member variable as this packet is large and used often */ ProtoBuf::MapUpdate m_updatepacket; + /* list of blocks */ + QList m_blocks; + /* currently colored blocks + tickcount before they will turn to non-colored back */ + QMap m_coloredBlocks; + QHostAddress m_bindaddress; unsigned int m_port; unsigned int m_maxplayers; diff --git a/pacman-google/mp3/audacity/eating_fruit.aup b/pacman-google/mp3/audacity/eating_fruit.aup new file mode 100644 index 0000000..8580824 --- /dev/null +++ b/pacman-google/mp3/audacity/eating_fruit.aup @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pacman-google/mp3/audacity/eating_fruit_data/e00/d00/e00009ad.au b/pacman-google/mp3/audacity/eating_fruit_data/e00/d00/e00009ad.au new file mode 100644 index 0000000..5a34d7e Binary files /dev/null and b/pacman-google/mp3/audacity/eating_fruit_data/e00/d00/e00009ad.au differ diff --git a/pacman-google/mp3/audacity/eating_fruit_data/e00/d00/e0000e7c.au b/pacman-google/mp3/audacity/eating_fruit_data/e00/d00/e0000e7c.au new file mode 100644 index 0000000..4d1a0ea Binary files /dev/null and b/pacman-google/mp3/audacity/eating_fruit_data/e00/d00/e0000e7c.au differ -- cgit v1.2.3