496e5ab33381e3f4a902012fb197926bb836df5e
[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 to to VY_INITIAL, if 
29  * he jumps on it to 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_INITIAL = -500;
34 }
35
36 Trampoline::Trampoline(const lisp::Lisp& lisp)
37         : MovingSprite(lisp, "images/objects/trampoline/trampoline.sprite" )
38 {
39   sound_manager->preload( TRAMPOLINE_SOUND );
40   flags |= FLAG_PORTABLE;
41   flags |= FLAG_SOLID;
42   physic.set_velocity(0, 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   // but to make this work we have to be in COLGROUP_STATIC which would
97   // break jumping and grabbing.
98 }
99
100 void 
101 Trampoline::collision_solid( const CollisionHit& hit ){
102   if( hit.bottom ){
103      on_ground = true;
104   }
105
106
107 void
108 Trampoline::grab( MovingObject&, const Vector& pos, Direction ){
109   movement = pos - get_pos();
110   set_group( COLGROUP_DISABLED );
111   on_ground = true;
112   sprite->set_animation_loops( 0 );
113 }
114
115 void
116 Trampoline::ungrab(MovingObject& , Direction ){
117   set_group( COLGROUP_MOVING );
118   on_ground = false;
119   physic.set_velocity(0, 0);
120 }
121
122
123 IMPLEMENT_FACTORY(Trampoline, "trampoline");