From: Ingo Ruhnke Date: Sat, 10 Apr 2004 22:01:27 +0000 (+0000) Subject: - moved lots of code around, made gameloop even more into a class X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=90f6c152912be384311abba3848ac1c0d7d3919a;p=supertux.git - moved lots of code around, made gameloop even more into a class SVN-Revision: 459 --- diff --git a/src/gameloop.cpp b/src/gameloop.cpp index e9b402fc2..fc3e73c77 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -10,6 +10,7 @@ April 11, 2000 - March 15, 2004 */ +#include #include #include #include @@ -44,7 +45,6 @@ /* extern variables */ -Level current_level; int game_started = false; /* Local variables: */ @@ -61,8 +61,9 @@ static unsigned int update_time; static int pause_menu_frame; static int debug_fps; -/* Local function prototypes: */ +GameSession* GameSession::current_ = 0; +/* Local function prototypes: */ void levelintro(void); void loadshared(void); void unloadshared(void); @@ -70,7 +71,74 @@ void drawstatus(void); void drawendscreen(void); void drawresultscreen(void); -void levelintro(void) +GameSession::GameSession() +{ + current_ = this; + assert(0); +} + +GameSession::GameSession(const std::string& filename) +{ + current_ = this; + + timer_init(&fps_timer, true); + timer_init(&frame_timer, true); + + current_level.load(filename); +} + +GameSession::GameSession(const std::string& subset, int levelnb, int mode) +{ + current_ = this; + + timer_init(&fps_timer, true); + timer_init(&frame_timer, true); + + game_started = true; + + st_gl_mode = mode; + level = levelnb; + + /* Init the game: */ + arrays_free(); + set_defaults(); + + strcpy(level_subset, subset.c_str()); + + if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE) + { + if (current_level.load(level_subset)) + exit(1); + } + else + { + if(current_level.load(level_subset, level) != 0) + exit(1); + } + + current_level.load_gfx(); + loadshared(); + activate_bad_guys(¤t_level); + activate_particle_systems(); + current_level.load_song(); + + tux.init(); + + if(st_gl_mode != ST_GL_TEST) + load_hs(); + + if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE) + levelintro(); + + timer_init(&time_left,true); + start_timers(); + + if(st_gl_mode == ST_GL_LOAD_GAME) + loadgame(levelnb); +} + +void +GameSession::levelintro(void) { char str[60]; /* Level Intro: */ @@ -92,7 +160,8 @@ void levelintro(void) } /* Reset Timers */ -void start_timers(void) +void +GameSession::start_timers() { timer_start(&time_left,current_level.time_left*1000); st_pause_ticks_init(); @@ -109,7 +178,8 @@ void activate_bad_guys(Level* plevel) } } -void activate_particle_systems(void) +void +GameSession::activate_particle_systems() { if(current_level.particle_system == "clouds") { @@ -125,9 +195,8 @@ void activate_particle_systems(void) } } -/* --- GAME EVENT! --- */ - -void game_event(void) +void +GameSession::process_events() { while (SDL_PollEvent(&event)) { @@ -294,14 +363,9 @@ void game_event(void) } /* while */ } -/* --- GAME ACTION! --- */ - int GameSession::action() { - unsigned int i; - - /* (tux.is_dead() || next_level) */ if (tux.is_dead() || next_level) { /* Tux either died, or reached the end of a level! */ @@ -388,21 +452,14 @@ GameSession::action() tux.action(); /* Handle bouncy distros: */ - for (i = 0; i < bouncy_distros.size(); i++) - { - bouncy_distro_action(&bouncy_distros[i]); - } - + for (unsigned int i = 0; i < bouncy_distros.size(); i++) + bouncy_distro_action(&bouncy_distros[i]); /* Handle broken bricks: */ - for (i = 0; i < broken_bricks.size(); i++) - { + for (unsigned int i = 0; i < broken_bricks.size(); i++) broken_brick_action(&broken_bricks[i]); - } - /* Handle distro counting: */ - if (counting_distros) { distro_counter--; @@ -411,44 +468,21 @@ GameSession::action() counting_distros = -1; } + // Handle all kinds of game objects + for (unsigned int i = 0; i < bouncy_bricks.size(); i++) + bouncy_brick_action(&bouncy_bricks[i]); + + for (unsigned int i = 0; i < floating_scores.size(); i++) + floating_score_action(&floating_scores[i]); - /* Handle bouncy bricks: */ - - for (i = 0; i < bouncy_bricks.size(); i++) - { - bouncy_brick_action(&bouncy_bricks[i]); - } - - - /* Handle floating scores: */ - - for (i = 0; i < floating_scores.size(); i++) - { - floating_score_action(&floating_scores[i]); - } - - - /* Handle bullets: */ - - for (i = 0; i < bullets.size(); ++i) - { - bullet_action(&bullets[i]); - } - - /* Handle upgrades: */ - - for (i = 0; i < upgrades.size(); i++) - { - upgrade_action(&upgrades[i]); - } - - - /* Handle bad guys: */ + for (unsigned int i = 0; i < bullets.size(); ++i) + bullet_action(&bullets[i]); + + for (unsigned int i = 0; i < upgrades.size(); i++) + upgrade_action(&upgrades[i]); - for (i = 0; i < bad_guys.size(); i++) - { - bad_guys[i].action(); - } + for (unsigned int i = 0; i < bad_guys.size(); i++) + bad_guys[i].action(); /* update particle systems */ std::vector::iterator p; @@ -579,59 +613,12 @@ GameSession::draw() updatescreen(); } -/* --- GAME LOOP! --- */ - -GameSession::GameSession(const char * subset, int levelnb, int mode) -{ - timer_init(&fps_timer, true); - timer_init(&frame_timer, true); - - game_started = true; - - st_gl_mode = mode; - level = levelnb; - - /* Init the game: */ - arrays_free(); - set_defaults(); - - strcpy(level_subset,subset); - - if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE) - { - if (current_level.load(level_subset)) - exit(1); - } - else - { - if(current_level.load(level_subset, level) != 0) - exit(1); - } - - current_level.load_gfx(); - loadshared(); - activate_bad_guys(¤t_level); - activate_particle_systems(); - current_level.load_song(); - - tux.init(); - - if(st_gl_mode != ST_GL_TEST) - load_hs(); - - if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE) - levelintro(); - - timer_init(&time_left,true); - start_timers(); - - if(st_gl_mode == ST_GL_LOAD_GAME) - loadgame(levelnb); -} int GameSession::run() { + current_ = this; + int fps_cnt; bool jump; bool done; @@ -677,7 +664,7 @@ GameSession::run() tux.input.old_fire = tux.input.fire; - game_event(); + process_events(); if(show_menu) { @@ -1198,50 +1185,7 @@ void drawshape(float x, float y, unsigned int c, Uint8 alpha) } } -/* Break a brick: */ -void trybreakbrick(float x, float y, bool small) -{ - Tile* tile = gettile(x, y); - if (tile->brick) - { - if (tile->data > 0) - { - /* Get a distro from it: */ - add_bouncy_distro(((int)(x + 1) / 32) * 32, - (int)(y / 32) * 32); - - if (!counting_distros) - { - counting_distros = true; - distro_counter = 50; - } - - if (distro_counter <= 0) - current_level.change(x, y, TM_IA, tile->next_tile); - - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); - score = score + SCORE_DISTRO; - distros++; - } - else if (!small) - { - /* Get rid of it: */ - current_level.change(x, y, TM_IA, tile->next_tile); - - /* Replace it with broken bits: */ - add_broken_brick(((int)(x + 1) / 32) * 32, - (int)(y / 32) * 32); - - /* Get some score: */ - play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER); - score = score + SCORE_BRICK; - } - } -} - - /* Bounce a brick: */ - void bumpbrick(float x, float y) { add_bouncy_brick(((int)(x + 1) / 32) * 32, @@ -1250,95 +1194,6 @@ void bumpbrick(float x, float y) play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER); } -/* Empty a box: */ -void tryemptybox(float x, float y, int col_side) -{ - Tile* tile = gettile(x,y); - if (!tile->fullbox) - return; - - // according to the collision side, set the upgrade direction - if(col_side == LEFT) - col_side = RIGHT; - else - col_side = LEFT; - - switch(tile->data) - { - case 1: //'A': /* Box with a distro! */ - add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32 - 32); - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); - score = score + SCORE_DISTRO; - distros++; - break; - - case 2: // 'B': /* 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); - 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); - break; - default: - break; - } - - /* Empty the box: */ - current_level.change(x, y, TM_IA, tile->next_tile); -} - -/* Try to grab a distro: */ -void trygrabdistro(float x, float y, int bounciness) -{ - Tile* tile = gettile(x, y); - if (tile && tile->distro) - { - current_level.change(x, y, TM_IA, tile->next_tile); - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); - - if (bounciness == BOUNCE) - { - add_bouncy_distro(((int)(x + 1) / 32) * 32, - (int)(y / 32) * 32); - } - - score = score + SCORE_DISTRO; - distros++; - } -} - -/* Try to bump a bad guy from below: */ -void trybumpbadguy(float x, float y) -{ - /* Bad guys: */ - for (unsigned int i = 0; i < bad_guys.size(); 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) - { - bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP); - } - } - - - /* Upgrades: */ - for (unsigned int i = 0; i < upgrades.size(); i++) - { - if (upgrades[i].base.height == 32 && - upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 && - upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16) - { - upgrades[i].base.xm = -upgrades[i].base.xm; - upgrades[i].base.ym = -8; - play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER); - } - } -} - /* (Status): */ void drawstatus(void) { @@ -1426,7 +1281,8 @@ void drawresultscreen(void) wait_for_event(event,2000,5000,true); } -void savegame(int slot) +void +GameSession::savegame(int slot) { char savefile[1024]; FILE* fi; @@ -1461,7 +1317,8 @@ void savegame(int slot) } -void loadgame(int slot) +void +GameSession::loadgame(int slot) { char savefile[1024]; char str[100]; @@ -1498,10 +1355,10 @@ void loadgame(int slot) levelintro(); update_time = st_get_ticks(); - fread(&score,sizeof(int),1,fi); - fread(&distros,sizeof(int),1,fi); + fread(&score, sizeof(int),1,fi); + fread(&distros, sizeof(int),1,fi); fread(&scroll_x,sizeof(float),1,fi); - fread(&tux, sizeof(Player), 1, fi); + fread(&tux, sizeof(Player), 1, fi); timer_fread(&tux.invincible_timer,fi); timer_fread(&tux.skidding_timer,fi); timer_fread(&tux.safe_timer,fi); diff --git a/src/gameloop.h b/src/gameloop.h index b7e048b2d..c0dfe0756 100644 --- a/src/gameloop.h +++ b/src/gameloop.h @@ -24,44 +24,44 @@ #define ST_GL_LOAD_GAME 2 #define ST_GL_LOAD_LEVEL_FILE 3 -// FIXME: Make this local to the gamesession -extern Level current_level; - extern int game_started; class GameSession { private: timer_type fps_timer, frame_timer; + Level current_level; public: - GameSession(const char * subset, int levelnb, int mode); + GameSession(); + GameSession(const std::string& filename); + GameSession(const std::string& subset, int levelnb, int mode); int run(); void draw(); int action(); + void process_events(); + + Level* get_level() { return ¤t_level; } + + void savegame(int slot); + void loadgame(int slot); + + static GameSession* current() { return current_; } + private: + static GameSession* current_; + + void levelintro(); + void start_timers(); + void activate_particle_systems(); }; void activate_bad_guys(Level* plevel); -void savegame(int slot); -void loadgame(int slot); + std::string slotinfo(int slot); bool rectcollision(base_type* one, base_type* two); void drawshape(float x, float y, unsigned int c, Uint8 alpha = 255); void bumpbrick(float x, float y); -/** Try to grab the coin at the given coordinates */ -void trygrabdistro(float x, float y, int bounciness); - -/** Try to break the brick at the given coordinates */ -void trybreakbrick(float x, float y, bool small); - -/** Try to get the content out of a bonus box, thus emptying it */ -void tryemptybox(float x, float y, int col_side); - -/** Try to bumb a badguy that might we walking above Tux, thus shaking - the tile which the badguy is walking on an killing him this way */ -void trybumpbadguy(float x, float y); - #endif /*SUPERTUX_GAMELOOP_H*/ diff --git a/src/level.cpp b/src/level.cpp index 8aa7e64b3..a33080f34 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -245,14 +245,14 @@ Level::load(const char *subset, int level) } int -Level::load(const char* filename) +Level::load(const std::string& filename) { FILE * fi; lisp_object_t* root_obj = 0; - fi = fopen(filename, "r"); + fi = fopen(filename.c_str(), "r"); if (fi == NULL) { - perror(filename); + perror(filename.c_str()); return -1; } @@ -262,7 +262,7 @@ Level::load(const char* filename) if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR) { - printf("World: Parse Error in file %s", filename); + printf("World: Parse Error in file %s", filename.c_str()); } vector ia_tm; @@ -691,7 +691,8 @@ Level::load_song() } -unsigned int gettileid(float x, float y) +unsigned int +Level::gettileid(float x, float y) { int xx, yy; unsigned int c; @@ -699,8 +700,8 @@ unsigned int gettileid(float x, float y) yy = ((int)y / 32); xx = ((int)x / 32); - if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width) - c = current_level.ia_tiles[yy][xx]; + if (yy >= 0 && yy < 15 && xx >= 0 && xx <= width) + c = ia_tiles[yy][xx]; else c = 0; @@ -709,36 +710,36 @@ unsigned int gettileid(float x, float y) Tile* gettile(float x, float y) { - return TileManager::instance()->get(gettileid(x, y)); + return TileManager::instance()->get(GameSession::current()->get_level()->gettileid(x, y)); } bool issolid(float x, float y) { - Tile* tile = TileManager::instance()->get(gettileid(x,y)); + Tile* tile = gettile(x,y); return tile && tile->solid; } bool isbrick(float x, float y) { - Tile* tile = TileManager::instance()->get(gettileid(x,y)); + Tile* tile = gettile(x,y); return tile && tile->brick; } bool isice(float x, float y) { - Tile* tile = TileManager::instance()->get(gettileid(x,y)); + Tile* tile = gettile(x,y); return tile && tile->ice; } bool isfullbox(float x, float y) { - Tile* tile = TileManager::instance()->get(gettileid(x,y)); + Tile* tile = gettile(x,y); return tile && tile->fullbox; } bool isdistro(float x, float y) { - Tile* tile = TileManager::instance()->get(gettileid(x,y)); + Tile* tile = gettile(x,y); return tile && tile->distro; } diff --git a/src/level.h b/src/level.h index dc946adf9..ad15356f8 100644 --- a/src/level.h +++ b/src/level.h @@ -82,7 +82,7 @@ class Level void cleanup(); int load(const char* subset, int level); - int load(const char* filename); + int load(const std::string& filename); void load_gfx(); void load_song(); @@ -94,15 +94,15 @@ class Level /** Resize the level to a new width */ void change_size (int new_width); + + /** Return the id of the tile at position x/y */ + unsigned int gettileid(float x, float y); }; void level_load_image(texture_type* ptexture, std::string theme, const char * file, int use_alpha); void level_free_song(); void level_free_gfx(); -/** Return the id of the tile at the given x/y coordinates */ -unsigned int gettileid(float x, float y); - /** Return a pointer to the tile at the given x/y coordinates */ Tile* gettile(float x, float y); diff --git a/src/player.cpp b/src/player.cpp index ea91fcd16..d6b09bd41 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -914,6 +914,8 @@ Player::remove_powerups() void Player::keep_in_bounds() { + Level* plevel = GameSession::current()->get_level(); + /* Keep tux in bounds: */ if (base.x< 0) base.x= 0; @@ -928,14 +930,17 @@ Player::keep_in_bounds() scroll_x = 0; } - else if (base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w)) + else if (base.x > screen->w / 2 + scroll_x + && scroll_x < ((GameSession::current()->get_level()->width * 32) - screen->w)) { - // Scroll the screen in past center: + // FIXME: Scrolling needs to be handled by a seperate View + // class, doing it as a player huck is ugly + // Scroll the screen in past center: scroll_x = base.x - screen->w / 2; - if (scroll_x > ((current_level.width * 32) - screen->w)) - scroll_x = ((current_level.width * 32) - screen->w); + if (scroll_x > ((plevel->width * 32) - screen->w)) + scroll_x = ((plevel->width * 32) - screen->w); } else if (base.x> 608 + scroll_x) { diff --git a/src/setup.cpp b/src/setup.cpp index 1e1b22b63..421bcec5d 100644 --- a/src/setup.cpp +++ b/src/setup.cpp @@ -453,7 +453,7 @@ void process_save_game_menu() { int slot = save_game_menu->check(); if (slot != -1) - savegame(slot - 1); + GameSession::current()->savegame(slot - 1); } bool process_load_game_menu() @@ -486,7 +486,8 @@ bool process_load_game_menu() } else { - loadgame(slot - 1); + //loadgame(slot - 1); + puts("Warning: Loading games isn't supported at the moment"); } } st_pause_ticks_stop(); diff --git a/src/special.cpp b/src/special.cpp index 53b372fb6..2e5a05a01 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -52,28 +52,28 @@ void bullet_init(bullet_type* pbullet, float x, float y, float xm, int dir) void bullet_action(bullet_type* pbullet) { - pbullet->base.x = pbullet->base.x + pbullet->base.xm * frame_ratio; - pbullet->base.y = pbullet->base.y + pbullet->base.ym * frame_ratio; + pbullet->base.x = pbullet->base.x + pbullet->base.xm * frame_ratio; + pbullet->base.y = pbullet->base.y + pbullet->base.ym * frame_ratio; - collision_swept_object_map(&pbullet->old_base,&pbullet->base); + collision_swept_object_map(&pbullet->old_base,&pbullet->base); - if (issolid(pbullet->base.x, pbullet->base.y + 4) || issolid(pbullet->base.x, pbullet->base.y)) - { - pbullet->base.ym = -pbullet->base.ym; - pbullet->base.y = (int)(pbullet->base.y / 32) * 32; - } + if (issolid(pbullet->base.x, pbullet->base.y + 4) || issolid(pbullet->base.x, pbullet->base.y)) + { + pbullet->base.ym = -pbullet->base.ym; + pbullet->base.y = (int)(pbullet->base.y / 32) * 32; + } - pbullet->base.ym = pbullet->base.ym + GRAVITY; + pbullet->base.ym = pbullet->base.ym + GRAVITY; - if (pbullet->base.x < scroll_x || - pbullet->base.x > scroll_x + screen->w || - pbullet->base.y < 0 || - pbullet->base.y > screen->h || - issolid(pbullet->base.x + 4, pbullet->base.y + 2) || - issolid(pbullet->base.x, pbullet->base.y + 2)) - { - bullets.erase(static_cast::iterator>(pbullet)); - } + if (pbullet->base.x < scroll_x || + pbullet->base.x > scroll_x + screen->w || + pbullet->base.y < 0 || + pbullet->base.y > screen->h || + issolid(pbullet->base.x + 4, pbullet->base.y + 2) || + issolid(pbullet->base.x, pbullet->base.y + 2)) + { + bullets.erase(static_cast::iterator>(pbullet)); + } } @@ -92,10 +92,10 @@ void bullet_collision(bullet_type* pbullet, int c_object) if(c_object == CO_BADGUY) { std::vector::iterator i; for(i = bullets.begin(); i != bullets.end(); ++i) { - if(& (*i) == pbullet) { - bullets.erase(i); - return; - } + if(& (*i) == pbullet) { + bullets.erase(i); + return; + } } } } @@ -120,105 +120,105 @@ void upgrade_action(upgrade_type *pupgrade) { - if (pupgrade->base.height < 32) - { - /* Rise up! */ + if (pupgrade->base.height < 32) + { + /* Rise up! */ - pupgrade->base.height = pupgrade->base.height + 0.7 * frame_ratio; - if(pupgrade->base.height > 32) - pupgrade->base.height = 32; - } - else - { - /* Move around? */ + pupgrade->base.height = pupgrade->base.height + 0.7 * frame_ratio; + if(pupgrade->base.height > 32) + pupgrade->base.height = 32; + } + else + { + /* Move around? */ - if (pupgrade->kind == UPGRADE_MINTS || - pupgrade->kind == UPGRADE_HERRING) - { - pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio; - pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio; + if (pupgrade->kind == UPGRADE_MINTS || + pupgrade->kind == UPGRADE_HERRING) + { + pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio; + pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio; - collision_swept_object_map(&pupgrade->old_base,&pupgrade->base); + collision_swept_object_map(&pupgrade->old_base,&pupgrade->base); - /* Off the screen? Kill it! */ + /* Off the screen? Kill it! */ - if (pupgrade->base.x < scroll_x - pupgrade->base.width) - upgrades.erase(static_cast::iterator>(pupgrade)); - if (pupgrade->base.y > screen->h) - upgrades.erase(static_cast::iterator>(pupgrade)); + if (pupgrade->base.x < scroll_x - pupgrade->base.width) + upgrades.erase(static_cast::iterator>(pupgrade)); + if (pupgrade->base.y > screen->h) + upgrades.erase(static_cast::iterator>(pupgrade)); - if (issolid(pupgrade->base.x + 1, pupgrade->base.y + 32.) || - issolid(pupgrade->base.x + 31., pupgrade->base.y + 32.)) + if (issolid(pupgrade->base.x + 1, pupgrade->base.y + 32.) || + issolid(pupgrade->base.x + 31., pupgrade->base.y + 32.)) + { + if (pupgrade->base.ym > 0) { - if (pupgrade->base.ym > 0) + if (pupgrade->kind == UPGRADE_MINTS) { - if (pupgrade->kind == UPGRADE_MINTS) - { - pupgrade->base.ym = 0; - } - else if (pupgrade->kind == UPGRADE_HERRING) - { - pupgrade->base.ym = -8; - } - - pupgrade->base.y = (int)(pupgrade->base.y / 32) * 32; + pupgrade->base.ym = 0; + } + else if (pupgrade->kind == UPGRADE_HERRING) + { + pupgrade->base.ym = -8; } - } - else - pupgrade->base.ym = pupgrade->base.ym + GRAVITY * frame_ratio; - if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y)) - { - if(pupgrade->base.xm < 0) - pupgrade->base.xm = -pupgrade->base.xm; - } - else if (issolid(pupgrade->base.x + pupgrade->base.width, (int) pupgrade->base.y)) - { - if(pupgrade->base.xm > 0) - pupgrade->base.xm = -pupgrade->base.xm; + pupgrade->base.y = (int)(pupgrade->base.y / 32) * 32; } } + else + pupgrade->base.ym = pupgrade->base.ym + GRAVITY * frame_ratio; + if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y)) + { + if(pupgrade->base.xm < 0) + pupgrade->base.xm = -pupgrade->base.xm; + } + else if (issolid(pupgrade->base.x + pupgrade->base.width, (int) pupgrade->base.y)) + { + if(pupgrade->base.xm > 0) + pupgrade->base.xm = -pupgrade->base.xm; + } } + + } } void upgrade_draw(upgrade_type* pupgrade) { SDL_Rect dest; - if (pupgrade->base.height < 32) + if (pupgrade->base.height < 32) + { + /* Rising up... */ + + dest.x = (int)(pupgrade->base.x - scroll_x); + dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height); + dest.w = 32; + dest.h = (int)pupgrade->base.height; + + if (pupgrade->kind == UPGRADE_MINTS) + texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h); + else if (pupgrade->kind == UPGRADE_COFFEE) + texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h); + else if (pupgrade->kind == UPGRADE_HERRING) + texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h); + } + else + { + if (pupgrade->kind == UPGRADE_MINTS) { - /* Rising up... */ - - dest.x = (int)(pupgrade->base.x - scroll_x); - dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height); - dest.w = 32; - dest.h = (int)pupgrade->base.height; - - if (pupgrade->kind == UPGRADE_MINTS) - texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h); - else if (pupgrade->kind == UPGRADE_COFFEE) - texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h); - else if (pupgrade->kind == UPGRADE_HERRING) - texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h); + texture_draw(&img_mints, + pupgrade->base.x - scroll_x, pupgrade->base.y); } - else + else if (pupgrade->kind == UPGRADE_COFFEE) { - if (pupgrade->kind == UPGRADE_MINTS) - { - texture_draw(&img_mints, - pupgrade->base.x - scroll_x, pupgrade->base.y); - } - else if (pupgrade->kind == UPGRADE_COFFEE) - { - texture_draw(&img_coffee, - pupgrade->base.x - scroll_x, pupgrade->base.y); - } - else if (pupgrade->kind == UPGRADE_HERRING) - { - texture_draw(&img_golden_herring, - pupgrade->base.x - scroll_x, pupgrade->base.y); - } + texture_draw(&img_coffee, + pupgrade->base.x - scroll_x, pupgrade->base.y); } + else if (pupgrade->kind == UPGRADE_HERRING) + { + texture_draw(&img_golden_herring, + pupgrade->base.x - scroll_x, pupgrade->base.y); + } + } } void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object) @@ -244,11 +244,11 @@ void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object) pplayer->base.height = 64; pplayer->base.y -= 32; if(collision_object_map(&pplayer->base)) - { - pplayer->base.height = 32; - pplayer->base.y += 32; - pplayer->duck = true; - } + { + pplayer->base.height = 32; + pplayer->base.y += 32; + pplayer->duck = true; + } timer_start(&super_bkgd_timer, 350); } else if (pupgrade->kind == UPGRADE_COFFEE) diff --git a/src/title.cpp b/src/title.cpp index 263b18879..b90a631a5 100644 --- a/src/title.cpp +++ b/src/title.cpp @@ -40,7 +40,6 @@ #include "math.h" void loadshared(void); -void activate_particle_systems(void); static texture_type bkg_title; static texture_type logo; @@ -65,10 +64,10 @@ void draw_background() texture_draw_bg(&bkg_title); } -void draw_demo() +void draw_demo(Level* plevel) { - /* DEMO begin */ - /* update particle systems */ + /* FIXME: + // update particle systems std::vector::iterator p; for(p = particle_systems.begin(); p != particle_systems.end(); ++p) { @@ -80,6 +79,7 @@ void draw_demo() { (*p)->draw(scroll_x, 0, 0); } + */ // Draw interactive tiles: for (int y = 0; y < 15; ++y) @@ -87,7 +87,7 @@ void draw_demo() for (int x = 0; x < 21; ++x) { drawshape(32*x - fmodf(scroll_x, 32), y * 32, - current_level.ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]); + plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]); } } @@ -108,9 +108,9 @@ void draw_demo() } // Wrap around at the end of the level back to the beginnig - if(current_level.width * 32 - 320 < titletux.base.x) + if(plevel->width * 32 - 320 < titletux.base.x) { - titletux.base.x = titletux.base.x - (current_level.width * 32 - 640); + titletux.base.x = titletux.base.x - (plevel->width * 32 - 640); scroll_x = titletux.base.x - 320; } @@ -142,9 +142,9 @@ int title(void) st_pause_ticks_init(); - current_level.load((datadir + "/levels/misc/menu.stl").c_str()); + GameSession session(datadir + "/levels/misc/menu.stl"); loadshared(); - activate_particle_systems(); + //FIXME:activate_particle_systems(); /* Lower the gravity that tux doesn't jump to hectically through the demo */ //gravity = 5; @@ -215,8 +215,8 @@ int title(void) /* Draw the background: */ draw_background(); - draw_demo(); - + draw_demo(session.get_level()); + if (current_menu == main_menu) texture_draw(&logo, 160, 30); diff --git a/src/world.cpp b/src/world.cpp index 5a07ed601..f198e81bf 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -17,6 +17,7 @@ #include "screen.h" #include "defines.h" #include "world.h" +#include "tile.h" texture_type img_distro[4]; @@ -81,11 +82,11 @@ void broken_brick_draw(broken_brick_type* pbroken_brick) void bouncy_brick_init(bouncy_brick_type* pbouncy_brick, float x, float y) { - pbouncy_brick->base.x = x; - pbouncy_brick->base.y = y; - pbouncy_brick->offset = 0; + pbouncy_brick->base.x = x; + pbouncy_brick->base.y = y; + pbouncy_brick->offset = 0; pbouncy_brick->offset_m = -BOUNCY_BRICK_SPEED; - pbouncy_brick->shape = gettileid(x, y); + pbouncy_brick->shape = GameSession::current()->get_level()->gettileid(x, y); } void bouncy_brick_action(bouncy_brick_type* pbouncy_brick) @@ -119,13 +120,15 @@ void bouncy_brick_draw(bouncy_brick_type* pbouncy_brick) dest.w = 32; dest.h = 32; + Level* plevel = GameSession::current()->get_level(); + // FIXME: overdrawing hack to clean the tile from the screen to // paint it later at on offseted position - if(current_level.bkgd_image[0] == '\0') + if(plevel->bkgd_image[0] == '\0') { fillrect(pbouncy_brick->base.x - scroll_x, pbouncy_brick->base.y, - 32,32,current_level.bkgd_red,current_level.bkgd_green, - current_level.bkgd_blue,0); + 32,32, + plevel->bkgd_red, plevel->bkgd_green, plevel->bkgd_blue, 0); } else { @@ -163,5 +166,140 @@ void floating_score_draw(floating_score_type* pfloating_score) text_draw(&gold_text, str, (int)pfloating_score->base.x + 16 - strlen(str) * 8, (int)pfloating_score->base.y, 1); } +/* Break a brick: */ +void trybreakbrick(float x, float y, bool small) +{ + Level* plevel = GameSession::current()->get_level(); + + Tile* tile = gettile(x, y); + if (tile->brick) + { + if (tile->data > 0) + { + /* Get a distro from it: */ + add_bouncy_distro(((int)(x + 1) / 32) * 32, + (int)(y / 32) * 32); + + if (!counting_distros) + { + counting_distros = true; + distro_counter = 50; + } + + if (distro_counter <= 0) + plevel->change(x, y, TM_IA, tile->next_tile); + + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + score = score + SCORE_DISTRO; + distros++; + } + else if (!small) + { + /* Get rid of it: */ + plevel->change(x, y, TM_IA, tile->next_tile); + + /* Replace it with broken bits: */ + add_broken_brick(((int)(x + 1) / 32) * 32, + (int)(y / 32) * 32); + + /* Get some score: */ + play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER); + score = score + SCORE_BRICK; + } + } +} + +/* Empty a box: */ +void tryemptybox(float x, float y, int col_side) +{ + Level* plevel = GameSession::current()->get_level(); + + Tile* tile = gettile(x,y); + if (!tile->fullbox) + return; + + // according to the collision side, set the upgrade direction + if(col_side == LEFT) + col_side = RIGHT; + else + col_side = LEFT; + + switch(tile->data) + { + case 1: //'A': /* Box with a distro! */ + add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32 - 32); + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + score = score + SCORE_DISTRO; + distros++; + break; + + case 2: // 'B': /* 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); + 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); + break; + default: + break; + } + + /* Empty the box: */ + plevel->change(x, y, TM_IA, tile->next_tile); +} + +/* Try to grab a distro: */ +void trygrabdistro(float x, float y, int bounciness) +{ + Level* plevel = GameSession::current()->get_level(); + Tile* tile = gettile(x, y); + if (tile && tile->distro) + { + plevel->change(x, y, TM_IA, tile->next_tile); + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + + if (bounciness == BOUNCE) + { + add_bouncy_distro(((int)(x + 1) / 32) * 32, + (int)(y / 32) * 32); + } + + score = score + SCORE_DISTRO; + distros++; + } +} + +/* Try to bump a bad guy from below: */ +void trybumpbadguy(float x, float y) +{ + /* Bad guys: */ + for (unsigned int i = 0; i < bad_guys.size(); 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) + { + bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP); + } + } + + + /* Upgrades: */ + for (unsigned int i = 0; i < upgrades.size(); i++) + { + if (upgrades[i].base.height == 32 && + upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 && + upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16) + { + upgrades[i].base.xm = -upgrades[i].base.xm; + upgrades[i].base.ym = -8; + play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER); + } + } +} + /* EOF */ diff --git a/src/world.h b/src/world.h index 243ac8ec1..ce285d73a 100644 --- a/src/world.h +++ b/src/world.h @@ -69,5 +69,19 @@ void floating_score_init(floating_score_type* pfloating_score, float x, float y, void floating_score_action(floating_score_type* pfloating_score); void floating_score_draw(floating_score_type* pfloating_score); + +/** Try to grab the coin at the given coordinates */ +void trygrabdistro(float x, float y, int bounciness); + +/** Try to break the brick at the given coordinates */ +void trybreakbrick(float x, float y, bool small); + +/** Try to get the content out of a bonus box, thus emptying it */ +void tryemptybox(float x, float y, int col_side); + +/** Try to bumb a badguy that might we walking above Tux, thus shaking + the tile which the badguy is walking on an killing him this way */ +void trybumpbadguy(float x, float y); + #endif /*SUPERTUX_WORLD_H*/