@@ -57,6 +57,8 @@ bool GameScene::init() {
5757 this ->addChild (map, 1 , 100 );
5858 map->getLayer (" background" )->setGlobalZOrder (-1 );
5959
60+ bricks = map->getLayer (" bricks" );
61+
6062 // "destructable" layer, indicating the tiles which can be blown up by bubbles
6163 destructable = map->getLayer (" destructable" );
6264 destructable->setVisible (false ); /* set it transparent*/
@@ -115,7 +117,7 @@ bool GameScene::init() {
115117 y_movement = MOVE_DOWN;
116118 break ;
117119 case EventKeyboard::KeyCode::KEY_SPACE:
118- if (hero->can_set_bomb ()) {
120+ if (here_can_set (hero-> getPosition ()) && hero->can_set_bomb ()) {
119121 Bomb *bomb = hero->set_bomb ();
120122 current_bombs.pushBack (bomb);
121123 }
@@ -200,55 +202,80 @@ void GameScene::update(float delta) {
200202void GameScene::bomb_explode (Bomb *bomb)
201203{
202204 int power = bomb->getPower ();
205+ int l_range = 0 ;
206+ int r_range = 0 ;
207+ int u_range = 0 ;
208+ int d_range = 0 ;
209+
203210 Vec2 bomb_tile_coord = tileCoordFromPosition (bomb->getPosition ());
204- int firstGid = destructable->getTileSet ()->_firstGid ;
205-
206- int i = 0 ;
207- for (; i < power && bomb_tile_coord.x - i - 1 >= 0 ; i++) {
208- int GID = destructable->getTileGIDAt (Vec2 (bomb_tile_coord.x - i - 1 , bomb_tile_coord.y ));
209- if (GID - firstGid >= 0 ) {
210- map->getLayer (" bricks" )->removeTileAt (Vec2 (bomb_tile_coord.x - i - 1 , bomb_tile_coord.y ));
211- if (bomb_tile_coord.y > 0 ) {
212- map->getLayer (" tops" )->removeTileAt (Vec2 (bomb_tile_coord.x - i - 1 , bomb_tile_coord.y - 1 ));
211+ int firstGid_of_des = destructable->getTileSet ()->_firstGid ;
212+ int firstGid_of_brk = bricks->getTileSet ()->_firstGid ;
213+
214+ for (; l_range < power && bomb_tile_coord.x - l_range - 1 >= 0 ; l_range++) {
215+
216+ int GID_brk = bricks->getTileGIDAt (Vec2 (bomb_tile_coord.x - l_range - 1 , bomb_tile_coord.y ));
217+ if (GID_brk - firstGid_of_brk >= 0 ){
218+ int GID_des = destructable->getTileGIDAt (Vec2 (bomb_tile_coord.x - l_range - 1 , bomb_tile_coord.y ));
219+ if (GID_des - firstGid_of_des >= 0 ) {
220+ bricks->removeTileAt (Vec2 (bomb_tile_coord.x - l_range - 1 , bomb_tile_coord.y ));
221+ if (bomb_tile_coord.y > 0 ) {
222+ map->getLayer (" tops" )->removeTileAt (Vec2 (bomb_tile_coord.x - l_range - 1 , bomb_tile_coord.y - 1 ));
223+ }
224+ destructable->removeTileAt (Vec2 (bomb_tile_coord.x - l_range - 1 , bomb_tile_coord.y ));
213225 }
214- destructable->removeTileAt (Vec2 (bomb_tile_coord.x - i - 1 , bomb_tile_coord.y ));
215226 break ;
216227 }
217228 }
218- i = 0 ;
219- for (; i < power && bomb_tile_coord.x + i + 1 < MAP_SIZE.width ; i++) {
220- int GID = destructable->getTileGIDAt (Vec2 (bomb_tile_coord.x + i + 1 , bomb_tile_coord.y ));
221- if (GID - firstGid >= 0 ) {
222- map->getLayer (" bricks" )->removeTileAt (Vec2 (bomb_tile_coord.x + i + 1 , bomb_tile_coord.y ));
223- if (bomb_tile_coord.y > 0 ) {
224- map->getLayer (" tops" )->removeTileAt (Vec2 (bomb_tile_coord.x + i + 1 , bomb_tile_coord.y - 1 ));
229+
230+ for (; r_range < power && bomb_tile_coord.x + r_range + 1 < MAP_SIZE.width ; r_range++) {
231+ int GID_brk = bricks->getTileGIDAt (Vec2 (bomb_tile_coord.x + r_range + 1 , bomb_tile_coord.y ));
232+ if (GID_brk - firstGid_of_brk >= 0 ) {
233+ int GID_des = destructable->getTileGIDAt (Vec2 (bomb_tile_coord.x + r_range + 1 , bomb_tile_coord.y ));
234+ if (GID_des - firstGid_of_des >= 0 ) {
235+ bricks->removeTileAt (Vec2 (bomb_tile_coord.x + r_range + 1 , bomb_tile_coord.y ));
236+ if (bomb_tile_coord.y > 0 ) {
237+ map->getLayer (" tops" )->removeTileAt (Vec2 (bomb_tile_coord.x + r_range + 1 , bomb_tile_coord.y - 1 ));
238+ }
239+ destructable->removeTileAt (Vec2 (bomb_tile_coord.x + r_range + 1 , bomb_tile_coord.y ));
225240 }
226- destructable->removeTileAt (Vec2 (bomb_tile_coord.x + i + 1 , bomb_tile_coord.y ));
227241 break ;
228242 }
229243 }
230- int j = 0 ;
231- for (; j < power && bomb_tile_coord.y + j + 1 < MAP_SIZE.height ; j++) {
232- int GID = destructable->getTileGIDAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + j + 1 ));
233- if (GID - firstGid >= 0 ) {
234- map->getLayer (" bricks" )->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + j + 1 ));
235- map->getLayer (" tops" )->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + j));
236- destructable->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + j + 1 ));
244+
245+ for (; d_range < power && bomb_tile_coord.y + d_range + 1 < MAP_SIZE.height ; d_range++) {
246+ int GID_brk = bricks->getTileGIDAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + d_range + 1 ));
247+ if (GID_brk - firstGid_of_brk >= 0 ) {
248+ int GID_des = destructable->getTileGIDAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + d_range + 1 ));
249+ if (GID_des - firstGid_of_des >= 0 ) {
250+ bricks->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + d_range + 1 ));
251+ map->getLayer (" tops" )->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + d_range));
252+ destructable->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y + d_range + 1 ));
253+ }
237254 break ;
238255 }
239256 }
240- j = 0 ;
241- for (; j < power && bomb_tile_coord.y - j - 1 >= 0 ; j++) {
242- int GID = destructable->getTileGIDAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - j - 1 ));
243- if (GID - firstGid >= 0 ) {
244- map->getLayer (" bricks" )->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - j - 1 ));
245- if (bomb_tile_coord.y - j - 1 != 0 ) {
246- map->getLayer (" tops" )->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - j - 2 ));
257+
258+ for (; u_range < power && bomb_tile_coord.y - u_range - 1 >= 0 ; u_range++) {
259+ int GID_brk = bricks->getTileGIDAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - u_range - 1 ));
260+ if (GID_brk - firstGid_of_brk >= 0 ) {
261+ int GID_des = destructable->getTileGIDAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - u_range - 1 ));
262+ if (GID_des - firstGid_of_des >= 0 ) {
263+ bricks->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - u_range - 1 ));
264+ if (bomb_tile_coord.y - u_range - 1 != 0 ) {
265+ map->getLayer (" tops" )->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - u_range - 2 ));
266+ }
267+ destructable->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - u_range - 1 ));
247268 }
248- destructable->removeTileAt (Vec2 (bomb_tile_coord.x , bomb_tile_coord.y - j - 1 ));
249269 break ;
250270 }
251271 }
272+
273+ /* Now we have l_range, r_value, u_value, d_value, which indicate the explosion
274+ * range of the bomb in the four directions. What you need to do now is to
275+ * display the animation effect of bombs.
276+ * Please add your code here...
277+ */
278+
252279}
253280
254281bool GameScene::isOutOfMap (Vec2 pos)
@@ -263,18 +290,26 @@ bool GameScene::isOutOfMap(Vec2 pos)
263290 return false ;
264291}
265292
293+ bool GameScene::here_can_set (Vec2 pos)
294+ {
295+ Vec2 tile_coord = tileCoordFromPosition (pos);
296+ for (Bomb *bomb : current_bombs) {
297+ if (tileCoordFromPosition (bomb->getPosition ()) == tile_coord) {
298+ return false ;
299+ }
300+ }
301+ return true ;
302+ }
303+
266304bool GameScene::collideWithBrick (cocos2d::Vec2 targetPos)
267305{
268306 // get the tile coord of the target position
269307 Vec2 tileCoord = tileCoordFromPosition (targetPos);
270308
271- // tiles in the "bricks" layer are "collidable"
272- TMXLayer *collide = map->getLayer (" bricks" );
273-
274309 // get absolute GID of the tile
275- int tileGid = collide ->getTileGIDAt (tileCoord);
310+ int tileGid = bricks ->getTileGIDAt (tileCoord);
276311 // first GID of the "bricks" layer
277- int firstGid = collide ->getTileSet ()->_firstGid ;
312+ int firstGid = bricks ->getTileSet ()->_firstGid ;
278313 // get related GID of the tile
279314 tileGid -= firstGid;
280315
@@ -285,8 +320,18 @@ bool GameScene::collideWithBrick(cocos2d::Vec2 targetPos)
285320 return false ;
286321}
287322
288- bool GameScene::collideWithBubble (cocos2d:: Vec2 targetPos)
323+ bool GameScene::collideWithBubble (Vec2 playerPos, Vec2 targetPos)
289324{
325+ Vec2 target_tileCoord = tileCoordFromPosition (targetPos);
326+ Vec2 now_tileCoord = tileCoordFromPosition (playerPos);
327+
328+ if (now_tileCoord == target_tileCoord) return false ;
329+
330+ for (Bomb *bomb : current_bombs) {
331+ if (tileCoordFromPosition (bomb->getPosition ()) == target_tileCoord) {
332+ return true ;
333+ }
334+ }
290335 return false ;
291336}
292337
@@ -311,7 +356,9 @@ void GameScene::makeMove(Vec2 position)
311356 // if the target position is out of bound
312357 if (isOutOfMap (targetPos_down) || isOutOfMap (targetPos_top)) return ;
313358
314- if (collideWithBrick (targetPos_down) || collideWithBrick (targetPos_top) || collideWithBubble (targetPos_down) || collideWithBubble (targetPos_top)) return ;
359+ if (collideWithBrick (targetPos_down) || collideWithBrick (targetPos_top)) return ;
360+
361+ if (collideWithBubble (hero->getPosition (), targetPos_top)) return ;
315362
316363 hero->setPosition (position);
317364}
0 commit comments