X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fworld.cpp;h=6969e7a0c942657b76924b8518c67a1b7e5fd390;hb=90b85c87d5da62881fcb51b1f1b6767beb50d11f;hp=f2a64b509b5b1292f3f219db0900990cacf57435;hpb=b58b123aea0adfa0596907d649cd3de376ef6801;p=supertux.git diff --git a/src/world.cpp b/src/world.cpp index f2a64b509..6969e7a0c 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1,7 +1,9 @@ // $Id$ // // SuperTux -// Copyright (C) 2004 SuperTux Development Team, see AUTHORS for details +// Copyright (C) 2000 Bill Kendrick +// Copyright (C) 2004 Tobias Glaesser +// Copyright (C) 2004 Ingo Ruhnke // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -15,8 +17,10 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +#include #include #include #include @@ -29,22 +33,49 @@ #include "tile.h" #include "resources.h" -texture_type img_distro[4]; +Surface* img_distro[4]; World* World::current_ = 0; -World::World() +World::World(const std::string& filename) { // FIXME: Move this to action and draw and everywhere else where the // world calls child functions current_ = this; - level = new Level; + level = new Level(filename); tux.init(); + + set_defaults(); + + get_level()->load_gfx(); + activate_bad_guys(); + activate_particle_systems(); + get_level()->load_song(); +} + +World::World(const std::string& subset, int level_nr) +{ + // FIXME: Move this to action and draw and everywhere else where the + // world calls child functions + current_ = this; + + level = new Level(subset, level_nr); + tux.init(); + + set_defaults(); + + get_level()->load_gfx(); + activate_bad_guys(); + activate_particle_systems(); + get_level()->load_song(); } World::~World() { + for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) + delete *i; + delete level; } @@ -60,36 +91,7 @@ World::set_defaults() distro_counter = 0; /* set current song/music */ - set_current_music(LEVEL_MUSIC); -} - -int -World::load(const std::string& subset, int level_nr) -{ - return level->load(subset, level_nr); -} - -int -World::load(const std::string& filename) -{ - return level->load(filename); -} - -void -World::arrays_free(void) -{ - bad_guys.clear(); - bouncy_distros.clear(); - broken_bricks.clear(); - bouncy_bricks.clear(); - floating_scores.clear(); - upgrades.clear(); - bullets.clear(); - std::vector::iterator i; - for(i = particle_systems.begin(); i != particle_systems.end(); ++i) { - delete *i; - } - particle_systems.clear(); + currentmusic = LEVEL_MUSIC; } void @@ -99,7 +101,7 @@ World::activate_bad_guys() i != level->badguy_data.end(); ++i) { - add_bad_guy(i->x, i->y, i->kind); + add_bad_guy(i->x, i->y, i->kind, i->stay_on_platform); } } @@ -128,14 +130,13 @@ World::draw() /* Draw the real background */ if(get_level()->bkgd_image[0] != '\0') { - int s = (int)scroll_x / 30; - texture_draw_part(&level->img_bkgd, s, 0,0,0,level->img_bkgd.w - s, level->img_bkgd.h); - texture_draw_part(&level->img_bkgd, 0, 0,screen->w - s ,0,s,level->img_bkgd.h); + int s = ((int)scroll_x / 2)%640; + level->img_bkgd->draw_part(s, 0,0,0,level->img_bkgd->w - s, level->img_bkgd->h); + level->img_bkgd->draw_part(0, 0,screen->w - s ,0,s,level->img_bkgd->h); } else { - drawgradient(level->bkgd_top_red, level->bkgd_top_green, level->bkgd_top_blue, - level->bkgd_bottom_red, level->bkgd_bottom_green, level->bkgd_bottom_blue); + drawgradient(level->bkgd_top, level->bkgd_bottom); } /* Draw particle systems (background) */ @@ -169,8 +170,8 @@ World::draw() for (unsigned int i = 0; i < bouncy_bricks.size(); ++i) bouncy_bricks[i].draw(); - for (unsigned int i = 0; i < bad_guys.size(); ++i) - bad_guys[i].draw(); + for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) + (*i)->draw(); tux.draw(); @@ -209,6 +210,8 @@ World::draw() void World::action(double frame_ratio) { + tux.action(frame_ratio); + /* Handle bouncy distros: */ for (unsigned int i = 0; i < bouncy_distros.size(); i++) bouncy_distros[i].action(frame_ratio); @@ -239,8 +242,8 @@ World::action(double frame_ratio) for (unsigned int i = 0; i < upgrades.size(); i++) upgrades[i].action(frame_ratio); - for (unsigned int i = 0; i < bad_guys.size(); i++) - bad_guys[i].action(frame_ratio); + for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) + (*i)->action(frame_ratio); /* update particle systems */ std::vector::iterator p; @@ -251,26 +254,33 @@ World::action(double frame_ratio) /* Handle all possible collisions. */ collision_handler(); + + { // Cleanup marked badguys + for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) + if ((*i)->is_removable()) + delete *i; + bad_guys.remove_if(std::mem_fun(&BadGuy::is_removable)); + } } - void World::collision_handler() { // CO_BULLET & CO_BADGUY check for(unsigned int i = 0; i < bullets.size(); ++i) { - for(unsigned int j = 0; j < bad_guys.size(); ++j) + for (BadGuys::iterator j = bad_guys.begin(); j != bad_guys.end(); ++j) { - if(bad_guys[j].dying != DYING_NOT) + if((*j)->dying != DYING_NOT) continue; - if(rectcollision(&bullets[i].base, &bad_guys[j].base)) + + if(rectcollision(bullets[i].base, (*j)->base)) { // We have detected a collision and now call the // collision functions of the collided objects. // collide with bad_guy first, since bullet_collision will // delete the bullet - bad_guys[j].collision(0, CO_BULLET); + (*j)->collision(0, CO_BULLET); bullets[i].collision(CO_BADGUY); break; // bullet is invalid now, so break } @@ -278,22 +288,24 @@ World::collision_handler() } /* CO_BADGUY & CO_BADGUY check */ - for(unsigned int i = 0; i < bad_guys.size(); ++i) + for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) { - if(bad_guys[i].dying != DYING_NOT) + if((*i)->dying != DYING_NOT) continue; - for(unsigned int j = i+1; j < bad_guys.size(); ++j) + BadGuys::iterator j = i; + ++j; + for (; j != bad_guys.end(); ++j) { - if(j == i || bad_guys[j].dying != DYING_NOT) + if(j == i || (*j)->dying != DYING_NOT) continue; - if(rectcollision(&bad_guys[i].base, &bad_guys[j].base)) + if(rectcollision((*i)->base, (*j)->base)) { // We have detected a collision and now call the // collision functions of the collided objects. - bad_guys[j].collision(&bad_guys[i], CO_BADGUY); - bad_guys[i].collision(&bad_guys[j], CO_BADGUY); + (*j)->collision(*i, CO_BADGUY); + (*i)->collision(*j, CO_BADGUY); } } } @@ -301,24 +313,25 @@ World::collision_handler() if(tux.dying != DYING_NOT) return; // CO_BADGUY & CO_PLAYER check - for(unsigned int i = 0; i < bad_guys.size(); ++i) + for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) { - if(bad_guys[i].dying != DYING_NOT) + if((*i)->dying != DYING_NOT) continue; - if(rectcollision_offset(&bad_guys[i].base,&tux.base,0,0)) + if(rectcollision_offset((*i)->base, tux.base, 0, 0)) { // We have detected a collision and now call the collision // functions of the collided objects. if (tux.previous_base.y < tux.base.y && tux.previous_base.y + tux.previous_base.height - < bad_guys[i].base.y + bad_guys[i].base.height/2) + < (*i)->base.y + (*i)->base.height/2) { - bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_SQUISH); + (*i)->collision(&tux, CO_PLAYER, COLLISION_SQUISH); } else { - tux.collision(&bad_guys[i], CO_BADGUY); + tux.collision(*i, CO_BADGUY); + (*i)->collision(&tux, CO_PLAYER, COLLISION_NORMAL); } } } @@ -326,7 +339,7 @@ World::collision_handler() // CO_UPGRADE & CO_PLAYER check for(unsigned int i = 0; i < upgrades.size(); ++i) { - if(rectcollision(&upgrades[i].base, &tux.base)) + if(rectcollision(upgrades[i].base, tux.base)) { // We have detected a collision and now call the collision // functions of the collided objects. @@ -379,17 +392,16 @@ World::add_bouncy_brick(float x, float y) bouncy_bricks.push_back(new_bouncy_brick); } -void -World::add_bad_guy(float x, float y, BadGuyKind kind) +BadGuy* +World::add_bad_guy(float x, float y, BadGuyKind kind, bool stay_on_platform) { - bad_guys.push_back(BadGuy()); - BadGuy& new_bad_guy = bad_guys.back(); - - new_bad_guy.init(x,y,kind); + BadGuy* badguy = new BadGuy(x,y,kind, stay_on_platform); + bad_guys.push_back(badguy); + return badguy; } void -World::add_upgrade(float x, float y, int dir, int kind) +World::add_upgrade(float x, float y, Direction dir, UpgradeKind kind) { Upgrade new_upgrade; new_upgrade.init(x,y,dir,kind); @@ -397,8 +409,11 @@ World::add_upgrade(float x, float y, int dir, int kind) } void -World::add_bullet(float x, float y, float xm, int dir) +World::add_bullet(float x, float y, float xm, Direction dir) { + if(bullets.size() > MAX_BULLETS-1) + return; + Bullet new_bullet; new_bullet.init(x,y,xm,dir); bullets.push_back(new_bullet); @@ -406,6 +421,32 @@ World::add_bullet(float x, float y, float xm, int dir) play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER); } +void +World::play_music(int musictype) +{ + currentmusic = musictype; + switch(currentmusic) { + case HURRYUP_MUSIC: + music_manager->play_music(get_level()->get_level_music_fast()); + break; + case LEVEL_MUSIC: + music_manager->play_music(get_level()->get_level_music()); + break; + case HERRING_MUSIC: + music_manager->play_music(herring_song); + break; + default: + music_manager->halt_music(); + break; + } +} + +int +World::get_music_type() +{ + return currentmusic; +} + /* Break a brick: */ void World::trybreakbrick(float x, float y, bool small) @@ -453,7 +494,7 @@ World::trybreakbrick(float x, float y, bool small) /* Empty a box: */ void -World::tryemptybox(float x, float y, int col_side) +World::tryemptybox(float x, float y, Direction col_side) { Tile* tile = gettile(x,y); if (!tile->fullbox) @@ -465,10 +506,12 @@ World::tryemptybox(float x, float y, int col_side) else col_side = LEFT; + int posx = ((int)(x+1) / 32) * 32; + int posy = (int)(y/32) * 32 - 32; switch(tile->data) { case 1: // Box with a distro! - add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32 - 32); + add_bouncy_distro(posx, posy); play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); player_status.score = player_status.score + SCORE_DISTRO; player_status.distros++; @@ -476,14 +519,18 @@ World::tryemptybox(float x, float y, int col_side) case 2: // Add an upgrade! if (tux.size == SMALL) /* Tux is small, add mints! */ - add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_MINTS); - else /* Tux is big, add coffee: */ - add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_COFFEE); + add_upgrade(posx, posy, col_side, UPGRADE_GROWUP); + else /* Tux is big, add an iceflower: */ + add_upgrade(posx, posy, col_side, UPGRADE_ICEFLOWER); play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER); break; case 3: // Add a golden herring - add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_HERRING); + add_upgrade(posx, posy, col_side, UPGRADE_HERRING); + break; + + case 4: // Add a 1up extra + add_upgrade(posx, posy, col_side, UPGRADE_1UP); break; default: break; @@ -518,18 +565,17 @@ World::trygrabdistro(float x, float y, int bounciness) void World::trybumpbadguy(float x, float y) { - /* Bad guys: */ - for (unsigned int i = 0; i < bad_guys.size(); i++) + // Bad guys: + for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) { - if (bad_guys[i].base.x >= x - 32 && bad_guys[i].base.x <= x + 32 && - bad_guys[i].base.y >= y - 16 && bad_guys[i].base.y <= y + 16) + if ((*i)->base.x >= x - 32 && (*i)->base.x <= x + 32 && + (*i)->base.y >= y - 16 && (*i)->base.y <= y + 16) { - bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP); + (*i)->collision(&tux, CO_PLAYER, COLLISION_BUMP); } } - - /* Upgrades: */ + // Upgrades: for (unsigned int i = 0; i < upgrades.size(); i++) { if (upgrades[i].base.height == 32 &&