3 // SuperTux - A Jump'n Run
4 // Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include "sprite_manager.h"
32 #include "resources.h"
34 Sprite* img_firebullet;
35 Sprite* img_icebullet;
38 Sprite* img_iceflower;
39 Sprite* img_fireflower;
42 #define GROWUP_SPEED 1.0f
44 #define BULLET_STARTING_YM 0
47 Bullet::Bullet(DisplayManager& display_manager, const Vector& pos, float xm,
50 display_manager.add_drawable(this, LAYER_OBJECTS);
59 physic.set_velocity_x(BULLET_XM + xm);
64 physic.set_velocity_x(-BULLET_XM + xm);
67 base.y = pos.y + base.height/2;
68 physic.set_velocity_y(-BULLET_STARTING_YM);
74 Bullet::action(float elapsed_time)
80 physic.apply(elapsed_time, base.x, base.y);
81 collision_swept_object_map(&old_base,&base);
83 if (issolid(base.x, base.y + 4) || issolid(base.x, base.y))
86 physic.set_velocity_y(-physic.get_velocity_y());
90 if(kind == FIRE_BULLET)
91 // @not framerate independant :-/
92 physic.set_velocity_y(physic.get_velocity_y() - 0.5 * elapsed_time);
93 if(physic.get_velocity_y() > 9)
94 physic.set_velocity_y(9);
95 else if(physic.get_velocity_y() < -9)
96 physic.set_velocity_y(-9);
99 World::current()->camera->get_translation().x;
101 World::current()->camera->get_translation().y;
102 if (base.x < scroll_x ||
103 base.x > scroll_x + screen->w ||
105 base.y > scroll_y + screen->h ||
106 issolid(base.x + 4, base.y + 2) ||
107 issolid(base.x, base.y + 2) ||
115 Bullet::draw(Camera& viewport, int )
117 if(kind == FIRE_BULLET)
118 img_firebullet->draw(viewport.world2screen(Vector(base.x, base.y)));
119 else if(kind == ICE_BULLET)
120 img_icebullet->draw(viewport.world2screen(Vector(base.x, base.y)));
124 Bullet::collision(const MovingObject& , int)
130 Bullet::collision(int c_object)
132 if(c_object == CO_BADGUY) {
137 //---------------------------------------------------------------------------
139 Upgrade::Upgrade(DisplayManager& display_manager, const Vector& pos,
140 Direction dir_, UpgradeKind kind_)
142 display_manager.add_drawable(this, LAYER_OBJECTS);
154 physic.enable_gravity(false);
156 if(kind == UPGRADE_1UP || kind == UPGRADE_HERRING) {
157 physic.set_velocity(dir == LEFT ? -1 : 1, 4);
158 physic.enable_gravity(true);
160 } else if (kind == UPGRADE_ICEFLOWER || kind == UPGRADE_FIREFLOWER) {
162 } else if (kind == UPGRADE_GROWUP) {
163 physic.set_velocity(dir == LEFT ? -GROWUP_SPEED : GROWUP_SPEED, 0);
165 physic.set_velocity(dir == LEFT ? -2 : 2, 0);
174 Upgrade::action(float elapsed_time)
176 if (kind == UPGRADE_ICEFLOWER || kind == UPGRADE_FIREFLOWER
177 || kind == UPGRADE_GROWUP) {
178 if (base.height < 32) {
180 base.height = base.height + 0.7 * elapsed_time;
188 /* Away from the screen? Kill it! */
190 World::current()->camera->get_translation().x;
192 World::current()->camera->get_translation().y;
194 if(base.x < scroll_x - X_OFFSCREEN_DISTANCE ||
195 base.x > scroll_x + screen->w + X_OFFSCREEN_DISTANCE ||
196 base.y < scroll_y - Y_OFFSCREEN_DISTANCE ||
197 base.y > scroll_y + screen->h + Y_OFFSCREEN_DISTANCE)
204 physic.apply(elapsed_time, base.x, base.y);
205 if(kind == UPGRADE_GROWUP) {
206 collision_swept_object_map(&old_base, &base);
210 if(kind == UPGRADE_GROWUP || kind == UPGRADE_HERRING) {
212 if(physic.get_velocity_y() != 0) {
213 if(issolid(base.x, base.y + base.height)) {
214 base.y = int(base.y / 32) * 32;
216 if(kind == UPGRADE_GROWUP) {
217 physic.enable_gravity(false);
218 physic.set_velocity(dir == LEFT ? -GROWUP_SPEED : GROWUP_SPEED, 0);
219 } else if(kind == UPGRADE_HERRING) {
220 physic.set_velocity(dir == LEFT ? -2 : 2, 3);
224 if((physic.get_velocity_x() < 0
225 && !issolid(base.x+base.width, base.y + base.height))
226 || (physic.get_velocity_x() > 0
227 && !issolid(base.x, base.y + base.height))) {
228 physic.enable_gravity(true);
233 // horizontal bounce?
234 if(kind == UPGRADE_GROWUP || kind == UPGRADE_HERRING) {
235 if ( (physic.get_velocity_x() < 0
236 && issolid(base.x, (int) base.y + base.height/2))
237 || (physic.get_velocity_x() > 0
238 && issolid(base.x + base.width, (int) base.y + base.height/2))) {
239 physic.set_velocity(-physic.get_velocity_x(),physic.get_velocity_y());
240 dir = dir == LEFT ? RIGHT : LEFT;
246 Upgrade::draw(Camera& viewport, int)
250 if (base.height < 32)
254 dest.x = (int)(base.x - viewport.get_translation().x);
255 dest.y = (int)(base.y + 32 - base.height - viewport.get_translation().y);
257 dest.h = (int)base.height;
259 if (kind == UPGRADE_GROWUP)
260 img_growup->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
261 else if (kind == UPGRADE_ICEFLOWER)
262 img_iceflower->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
263 else if (kind == UPGRADE_FIREFLOWER)
264 img_fireflower->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
265 else if (kind == UPGRADE_HERRING)
266 img_star->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
267 else if (kind == UPGRADE_1UP)
268 img_1up->draw_part( 0, 0, dest.x, dest.y, dest.w, dest.h);
272 if (kind == UPGRADE_GROWUP)
274 img_growup->draw(viewport.world2screen(Vector(base.x, base.y)));
276 else if (kind == UPGRADE_ICEFLOWER)
278 img_iceflower->draw(viewport.world2screen(Vector(base.x, base.y)));
280 else if (kind == UPGRADE_FIREFLOWER)
282 img_fireflower->draw(viewport.world2screen(Vector(base.x, base.y)));
284 else if (kind == UPGRADE_HERRING)
286 img_star->draw(viewport.world2screen(Vector(base.x, base.y)));
288 else if (kind == UPGRADE_1UP)
290 img_1up->draw(viewport.world2screen(Vector(base.x, base.y)));
296 Upgrade::bump(Player* player)
298 // these can't be bumped
299 if(kind != UPGRADE_GROWUP)
302 play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);
304 // determine new direction
305 if (player->base.x + player->base.width/2 > base.x + base.width/2)
310 // do a little jump and change direction
311 physic.set_velocity(-physic.get_velocity_x(), 3);
312 physic.enable_gravity(true);
316 Upgrade::collision(const MovingObject& , int)
322 Upgrade::collision(void* p_c_object, int c_object, CollisionType type)
324 Player* pplayer = NULL;
326 if(type == COLLISION_BUMP) {
327 if(c_object == CO_PLAYER)
328 pplayer = (Player*) p_c_object;
336 /* Remove the upgrade: */
338 /* p_c_object is CO_PLAYER, so assign it to pplayer */
339 pplayer = (Player*) p_c_object;
341 /* Affect the player: */
343 if (kind == UPGRADE_GROWUP)
345 play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER);
348 else if (kind == UPGRADE_FIREFLOWER)
350 play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER);
352 pplayer->got_power = pplayer->FIRE_POWER;
354 else if (kind == UPGRADE_ICEFLOWER)
356 play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER);
358 pplayer->got_power = pplayer->ICE_POWER;
360 else if (kind == UPGRADE_FIREFLOWER)
362 play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER);
364 pplayer->got_power = pplayer->FIRE_POWER;
366 else if (kind == UPGRADE_HERRING)
368 play_sound(sounds[SND_HERRING], SOUND_CENTER_SPEAKER);
369 pplayer->invincible_timer.start(TUX_INVINCIBLE_TIME);
370 World::current()->play_music(HERRING_MUSIC);
372 else if (kind == UPGRADE_1UP)
374 if(player_status.lives < MAX_LIVES) {
375 player_status.lives++;
376 play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
385 void load_special_gfx()
387 img_growup = sprite_manager->load("egg");
388 img_iceflower = sprite_manager->load("iceflower");
389 img_fireflower = sprite_manager->load("fireflower");
390 img_star = sprite_manager->load("star");
391 img_1up = sprite_manager->load("1up");
393 img_firebullet = sprite_manager->load("firebullet");
394 img_icebullet = sprite_manager->load("icebullet");
397 void free_special_gfx()