These are mostly bugs:
-- supertux crashs from time to time
+- supertux crashs from time to time - fixed
- leveleditor lacks enemies support (will be fixed soon by Tobias)
-- sometimes you die after being in pause modus and unpausing
-- sometimes the level restarts/you die after collecing a growup
+- sometimes you die after being in pause modus and unpausing - still true?
+- sometimes the level restarts/you die after collecing a growup - fixed
- mriceblock doesn't disapear after being kicked my another iceblock,
- not sure when exactly it happens, might depend on direction or so
+ not sure when exactly it happens, might depend on direction or so - fixed
+- mriceblock doesn't fall down when being squished in the air - fixed
+- It's not possible to duck while jumping - fixed
+- Intro/Extro textspeed is CPU dependent - fixed
- fadein/out for intro/extro would be nice
-
{
Player& tux = *World::current()->get_tux();
- if(dying == DYING_NOT)
+ if(mode != HELD)
fall();
/* Move left/right: */
- if (mode == NORMAL || mode == KICK)
+ if (mode != HELD)
{
// move
physic.apply(frame_ratio, base.x, base.y);
GameSession* GameSession::current_ = 0;
GameSession::GameSession(const std::string& subset_, int levelnb_, int mode)
- : world(0), st_gl_mode(mode), levelnb(levelnb_), end_sequence(false),
+ : world(0), st_gl_mode(mode), levelnb(levelnb_), end_sequence(NO_ENDSEQUENCE),
subset(subset_)
{
current_ = this;
{
game_pause = false;
exit_status = NONE;
- end_sequence = false;
+ end_sequence = NO_ENDSEQUENCE;
fps_timer.init(true);
frame_timer.init(true);
void
GameSession::process_events()
{
- if (end_sequence)
+ if (end_sequence != NO_ENDSEQUENCE)
{
Player& tux = *world->get_tux();
-
+
+ tux.input.fire = UP;
tux.input.left = UP;
- tux.input.right = DOWN;
+ tux.input.right = DOWN;
tux.input.down = UP;
if (int(last_x_pos) == int(tux.base.x))
}
}
}
- else
+ else // normal mode
{
if(!Menu::current() && !game_pause)
st_pause_ticks_stop();
Tile* endtile = collision_goal(tux->base);
// fallback in case the other endpositions don't trigger
- if (tux->base.x >= endpos || (endtile && endtile->data >= 1)
- || (end_sequence && !endsequence_timer.check()))
+ if (!end_sequence && tux->base.x >= endpos)
+ {
+ end_sequence = ENDSEQUENCE_WAITING;
+ last_x_pos = -1;
+ music_manager->play_music(level_end_song, 0);
+ endsequence_timer.start(7000);
+ }
+ else if(end_sequence && !endsequence_timer.check())
{
exit_status = LEVEL_FINISHED;
return;
}
+ else if(end_sequence == ENDSEQUENCE_RUNNING && endtile && endtile->data >= 1)
+ {
+ end_sequence = ENDSEQUENCE_WAITING;
+ }
else if(!end_sequence && endtile && endtile->data == 0)
{
- end_sequence = true;
+ end_sequence = ENDSEQUENCE_RUNNING;
last_x_pos = -1;
- music_manager->halt_music();
- music_manager->play_music(level_end_song);
- endsequence_timer.start(5000); // 5 seconds until we finish the map
+ music_manager->play_music(level_end_song, 0);
+ endsequence_timer.start(7000); // 5 seconds until we finish the map
}
else if (!end_sequence && tux->is_dead())
{
void
GameSession::action(double frame_ratio)
{
- check_end_conditions();
-
if (exit_status == NONE)
{
// Update Tux and the World
while (frame_ratio > 0)
{
// Update the world
- if (end_sequence)
+ check_end_conditions();
+ if (end_sequence == ENDSEQUENCE_RUNNING)
action(.5f);
- else
+ else if(end_sequence == NO_ENDSEQUENCE)
action(1.0f);
frame_ratio -= 1.0f;
}
/** If true the end_sequence will be played, user input will be
ignored while doing that */
- bool end_sequence;
+ enum EndSequenceState {
+ NO_ENDSEQUENCE,
+ ENDSEQUENCE_RUNNING, // tux is running right
+ ENDSEQUENCE_WAITING // waiting for the end of the music
+ };
+ EndSequenceState end_sequence;
float last_x_pos;
bool game_pause;
}
void
-MusicManager::play_music(const MusicRef& musicref)
+MusicManager::play_music(const MusicRef& musicref, int loops)
{
if(!audio_device)
return;
current_music->refcount++;
if(music_enabled)
- Mix_PlayMusic(current_music->music, -1);
+ Mix_PlayMusic(current_music->music, loops);
}
void
MusicRef load_music(const std::string& file);
bool exists_music(const std::string& filename);
- void play_music(const MusicRef& music);
+ void play_music(const MusicRef& music, int loops = -1);
void halt_music();
void enable_music(bool enable);
duck = false;
base.y -= 32;
base.height = 64;
- old_base = previous_base = base;
}
}
void
+Player::grow()
+{
+ if(size == BIG)
+ return;
+
+ size = BIG;
+ base.height = 64;
+ base.y -= 32;
+ // eventually go in duck mode if there's no space
+ if(collision_object_map(base))
+ {
+ base.height = 32;
+ base.y += 32;
+ duck = true;
+ }
+
+ old_base = previous_base = base;
+}
+
+void
Player::grabdistros()
{
/* Grab distros: */
void keep_in_bounds();
bool on_ground();
bool under_solid();
+ void grow();
private:
void handle_horizontal_input();
if (kind == UPGRADE_GROWUP)
{
play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER);
- pplayer->size = BIG;
- pplayer->base.height = 64;
- pplayer->base.y -= 32;
+ pplayer->grow();
}
else if (kind == UPGRADE_ICEFLOWER)
{
play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER);
+ pplayer->grow();
pplayer->got_coffee = true;
- if (pplayer->size == SMALL)
- {
- pplayer->size = BIG;
- pplayer->base.height = 64;
- pplayer->base.y -= 32;
- }
}
else if (kind == UPGRADE_HERRING)
{
/* --- SCROLL TEXT FUNCTION --- */
#define MAX_VEL 10
-#define SPEED_INC 1.0
+#define SPEED_INC 0.01
#define SCROLL 60
#define ITEMS_SPACE 4
void display_text_file(const std::string& file, Surface* surface, float scroll_speed)
{
int done;
- int scroll;
+ float scroll;
float speed;
int y;
int length;
scroll = 0;
- speed = scroll_speed;
+ speed = scroll_speed / 50;
done = 0;
length = names.num_items;
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ Uint32 lastticks = SDL_GetTicks();
while(done == 0)
{
/* in case of input, exit */
switch(names.item[i][0])
{
case ' ':
- white_small_text->drawf(names.item[i]+1, 0, screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
+ white_small_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
+ A_HMIDDLE, A_TOP, 1);
y += white_small_text->h+ITEMS_SPACE;
break;
case ' ':
- white_text->drawf(names.item[i]+1, 0, screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
+ white_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
+ A_HMIDDLE, A_TOP, 1);
y += white_text->h+ITEMS_SPACE;
break;
case '-':
- white_big_text->drawf(names.item[i]+1, 0, screen->h+y-scroll, A_HMIDDLE, A_TOP, 3);
+ white_big_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
+ A_HMIDDLE, A_TOP, 3);
y += white_big_text->h+ITEMS_SPACE;
break;
default:
- blue_text->drawf(names.item[i], 0, screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
+ blue_text->drawf(names.item[i], 0, screen->h+y-int(scroll),
+ A_HMIDDLE, A_TOP, 1);
y += blue_text->h+ITEMS_SPACE;
break;
}
if(screen->h+y-scroll < 0 && 20+screen->h+y-scroll < 0)
done = 1;
- scroll += (int)speed;
+ Uint32 ticks = SDL_GetTicks();
+ scroll += speed * (ticks - lastticks);
+ lastticks = ticks;
if(scroll < 0)
scroll = 0;
- SDL_Delay(35);
+ SDL_Delay(10);
}
string_list_free(&names);
}
if (!level->extro_filename.empty())
- { // Display final credits and go back to the main menu
+ {
+ MusicRef theme =
+ music_manager->load_music(datadir + "/music/theme.mod");
+ music_manager->play_music(theme);
+ // Display final credits and go back to the main menu
display_text_file(level->extro_filename,
"/images/background/extro.jpg", SCROLL_SPEED_MESSAGE);
display_text_file("CREDITS",