From: Christoph Sommer Date: Tue, 1 Jul 2008 20:06:37 +0000 (+0000) Subject: LevelIntro screen X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=d83146487eca3bb987302662f9acd0af13572ce5;p=supertux.git LevelIntro screen SVN-Revision: 5644 --- diff --git a/src/game_session.cpp b/src/game_session.cpp index 9cf47572a..707d597ad 100644 --- a/src/game_session.cpp +++ b/src/game_session.cpp @@ -74,6 +74,7 @@ #include "object/endsequence_fireworks.hpp" #include "direction.hpp" #include "scripting/time_scheduler.hpp" +#include "levelintro.hpp" // the engine will be run with a logical framerate of 64fps. // We chose 64fps here because it is a power of 2, so 1/64 gives an "even" @@ -92,7 +93,7 @@ GameSession::GameSession(const std::string& levelfile_, Statistics* statistics) end_sequence(0), levelfile(levelfile_), best_level_statistics(statistics), capture_demo_stream(0), playback_demo_stream(0), demo_controller(0), - play_time(0), edit_mode(false) + play_time(0), edit_mode(false), levelintro_shown(false) { current_ = this; currentsector = NULL; @@ -488,6 +489,11 @@ GameSession::setup() SDL_Event event; while(SDL_PollEvent(&event)) {} + + if (!levelintro_shown) { + levelintro_shown = true; + main_loop->push_screen(new LevelIntro(level.get(), best_level_statistics)); + } } void diff --git a/src/game_session.hpp b/src/game_session.hpp index edae3a632..7350b6d61 100644 --- a/src/game_session.hpp +++ b/src/game_session.hpp @@ -148,6 +148,7 @@ private: float play_time; /**< total time in seconds that this session ran interactively */ bool edit_mode; /**< true if GameSession runs in level editor mode */ + bool levelintro_shown; /**< true if the LevelIntro screen was already shown */ }; #endif /*SUPERTUX_GAMELOOP_H*/ diff --git a/src/levelintro.cpp b/src/levelintro.cpp new file mode 100644 index 000000000..097fceea9 --- /dev/null +++ b/src/levelintro.cpp @@ -0,0 +1,145 @@ +// $Id: textscroller.cpp 4981 2007-04-15 15:41:27Z sommer $ +// +// SuperTux -- LevelIntro screen +// Copyright (C) 2008 Christoph Sommer +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// 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. +#include + +#include "levelintro.hpp" + +#include +#include "log.hpp" +#include "mainloop.hpp" +#include "gettext.hpp" +#include "resources.hpp" +#include "video/font.hpp" +#include "video/drawing_context.hpp" +#include "gui/menu.hpp" +#include "main.hpp" +#include "fadeout.hpp" +#include "control/joystickkeyboardcontroller.hpp" +#include "sprite/sprite_manager.hpp" +#include "random_generator.hpp" + + +static const float DEFAULT_SPEED = 20; +static const float LEFT_BORDER = 50; +static const float SCROLL = 60; +static const float ITEMS_SPACE = 4; + +LevelIntro::LevelIntro(const Level* level, const Statistics* best_level_statistics) + : level(level), best_level_statistics(best_level_statistics), player_sprite_py(0), player_sprite_vy(0) +{ + player_sprite.reset(sprite_manager->create("images/creatures/tux/tux.sprite")); + player_sprite->set_action("small-walk-right"); + player_sprite_jump_timer.start(systemRandom.randf(5,10)); +} + +LevelIntro::~LevelIntro() +{ +} + +void +LevelIntro::setup() +{ + Menu::set_current(NULL); +} + +void +LevelIntro::update(float elapsed_time) +{ + + // Check if it's time to exit the screen + if(main_controller->pressed(Controller::JUMP) + || main_controller->pressed(Controller::ACTION) + || main_controller->pressed(Controller::MENU_SELECT) + || main_controller->pressed(Controller::PAUSE_MENU)) { + main_loop->exit_screen(new FadeOut(0.1)); + } + + player_sprite_py += player_sprite_vy * elapsed_time; + player_sprite_vy += 1000 * elapsed_time; + if (player_sprite_py >= 0) { + player_sprite_py = 0; + player_sprite_vy = 0; + } + if (player_sprite_jump_timer.check()) { + player_sprite_vy = -300; + player_sprite_jump_timer.start(systemRandom.randf(2,3)); + } + +} + +void +LevelIntro::draw(DrawingContext& context) +{ + const Statistics& stats = level->stats; + int py = SCREEN_HEIGHT / 2 - gold_text->get_height() / 2; + + context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT), Color(0.0f, 0.0f, 0.0f, 1.0f), 0); + + { + context.draw_center_text(gold_text, level->get_name(), Vector(0, py), LAYER_FOREGROUND1); + py += gold_text->get_height(); + } + + std::string author = level->get_author(); + if ((author != "") && (author != "SuperTux Team")) { + std::string author_text = std::string(_("contributed by ")) + author; + context.draw_center_text(white_small_text, author_text, Vector(0, py), LAYER_FOREGROUND1); + py += white_small_text->get_height(); + } + + py += 32; + + { + player_sprite->draw(context, Vector((SCREEN_WIDTH - player_sprite->get_current_hitbox_width()) / 2, py + player_sprite_py), LAYER_FOREGROUND1); + py += player_sprite->get_current_hitbox_height(); + } + + py += 32; + + { + context.draw_center_text(blue_text, std::string("- ") + _("Best Level Statistics") + std::string(" -"), Vector(0, py), LAYER_FOREGROUND1); + py += blue_text->get_height(); + } + + { + std::stringstream ss; + ss << _("Coins") << ": " << Statistics::coins_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->coins : 0, stats.total_coins); + context.draw_center_text(white_text, ss.str(), Vector(0, py), LAYER_FOREGROUND1); + py += white_text->get_height(); + } + + { + std::stringstream ss; + ss << _("Secrets") << ": " << Statistics::secrets_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->secrets : 0, stats.total_secrets); + context.draw_center_text(white_text, ss.str(), Vector(0, py), LAYER_FOREGROUND1); + py += white_text->get_height(); + } + + { + std::stringstream ss; + ss << _("Time") << ": " << Statistics::time_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->time : 0); + context.draw_center_text(white_text, ss.str(), Vector(0, py), LAYER_FOREGROUND1); + py += white_text->get_height(); + } + + py += 32; + + +} diff --git a/src/levelintro.hpp b/src/levelintro.hpp new file mode 100644 index 000000000..960630d4d --- /dev/null +++ b/src/levelintro.hpp @@ -0,0 +1,62 @@ +// $Id: textscroller.hpp 5330 2008-02-18 19:30:28Z sommer $ +// +// SuperTux -- LevelIntro screen +// Copyright (C) 2008 Christoph Sommer +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// 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. + +#ifndef __LEVELINTRO_H__ +#define __LEVELINTRO_H__ + +#include +#include +#include +#include + +#include "screen.hpp" +#include "math/vector.hpp" +#include "math/rect.hpp" +#include "level.hpp" +#include "sprite/sprite.hpp" +#include "timer.hpp" + +class DrawingContext; +class Surface; +class Font; + +/** + * Screen that welcomes the player to a level + */ +class LevelIntro : public Screen +{ +public: + LevelIntro(const Level* level, const Statistics* best_level_statistics); + virtual ~LevelIntro(); + + void setup(); + void draw(DrawingContext& context); + void update(float elapsed_time); + +private: + const Level* level; /**< The level of which this is the intro screen */ + const Statistics* best_level_statistics; /**< Best level statistics of the level of which is the intro screen */ + std::auto_ptr player_sprite; /**< Sprite representing the player */ + float player_sprite_py; /**< Position (y axis) for the player sprite */ + float player_sprite_vy; /**< Velocity (y axis) for the player sprite */ + Timer player_sprite_jump_timer; /**< When timer fires, the player sprite will "jump" */ +}; + +#endif diff --git a/src/mainloop.cpp b/src/mainloop.cpp index 6a9bb042d..1a7a1324a 100644 --- a/src/mainloop.cpp +++ b/src/mainloop.cpp @@ -253,9 +253,11 @@ MainLoop::handle_screen_switch() nextpush = false; nextpop = false; speed = 1.0; - if(next_screen.get() != NULL) - next_screen->setup(); - current_screen.reset(next_screen.release()); + Screen* next_screen_ptr = next_screen.release(); + next_screen.reset(0); + if(next_screen_ptr) + next_screen_ptr->setup(); + current_screen.reset(next_screen_ptr); screen_fade.reset(NULL); waiting_threads.wakeup(); diff --git a/src/statistics.cpp b/src/statistics.cpp index fbfa94d54..4298fc9f7 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -285,7 +285,7 @@ Statistics::reset() } void -Statistics::merge(Statistics& s2) +Statistics::merge(const Statistics& s2) { if (!s2.valid) return; coins = std::max(coins, s2.coins); @@ -317,21 +317,21 @@ Statistics::declare_invalid() } std::string -Statistics::coins_to_string(int coins, int total_coins) const { +Statistics::coins_to_string(int coins, int total_coins) { std::ostringstream os; os << std::min(coins, 999) << "/" << std::min(total_coins, 999); return os.str(); } std::string -Statistics::frags_to_string(int badguys, int total_badguys) const { +Statistics::frags_to_string(int badguys, int total_badguys) { std::ostringstream os; os << std::min(badguys, 999) << "/" << std::min(total_badguys, 999); return os.str(); } std::string -Statistics::time_to_string(float time) const { +Statistics::time_to_string(float time) { int time_csecs = std::min(static_cast(time * 100), 99 * 6000 + 9999); int mins = (time_csecs / 6000); int secs = (time_csecs % 6000) / 100; @@ -343,7 +343,7 @@ Statistics::time_to_string(float time) const { } std::string -Statistics::secrets_to_string(int secrets, int total_secrets) const { +Statistics::secrets_to_string(int secrets, int total_secrets) { std::ostringstream os; os << std::min(secrets, 999) << "/" << std::min(total_secrets, 999); return os.str(); diff --git a/src/statistics.hpp b/src/statistics.hpp index e2a219571..38c4f3e24 100644 --- a/src/statistics.hpp +++ b/src/statistics.hpp @@ -68,18 +68,19 @@ public: void zero(); /**< Set stats to zero */ void reset(); /**< Set stats (but not totals) to zero */ - void merge(Statistics& stats); /**< Given another Statistics object finds the best of each one */ + void merge(const Statistics& stats); /**< Given another Statistics object finds the best of each one */ void operator+=(const Statistics& o); /**< Add two Statistics objects */ void declare_invalid(); /**< marks statistics as invalid for their entire lifetime (e.g. after cheating). Invalid statistics will not be merged or drawn. */ + + static std::string coins_to_string(int coins, int total_coins); + static std::string frags_to_string(int badguys, int total_badguys); + static std::string time_to_string(float time); + static std::string secrets_to_string(int secrets, int total_secrets); private: bool valid; /**< stores whether these statistics can be trusted */ - std::string coins_to_string(int coins, int total_coins) const; - std::string frags_to_string(int badguys, int total_badguys) const; - std::string time_to_string(float time) const; - std::string secrets_to_string(int secrets, int total_secrets) const; }; #endif /*SUPERTUX_STATISTICS_H*/