00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <math.h>
00019 #include <sstream>
00020
00021 #include "audio/sound_manager.hpp"
00022 #include "util/writer.hpp"
00023 #include "supertux/globals.hpp"
00024 #include "supertux/player_status.hpp"
00025 #include "supertux/resources.hpp"
00026 #include "supertux/timer.hpp"
00027 #include "util/reader.hpp"
00028 #include "video/drawing_context.hpp"
00029
00030 static const int START_COINS = 100;
00031 static const int MAX_COINS = 9999;
00032
00033 static const int DISPLAYED_COINS_UNSET = -1;
00034
00035 PlayerStatus* player_status = 0;
00036
00037 PlayerStatus::PlayerStatus() :
00038
00039 coins(START_COINS),
00040 bonus(NO_BONUS),
00041 max_fire_bullets(0),
00042 max_ice_bullets(0),
00043 displayed_coins(DISPLAYED_COINS_UNSET),
00044 displayed_coins_frame(0),
00045 coin_surface()
00046 {
00047 reset();
00048
00049 coin_surface = Surface::create("images/engine/hud/coins-0.png");
00050 sound_manager->preload("sounds/coin.wav");
00051 sound_manager->preload("sounds/lifeup.wav");
00052 }
00053
00054 PlayerStatus::~PlayerStatus()
00055 {
00056 }
00057
00058 void PlayerStatus::reset()
00059 {
00060 coins = START_COINS;
00061 bonus = NO_BONUS;
00062 displayed_coins = DISPLAYED_COINS_UNSET;
00063 }
00064
00065 void
00066 PlayerStatus::add_coins(int count, bool play_sound)
00067 {
00068 static float sound_played_time = 0;
00069 coins = std::min(coins + count, MAX_COINS);
00070 if(play_sound) {
00071 if(count >= 100)
00072 sound_manager->play("sounds/lifeup.wav");
00073 else if (real_time > sound_played_time + 0.010) {
00074 sound_manager->play("sounds/coin.wav");
00075 sound_played_time = real_time;
00076 }
00077 }
00078 }
00079
00080 void
00081 PlayerStatus::write(lisp::Writer& writer)
00082 {
00083 switch(bonus) {
00084 case NO_BONUS:
00085 writer.write("bonus", "none");
00086 break;
00087 case GROWUP_BONUS:
00088 writer.write("bonus", "growup");
00089 break;
00090 case FIRE_BONUS:
00091 writer.write("bonus", "fireflower");
00092 break;
00093 case ICE_BONUS:
00094 writer.write("bonus", "iceflower");
00095 break;
00096 default:
00097 log_warning << "Unknown bonus type." << std::endl;
00098 writer.write("bonus", "none");
00099 }
00100 writer.write("fireflowers", max_fire_bullets);
00101 writer.write("iceflowers", max_ice_bullets);
00102
00103 writer.write("coins", coins);
00104 }
00105
00106 void
00107 PlayerStatus::read(const Reader& lisp)
00108 {
00109 reset();
00110
00111 std::string bonusname;
00112 if(lisp.get("bonus", bonusname)) {
00113 if(bonusname == "none") {
00114 bonus = NO_BONUS;
00115 } else if(bonusname == "growup") {
00116 bonus = GROWUP_BONUS;
00117 } else if(bonusname == "fireflower") {
00118 bonus = FIRE_BONUS;
00119 } else if(bonusname == "iceflower") {
00120 bonus = ICE_BONUS;
00121 } else {
00122 log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
00123 bonus = NO_BONUS;
00124 }
00125 }
00126 lisp.get("fireflowers", max_fire_bullets);
00127 lisp.get("iceflowers", max_ice_bullets);
00128
00129 lisp.get("coins", coins);
00130 }
00131
00132 void
00133 PlayerStatus::draw(DrawingContext& context)
00134 {
00135 int player_id = 0;
00136
00137 if ((displayed_coins == DISPLAYED_COINS_UNSET) ||
00138 (fabsf(displayed_coins - coins) > 100)) {
00139 displayed_coins = coins;
00140 displayed_coins_frame = 0;
00141 }
00142 if (++displayed_coins_frame > 2) {
00143 displayed_coins_frame = 0;
00144 if (displayed_coins < coins) displayed_coins++;
00145 if (displayed_coins > coins) displayed_coins--;
00146 }
00147 displayed_coins = std::min(std::max(displayed_coins, 0), 9999);
00148
00149 std::stringstream ss;
00150 ss << displayed_coins;
00151 std::string coins_text = ss.str();
00152
00153 context.push_transform();
00154 context.set_translation(Vector(0, 0));
00155
00156 if (coin_surface)
00157 {
00158 context.draw_surface(coin_surface,
00159 Vector(SCREEN_WIDTH - BORDER_X - coin_surface->get_width() - Resources::fixed_font->get_text_width(coins_text),
00160 BORDER_Y + 1 + (Resources::fixed_font->get_text_height(coins_text) + 5) * player_id),
00161 LAYER_HUD);
00162 }
00163 context.draw_text(Resources::fixed_font,
00164 coins_text,
00165 Vector(SCREEN_WIDTH - BORDER_X - Resources::fixed_font->get_text_width(coins_text),
00166 BORDER_Y + (Resources::fixed_font->get_text_height(coins_text) + 5) * player_id),
00167 ALIGN_LEFT,
00168 LAYER_HUD,
00169 PlayerStatus::text_color);
00170
00171 context.pop_transform();
00172 }
00173
00174