diff options
Diffstat (limited to 'pacman-c++/sceneholder.cpp')
| -rw-r--r-- | pacman-c++/sceneholder.cpp | 215 |
1 files changed, 114 insertions, 101 deletions
diff --git a/pacman-c++/sceneholder.cpp b/pacman-c++/sceneholder.cpp index d9e07e5..11e0772 100644 --- a/pacman-c++/sceneholder.cpp +++ b/pacman-c++/sceneholder.cpp | |||
| @@ -39,117 +39,130 @@ void SceneHolder::updateMap(const Transmission::map_t& map) | |||
| 39 | const Transmission::field_t &cur = map[x][y]; | 39 | const Transmission::field_t &cur = map[x][y]; |
| 40 | if (cur == Transmission::none) | 40 | if (cur == Transmission::none) |
| 41 | continue; | 41 | continue; |
| 42 | updateMap(map, x, y); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | } | ||
| 42 | 46 | ||
| 43 | Color::Color color = static_cast<Color::Color>(cur & Transmission::color_mask); | 47 | void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x, unsigned int y) |
| 44 | GameEntity* item = NULL; | 48 | { |
| 49 | const Transmission::field_t &cur = map[x][y]; | ||
| 50 | if (cur == Transmission::none) | ||
| 51 | return; | ||
| 45 | 52 | ||
| 46 | if (cur & Transmission::empty) | 53 | Color::Color color = static_cast<Color::Color>(cur & Transmission::color_mask); |
| 47 | { | 54 | GameEntity* item = NULL; |
| 48 | GameEntity *oldItem = visualMap[x][y]; | ||
| 49 | /* special handling for purging field | ||
| 50 | * remove elements (in case it's not an actor) | ||
| 51 | */ | ||
| 52 | if (oldItem != NULL && dynamic_cast<Actor *>(oldItem) == NULL) | ||
| 53 | { | ||
| 54 | visualMap[x][y] = NULL; | ||
| 55 | Actor *actor = NULL; | ||
| 56 | foreach (Actor *tmp, m_actors) | ||
| 57 | { | ||
| 58 | if (cur & tmp->color()) | ||
| 59 | { | ||
| 60 | actor = tmp; | ||
| 61 | break; | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | /* an item must be removed by an actor */ | ||
| 66 | if (actor == NULL) | ||
| 67 | Q_ASSERT(false); | ||
| 68 | oldItem->onDie(actor); | ||
| 69 | |||
| 70 | /* register item for removal in next update */ | ||
| 71 | m_oldItems.append(oldItem); | ||
| 72 | } | ||
| 73 | } | ||
| 74 | 55 | ||
| 75 | if (cur == Transmission::none) | 56 | if (cur & Transmission::empty) |
| 76 | { | 57 | { |
| 77 | // no update | 58 | GameEntity *oldItem = visualMap[x][y]; |
| 78 | } | 59 | /* special handling for purging field |
| 79 | else if (cur & Transmission::block) | 60 | * remove elements (in case it's not an actor) |
| 80 | { | 61 | */ |
| 81 | unsigned int neighbours = Block::None; | 62 | if (oldItem != NULL && dynamic_cast<Actor *>(oldItem) == NULL) |
| 82 | // check left side | 63 | { |
| 83 | if (x > 0 && map[x - 1][y] & Transmission::block) | 64 | visualMap[x][y] = NULL; |
| 84 | neighbours |= Block::Left; | 65 | Actor *actor = NULL; |
| 85 | // check right side | 66 | foreach (Actor *tmp, m_actors) |
| 86 | if (x < Constants::map_size.width && map[x + 1][y] & Transmission::block) | ||
| 87 | neighbours |= Block::Right; | ||
| 88 | // check upside | ||
| 89 | if (y > 0 && map[x][y - 1] & Transmission::block) | ||
| 90 | neighbours |= Block::Up; | ||
| 91 | // check down side | ||
| 92 | if (y < Constants::map_size.height && map[x][y + 1] & Transmission::block) | ||
| 93 | neighbours |= Block::Down; | ||
| 94 | item = new Block(color, neighbours); | ||
| 95 | } | ||
| 96 | else if (cur & Transmission::bonuspoint) | ||
| 97 | item = new BonusPoint(); | ||
| 98 | else if (cur & Transmission::point) | ||
| 99 | { | ||
| 100 | item = new Point(); | ||
| 101 | connect(item, SIGNAL(destroyed()), this, SLOT(decrementPoints())); | ||
| 102 | ++m_pointsLeft; | ||
| 103 | } | ||
| 104 | else if (cur & Transmission::pacman) | ||
| 105 | { | 67 | { |
| 106 | Actor *actor = m_actors.value(color, NULL); | 68 | if (cur & tmp->color()) |
| 107 | if (actor == NULL) | ||
| 108 | { | 69 | { |
| 109 | actor = new Actor(color, (color == m_color)); | 70 | actor = tmp; |
| 110 | m_actors[color] = actor; | 71 | break; |
| 111 | addItem(actor); | ||
| 112 | actor->setPos(mapPositionToCoord(x, y)); | ||
| 113 | } | ||
| 114 | else | ||
| 115 | { | ||
| 116 | Actor::Movement direction = Util::transmissionMovementToActor( | ||
| 117 | cur & Transmission::direction_mask); | ||
| 118 | actor->move(direction); | ||
| 119 | /* that's kind a hack but working right now | ||
| 120 | * I think that will fall on our's hat sooner or later | ||
| 121 | */ | ||
| 122 | if (!(cur & Transmission::empty)) | ||
| 123 | actor->stopEating(); | ||
| 124 | qDebug() << "[SceneUpdate] actor moves: color=" << color | ||
| 125 | << "direction=" << direction << "newpos=" << QPoint(x, y); | ||
| 126 | } | 72 | } |
| 127 | } | 73 | } |
| 128 | else if (cur & Transmission::empty) | 74 | |
| 129 | { | 75 | /* an item must be removed by an actor */ |
| 130 | /* already handled */ | 76 | if (actor == NULL) |
| 131 | } | ||
| 132 | else | ||
| 133 | { | ||
| 134 | qWarning() << "Unknown data. value=" << cur; | ||
| 135 | Q_ASSERT(false); | 77 | Q_ASSERT(false); |
| 136 | } | 78 | oldItem->onDie(actor); |
| 137 | 79 | ||
| 138 | /* add new created item to scene | 80 | /* register item for removal in next update */ |
| 139 | * remove old item on that location if there's one | 81 | m_oldItems.append(oldItem); |
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | if (cur == Transmission::none) | ||
| 86 | { | ||
| 87 | // no update | ||
| 88 | } | ||
| 89 | else if (cur & Transmission::block) | ||
| 90 | { | ||
| 91 | unsigned int neighbours = Block::None; | ||
| 92 | // check left side | ||
| 93 | if (x > 0 && map[x - 1][y] & Transmission::block) | ||
| 94 | neighbours |= Block::Left; | ||
| 95 | // check right side | ||
| 96 | if (x < Constants::map_size.width && map[x + 1][y] & Transmission::block) | ||
| 97 | neighbours |= Block::Right; | ||
| 98 | // check upside | ||
| 99 | if (y > 0 && map[x][y - 1] & Transmission::block) | ||
| 100 | neighbours |= Block::Up; | ||
| 101 | // check down side | ||
| 102 | if (y < Constants::map_size.height && map[x][y + 1] & Transmission::block) | ||
| 103 | neighbours |= Block::Down; | ||
| 104 | item = new Block(color, neighbours); | ||
| 105 | } | ||
| 106 | else if (cur & Transmission::bonuspoint) | ||
| 107 | item = new BonusPoint(); | ||
| 108 | else if (cur & Transmission::point) | ||
| 109 | { | ||
| 110 | item = new Point(); | ||
| 111 | connect(item, SIGNAL(destroyed()), this, SLOT(decrementPoints())); | ||
| 112 | ++m_pointsLeft; | ||
| 113 | } | ||
| 114 | else if (cur & Transmission::pacman) | ||
| 115 | { | ||
| 116 | Actor *actor = m_actors.value(color, NULL); | ||
| 117 | if (actor == NULL) | ||
| 118 | { | ||
| 119 | actor = new Actor(color, (color == m_color)); | ||
| 120 | m_actors[color] = actor; | ||
| 121 | addItem(actor); | ||
| 122 | actor->setPos(mapPositionToCoord(x, y)); | ||
| 123 | } | ||
| 124 | else | ||
| 125 | { | ||
| 126 | Actor::Movement direction = Util::transmissionMovementToActor( | ||
| 127 | cur & Transmission::direction_mask); | ||
| 128 | /* WARNING: do NOT add actor to visualMap as visualMap-items may | ||
| 129 | * get deleted during update and actors are referenced in_mactors too | ||
| 130 | * if you REALLY need that you need to changed updateMap so that all actors | ||
| 131 | * will be moved before any new items get allocated (totally untested) | ||
| 140 | */ | 132 | */ |
| 141 | if (item != NULL) | 133 | actor->move(direction); |
| 142 | { | 134 | /* that's kind a hack but working right now |
| 143 | addItem(item); | 135 | * I think that will fall on our's hat sooner or later |
| 144 | item->setPos(mapPositionToCoord(x, y)); | 136 | */ |
| 145 | GameEntity *oldItem = visualMap[x][y]; | 137 | if (!(cur & Transmission::empty)) |
| 146 | visualMap[x][y] = item; | 138 | actor->stopEating(); |
| 147 | if (oldItem != NULL) | 139 | qDebug() << "[SceneUpdate] actor moves: color=" << color |
| 148 | { | 140 | << "direction=" << direction << "newpos=" << QPoint(x, y); |
| 149 | removeItem(item); | 141 | } |
| 150 | delete oldItem; | 142 | } |
| 151 | } | 143 | else if (cur & Transmission::empty) |
| 152 | } | 144 | { |
| 145 | /* already handled */ | ||
| 146 | } | ||
| 147 | else | ||
| 148 | { | ||
| 149 | qWarning() << "Unknown data. value=" << cur; | ||
| 150 | Q_ASSERT(false); | ||
| 151 | } | ||
| 152 | |||
| 153 | /* add new created item to scene | ||
| 154 | * remove old item on that location if there's one | ||
| 155 | */ | ||
| 156 | if (item != NULL) | ||
| 157 | { | ||
| 158 | addItem(item); | ||
| 159 | item->setPos(mapPositionToCoord(x, y)); | ||
| 160 | GameEntity *oldItem = visualMap[x][y]; | ||
| 161 | visualMap[x][y] = item; | ||
| 162 | if (oldItem != NULL) | ||
| 163 | { | ||
| 164 | removeItem(item); | ||
| 165 | delete oldItem; | ||
| 153 | } | 166 | } |
| 154 | } | 167 | } |
| 155 | } | 168 | } |
