Portable and fixed trampoline.
[supertux.git] / src / object / trampoline.cpp
1 //  $Id$
2 //
3 //  SuperTux - Trampoline
4 //  Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
5 //  
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.
10 //
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.
15 //
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.
19
20 #include <config.h>
21
22 #include "trampoline.hpp"
23 #include "object_factory.hpp"
24 #include "player.hpp"
25 #include "audio/sound_manager.hpp"
26 #include "sprite/sprite_manager.hpp"
27
28 /* Trampoline will accelerate player by VY_FACTOR (or to VY_INITIAL if 
29  * that's faster) if he jumps on it. Acceleration is capped at VY_MIN. */
30 namespace{
31   static const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav";
32   static const float VY_MIN = -1000; //negative, upwards
33   static const float VY_FACTOR = -1.5;
34   static const float VY_INITIAL = -500;
35 }
36
37 Trampoline::Trampoline(const lisp::Lisp& lisp)
38         : MovingSprite(lisp, "images/objects/trampoline/trampoline.sprite" )
39 {
40   sound_manager->preload( TRAMPOLINE_SOUND );
41   flags |= FLAG_PORTABLE;
42   physic.set_velocity_y(0);
43   physic.enable_gravity(true);
44   on_ground = false;
45
46   bool portable = true;
47   //Check if this trampoline is not portable
48   if( lisp.get( "portable", portable ) ){
49     if( !portable ){
50         flags ^= FLAG_PORTABLE;
51         //we need another sprite
52         sprite_name = "images/objects/trampoline/trampoline_fix.sprite";
53         sprite = sprite_manager->create( sprite_name );
54         sprite->set_action("normal");
55     }
56   }
57 }
58
59 void
60 Trampoline::update( float elapsed_time ){
61     if( !on_ground ){
62         movement = physic.get_movement(elapsed_time);
63     }
64     if(sprite->animation_done()) {
65       sprite->set_action("normal");
66     }
67 }
68
69 HitResponse
70 Trampoline::collision(GameObject& other, const CollisionHit& hit )
71 {
72   //Tramponine has to be on ground to work.
73   if( !on_ground ){
74       return FORCE_MOVE;
75   }
76   Player* player = dynamic_cast<Player*> (&other);
77   if ( player ) {
78     float vy = player->physic.get_velocity_y();
79     //player is falling down on trampolin holding "jump"
80     if(hit.top && vy > 0) {
81       if(player->get_controller()->hold(Controller::JUMP)) { 
82         vy = VY_MIN;
83       } else {
84         vy = VY_INITIAL;
85       }
86
87       player->physic.set_velocity_y( vy );
88       sound_manager->play( TRAMPOLINE_SOUND );
89       sprite->set_action("swinging", 1);
90       //sprite->set_animation_loops(2); //TODO: 2 is not working
91       return SOLID;
92     }
93   }
94   
95   return SOLID; //TODO: Nobody should be able to walk through the trampoline.
96 }
97
98 void 
99 Trampoline::collision_solid( const CollisionHit& hit ){
100   if( hit.bottom ){
101      on_ground = true;
102   }
103
104
105 void
106 Trampoline::grab( MovingObject&, const Vector& pos, Direction ){
107   movement = pos - get_pos();
108   set_group( COLGROUP_DISABLED );
109   on_ground = true;
110   sprite->set_animation_loops( 0 );
111 }
112
113 void
114 Trampoline::ungrab(MovingObject& , Direction ){
115   set_group( COLGROUP_MOVING );
116   on_ground = false;
117   physic.set_velocity_y(0);
118 }
119
120
121 IMPLEMENT_FACTORY(Trampoline, "trampoline");