LevelIntro screen
authorChristoph Sommer <mail@christoph-sommer.de>
Tue, 1 Jul 2008 20:06:37 +0000 (20:06 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Tue, 1 Jul 2008 20:06:37 +0000 (20:06 +0000)
SVN-Revision: 5644

src/game_session.cpp
src/game_session.hpp
src/levelintro.cpp [new file with mode: 0644]
src/levelintro.hpp [new file with mode: 0644]
src/mainloop.cpp
src/statistics.cpp
src/statistics.hpp

index 9cf4757..707d597 100644 (file)
@@ -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
index edae3a6..7350b6d 100644 (file)
@@ -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 (file)
index 0000000..097fcee
--- /dev/null
@@ -0,0 +1,145 @@
+//  $Id: textscroller.cpp 4981 2007-04-15 15:41:27Z sommer $
+//
+//  SuperTux -- LevelIntro screen
+//  Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
+//
+//  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 <config.h>
+
+#include "levelintro.hpp"
+
+#include <stdexcept>
+#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 (file)
index 0000000..960630d
--- /dev/null
@@ -0,0 +1,62 @@
+//  $Id: textscroller.hpp 5330 2008-02-18 19:30:28Z sommer $
+//
+//  SuperTux -- LevelIntro screen
+//  Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
+//
+//  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 <vector>
+#include <string>
+#include <map>
+#include <memory>
+
+#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<Sprite> 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
index 6a9bb04..1a7a132 100644 (file)
@@ -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();
index fbfa94d..4298fc9 100644 (file)
@@ -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<int>(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();
index e2a2195..38c4f3e 100644 (file)
@@ -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*/