2 // C Implementation: world
7 // Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2004
9 // Copyright: See COPYING file that comes with this distribution
22 texture_type img_distro[4];
32 World::arrays_free(void)
35 bouncy_distros.clear();
36 broken_bricks.clear();
37 bouncy_bricks.clear();
38 floating_scores.clear();
41 std::vector<ParticleSystem*>::iterator i;
42 for(i = particle_systems.begin(); i != particle_systems.end(); ++i) {
45 particle_systems.clear();
51 /* (Bouncy bricks): */
52 for (unsigned int i = 0; i < bouncy_bricks.size(); ++i)
53 bouncy_brick_draw(&bouncy_bricks[i]);
55 for (unsigned int i = 0; i < bad_guys.size(); ++i)
60 for (unsigned int i = 0; i < bullets.size(); ++i)
61 bullet_draw(&bullets[i]);
63 for (unsigned int i = 0; i < floating_scores.size(); ++i)
64 floating_score_draw(&floating_scores[i]);
66 for (unsigned int i = 0; i < upgrades.size(); ++i)
67 upgrade_draw(&upgrades[i]);
69 for (unsigned int i = 0; i < bouncy_distros.size(); ++i)
70 bouncy_distro_draw(&bouncy_distros[i]);
76 /* Handle bouncy distros: */
77 for (unsigned int i = 0; i < bouncy_distros.size(); i++)
78 bouncy_distro_action(&bouncy_distros[i]);
80 /* Handle broken bricks: */
81 for (unsigned int i = 0; i < broken_bricks.size(); i++)
82 broken_brick_action(&broken_bricks[i]);
84 /* Handle distro counting: */
89 if (distro_counter <= 0)
90 counting_distros = -1;
93 // Handle all kinds of game objects
94 for (unsigned int i = 0; i < bouncy_bricks.size(); i++)
95 bouncy_brick_action(&bouncy_bricks[i]);
97 for (unsigned int i = 0; i < floating_scores.size(); i++)
98 floating_score_action(&floating_scores[i]);
100 for (unsigned int i = 0; i < bullets.size(); ++i)
101 bullet_action(&bullets[i]);
103 for (unsigned int i = 0; i < upgrades.size(); i++)
104 upgrade_action(&upgrades[i]);
106 for (unsigned int i = 0; i < bad_guys.size(); i++)
107 bad_guys[i].action();
111 World::add_score(float x, float y, int s)
115 floating_score_type new_floating_score;
116 floating_score_init(&new_floating_score,x,y,s);
117 floating_scores.push_back(new_floating_score);
121 World::add_bouncy_distro(float x, float y)
123 bouncy_distro_type new_bouncy_distro;
124 bouncy_distro_init(&new_bouncy_distro,x,y);
125 bouncy_distros.push_back(new_bouncy_distro);
129 World::add_broken_brick(float x, float y)
131 add_broken_brick_piece(x, y, -1, -4);
132 add_broken_brick_piece(x, y + 16, -1.5, -3);
134 add_broken_brick_piece(x + 16, y, 1, -4);
135 add_broken_brick_piece(x + 16, y + 16, 1.5, -3);
139 World::add_broken_brick_piece(float x, float y, float xm, float ym)
141 broken_brick_type new_broken_brick;
142 broken_brick_init(&new_broken_brick,x,y,xm,ym);
143 broken_bricks.push_back(new_broken_brick);
147 World::add_bouncy_brick(float x, float y)
149 bouncy_brick_type new_bouncy_brick;
150 bouncy_brick_init(&new_bouncy_brick,x,y);
151 bouncy_bricks.push_back(new_bouncy_brick);
155 World::add_bad_guy(float x, float y, BadGuyKind kind)
157 bad_guys.push_back(BadGuy());
158 BadGuy& new_bad_guy = bad_guys.back();
160 new_bad_guy.init(x,y,kind);
164 World::add_upgrade(float x, float y, int dir, int kind)
166 upgrade_type new_upgrade;
167 upgrade_init(&new_upgrade,x,y,dir,kind);
168 upgrades.push_back(new_upgrade);
172 World::add_bullet(float x, float y, float xm, int dir)
174 bullet_type new_bullet;
175 bullet_init(&new_bullet,x,y,xm,dir);
176 bullets.push_back(new_bullet);
178 play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER);
183 void bouncy_distro_init(bouncy_distro_type* pbouncy_distro, float x, float y)
185 pbouncy_distro->base.x = x;
186 pbouncy_distro->base.y = y;
187 pbouncy_distro->base.ym = -2;
190 void bouncy_distro_action(bouncy_distro_type* pbouncy_distro)
192 pbouncy_distro->base.y = pbouncy_distro->base.y + pbouncy_distro->base.ym * frame_ratio;
194 pbouncy_distro->base.ym += 0.1 * frame_ratio;
196 if (pbouncy_distro->base.ym >= 0)
197 world.bouncy_distros.erase(static_cast<std::vector<bouncy_distro_type>::iterator>(pbouncy_distro));
200 void bouncy_distro_draw(bouncy_distro_type* pbouncy_distro)
202 texture_draw(&img_distro[0],
203 pbouncy_distro->base.x - scroll_x,
204 pbouncy_distro->base.y);
207 void broken_brick_init(broken_brick_type* pbroken_brick, float x, float y, float xm, float ym)
209 pbroken_brick->base.x = x;
210 pbroken_brick->base.y = y;
211 pbroken_brick->base.xm = xm;
212 pbroken_brick->base.ym = ym;
213 timer_init(&pbroken_brick->timer, true);
214 timer_start(&pbroken_brick->timer,200);
217 void broken_brick_action(broken_brick_type* pbroken_brick)
219 pbroken_brick->base.x = pbroken_brick->base.x + pbroken_brick->base.xm * frame_ratio;
220 pbroken_brick->base.y = pbroken_brick->base.y + pbroken_brick->base.ym * frame_ratio;
222 if (!timer_check(&pbroken_brick->timer))
223 world.broken_bricks.erase(static_cast<std::vector<broken_brick_type>::iterator>(pbroken_brick));
226 void broken_brick_draw(broken_brick_type* pbroken_brick)
234 dest.x = (int)(pbroken_brick->base.x - scroll_x);
235 dest.y = (int)pbroken_brick->base.y;
239 texture_draw_part(&img_brick[0],src.x,src.y,dest.x,dest.y,dest.w,dest.h);
242 void bouncy_brick_init(bouncy_brick_type* pbouncy_brick, float x, float y)
244 pbouncy_brick->base.x = x;
245 pbouncy_brick->base.y = y;
246 pbouncy_brick->offset = 0;
247 pbouncy_brick->offset_m = -BOUNCY_BRICK_SPEED;
248 pbouncy_brick->shape = GameSession::current()->get_level()->gettileid(x, y);
251 void bouncy_brick_action(bouncy_brick_type* pbouncy_brick)
254 pbouncy_brick->offset = (pbouncy_brick->offset +
255 pbouncy_brick->offset_m * frame_ratio);
259 if (pbouncy_brick->offset < -BOUNCY_BRICK_MAX_OFFSET)
260 pbouncy_brick->offset_m = BOUNCY_BRICK_SPEED;
265 if (pbouncy_brick->offset >= 0)
266 world.bouncy_bricks.erase(static_cast<std::vector<bouncy_brick_type>::iterator>(pbouncy_brick));
269 void bouncy_brick_draw(bouncy_brick_type* pbouncy_brick)
274 if (pbouncy_brick->base.x >= scroll_x - 32 &&
275 pbouncy_brick->base.x <= scroll_x + screen->w)
277 dest.x = (int)(pbouncy_brick->base.x - scroll_x);
278 dest.y = (int)pbouncy_brick->base.y;
282 Level* plevel = GameSession::current()->get_level();
284 // FIXME: overdrawing hack to clean the tile from the screen to
285 // paint it later at on offseted position
286 if(plevel->bkgd_image[0] == '\0')
288 fillrect(pbouncy_brick->base.x - scroll_x, pbouncy_brick->base.y,
290 plevel->bkgd_red, plevel->bkgd_green, plevel->bkgd_blue, 0);
294 s = (int)scroll_x / 30;
295 texture_draw_part(&img_bkgd,dest.x + s,dest.y,dest.x,dest.y,dest.w,dest.h);
298 drawshape(pbouncy_brick->base.x - scroll_x,
299 pbouncy_brick->base.y + pbouncy_brick->offset,
300 pbouncy_brick->shape);
304 void floating_score_init(floating_score_type* pfloating_score, float x, float y, int s)
306 pfloating_score->base.x = x;
307 pfloating_score->base.y = y - 16;
308 timer_init(&pfloating_score->timer,true);
309 timer_start(&pfloating_score->timer,1000);
310 pfloating_score->value = s;
313 void floating_score_action(floating_score_type* pfloating_score)
315 pfloating_score->base.y = pfloating_score->base.y - 2 * frame_ratio;
317 if(!timer_check(&pfloating_score->timer))
318 world.floating_scores.erase(static_cast<std::vector<floating_score_type>::iterator>(pfloating_score));
321 void floating_score_draw(floating_score_type* pfloating_score)
324 sprintf(str, "%d", pfloating_score->value);
325 text_draw(&gold_text, str, (int)pfloating_score->base.x + 16 - strlen(str) * 8, (int)pfloating_score->base.y, 1);
329 void trybreakbrick(float x, float y, bool small)
331 Level* plevel = GameSession::current()->get_level();
333 Tile* tile = gettile(x, y);
338 /* Get a distro from it: */
339 world.add_bouncy_distro(((int)(x + 1) / 32) * 32,
342 if (!counting_distros)
344 counting_distros = true;
348 if (distro_counter <= 0)
349 plevel->change(x, y, TM_IA, tile->next_tile);
351 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
352 score = score + SCORE_DISTRO;
358 plevel->change(x, y, TM_IA, tile->next_tile);
360 /* Replace it with broken bits: */
361 world.add_broken_brick(((int)(x + 1) / 32) * 32,
364 /* Get some score: */
365 play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
366 score = score + SCORE_BRICK;
372 void tryemptybox(float x, float y, int col_side)
374 Level* plevel = GameSession::current()->get_level();
376 Tile* tile = gettile(x,y);
380 // according to the collision side, set the upgrade direction
388 case 1: //'A': /* Box with a distro! */
389 world.add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32 - 32);
390 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
391 score = score + SCORE_DISTRO;
395 case 2: // 'B': /* Add an upgrade! */
396 if (tux.size == SMALL) /* Tux is small, add mints! */
397 world.add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_MINTS);
398 else /* Tux is big, add coffee: */
399 world.add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_COFFEE);
400 play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
403 case 3:// '!': /* Add a golden herring */
404 world.add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_HERRING);
411 plevel->change(x, y, TM_IA, tile->next_tile);
414 /* Try to grab a distro: */
415 void trygrabdistro(float x, float y, int bounciness)
417 Level* plevel = GameSession::current()->get_level();
418 Tile* tile = gettile(x, y);
419 if (tile && tile->distro)
421 plevel->change(x, y, TM_IA, tile->next_tile);
422 play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
424 if (bounciness == BOUNCE)
426 world.add_bouncy_distro(((int)(x + 1) / 32) * 32,
430 score = score + SCORE_DISTRO;
435 /* Try to bump a bad guy from below: */
436 void trybumpbadguy(float x, float y)
439 for (unsigned int i = 0; i < world.bad_guys.size(); i++)
441 if (world.bad_guys[i].base.x >= x - 32 && world.bad_guys[i].base.x <= x + 32 &&
442 world.bad_guys[i].base.y >= y - 16 && world.bad_guys[i].base.y <= y + 16)
444 world.bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP);
450 for (unsigned int i = 0; i < world.upgrades.size(); i++)
452 if (world.upgrades[i].base.height == 32 &&
453 world.upgrades[i].base.x >= x - 32 && world.upgrades[i].base.x <= x + 32 &&
454 world.upgrades[i].base.y >= y - 16 && world.upgrades[i].base.y <= y + 16)
456 world.upgrades[i].base.xm = -world.upgrades[i].base.xm;
457 world.upgrades[i].base.ym = -8;
458 play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);