Walking badguy: Implemented {get,set}_walk_speed.
[supertux.git] / src / badguy / walking_badguy.cpp
1 //  SuperTux - WalkingBadguy
2 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include <math.h>
18
19 #include "badguy/walking_badguy.hpp"
20
21 #include "sprite/sprite.hpp"
22
23 WalkingBadguy::WalkingBadguy(const Vector& pos, 
24                              const std::string& sprite_name, 
25                              const std::string& walk_left_action, 
26                              const std::string& walk_right_action, 
27                              int layer) :
28   BadGuy(pos, sprite_name, layer), 
29   walk_left_action(walk_left_action), 
30   walk_right_action(walk_right_action), 
31   walk_speed(80), 
32   max_drop_height(-1),
33   turn_around_timer(),
34   turn_around_counter()
35 {
36 }
37
38 WalkingBadguy::WalkingBadguy(const Vector& pos, 
39                              Direction direction, 
40                              const std::string& sprite_name, 
41                              const std::string& walk_left_action, 
42                              const std::string& walk_right_action, 
43                              int layer) :
44   BadGuy(pos, direction, sprite_name, layer), 
45   walk_left_action(walk_left_action), 
46   walk_right_action(walk_right_action), 
47   walk_speed(80), 
48   max_drop_height(-1),
49   turn_around_timer(),
50   turn_around_counter()
51 {
52 }
53
54 WalkingBadguy::WalkingBadguy(const Reader& reader, 
55                              const std::string& sprite_name, 
56                              const std::string& walk_left_action, 
57                              const std::string& walk_right_action, 
58                              int layer) :
59   BadGuy(reader, sprite_name, layer), 
60   walk_left_action(walk_left_action), 
61   walk_right_action(walk_right_action), 
62   walk_speed(80), 
63   max_drop_height(-1),
64   turn_around_timer(),
65   turn_around_counter()
66 {
67 }
68
69 void
70 WalkingBadguy::initialize()
71 {
72   if(frozen)
73     return;
74   sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
75   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
76   physic.set_velocity_x(dir == LEFT ? -walk_speed : walk_speed);
77 }
78
79 void
80 WalkingBadguy::set_walk_speed (float ws)
81 {
82   walk_speed = fabs (ws);
83   physic.set_velocity_x(dir == LEFT ? -walk_speed : walk_speed);
84 }
85
86 void
87 WalkingBadguy::active_update(float elapsed_time)
88 {
89   BadGuy::active_update(elapsed_time);
90
91   if (max_drop_height > -1) {
92     if (on_ground() && might_fall(max_drop_height+1))
93     {
94       turn_around();
95     }
96   }
97
98 }
99
100 void
101 WalkingBadguy::collision_solid(const CollisionHit& hit)
102 {
103
104   update_on_ground_flag(hit);
105
106   if (hit.top) {
107     if (physic.get_velocity_y() < 0) physic.set_velocity_y(0);
108   }
109   if (hit.bottom) {
110     if (physic.get_velocity_y() > 0) physic.set_velocity_y(0);
111   }
112
113   if ((hit.left && (hit.slope_normal.y == 0) && (dir == LEFT)) || (hit.right && (hit.slope_normal.y == 0) && (dir == RIGHT))) {
114     turn_around();
115   }
116
117 }
118
119 HitResponse
120 WalkingBadguy::collision_badguy(BadGuy& , const CollisionHit& hit)
121 {
122
123   if ((hit.left && (dir == LEFT)) || (hit.right && (dir == RIGHT))) {
124     turn_around();
125   }
126
127   return CONTINUE;
128 }
129
130 void
131 WalkingBadguy::turn_around()
132 {
133   if(frozen)
134     return;
135   dir = dir == LEFT ? RIGHT : LEFT;
136   sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
137   physic.set_velocity_x(-physic.get_velocity_x());
138
139   // if we get dizzy, we fall off the screen
140   if (turn_around_timer.started()) {
141     if (turn_around_counter++ > 10) kill_fall();
142   } else {
143     turn_around_timer.start(1);
144     turn_around_counter = 0;
145   }
146
147 }
148
149 void
150 WalkingBadguy::freeze()
151 {
152   BadGuy::freeze();
153   physic.set_velocity_x(0);
154 }
155
156 void
157 WalkingBadguy::unfreeze()
158 {
159   BadGuy::unfreeze();
160   WalkingBadguy::initialize();
161 }
162
163 float
164 WalkingBadguy::get_velocity_y() const
165 {
166   return physic.get_velocity_y();
167 }
168
169 void
170 WalkingBadguy::set_velocity_y(float vy)
171 {
172   physic.set_velocity_y(vy);
173 }
174
175 /* EOF */