added missing #include <algorithm>
[supertux.git] / src / gameobjs.cpp
1 //  $Id$
2 // 
3 //  SuperTux
4 //  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
5 //  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
6 //
7 //  This program is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU General Public License
9 //  as published by the Free Software Foundation; either version 2
10 //  of the License, or (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 // 
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 //  02111-1307, USA.
21 #include <algorithm>
22 #include "world.h"
23 #include "tile.h"
24 #include "gameloop.h"
25 #include "gameobjs.h"
26
27 void
28 BouncyDistro::init(float x, float y)
29 {
30   base.x = x;
31   base.y = y;
32   base.ym = -2;
33 }
34
35 void
36 BouncyDistro::action(double frame_ratio)
37 {
38   base.y = base.y + base.ym * frame_ratio;
39
40   base.ym += 0.1 * frame_ratio;
41
42   if (base.ym >= 0)
43     {
44       std::vector<BouncyDistro*>::iterator i
45         = std::find(World::current()->bouncy_distros.begin(), 
46                     World::current()->bouncy_distros.end(), 
47                     this);
48       if (i != World::current()->bouncy_distros.end())
49         World::current()->bouncy_distros.erase(i);
50     }
51 }
52
53 void
54 BouncyDistro::draw()
55 {
56   img_distro[0]->draw(base.x - scroll_x,
57                       base.y);
58 }
59
60
61 void
62 BrokenBrick::init(Tile* tile_, float x, float y, float xm, float ym)
63 {
64   tile    = tile_;
65   base.x  = x;
66   base.y  = y;
67   base.xm = xm;
68   base.ym = ym;
69
70   timer.init(true);
71   timer.start(200);
72 }
73
74 void
75 BrokenBrick::action(double frame_ratio)
76 {
77   base.x = base.x + base.xm * frame_ratio;
78   base.y = base.y + base.ym * frame_ratio;
79
80   if (!timer.check())
81     {
82       std::vector<BrokenBrick*>::iterator i
83         = std::find(World::current()->broken_bricks.begin(), 
84                     World::current()->broken_bricks.end(), 
85                     this);
86       if (i != World::current()->broken_bricks.end())
87         World::current()->broken_bricks.erase(i);
88     }
89 }
90
91 void
92 BrokenBrick::draw()
93 {
94   SDL_Rect src, dest;
95   src.x = rand() % 16;
96   src.y = rand() % 16;
97   src.w = 16;
98   src.h = 16;
99
100   dest.x = (int)(base.x - scroll_x);
101   dest.y = (int)base.y;
102   dest.w = 16;
103   dest.h = 16;
104   
105   if (tile->images.size() > 0)
106     tile->images[0]->draw_part(src.x,src.y,dest.x,dest.y,dest.w,dest.h);
107 }
108
109 void
110 BouncyBrick::init(float x, float y)
111 {
112   base.x   = x;
113   base.y   = y;
114   offset   = 0;
115   offset_m = -BOUNCY_BRICK_SPEED;
116   shape    = World::current()->get_level()->gettileid(x, y);
117 }
118
119 void
120 BouncyBrick::action(double frame_ratio)
121 {
122   offset = (offset + offset_m * frame_ratio);
123
124   /* Go back down? */
125   if (offset < -BOUNCY_BRICK_MAX_OFFSET)
126     offset_m = BOUNCY_BRICK_SPEED;
127
128
129   /* Stop bouncing? */
130   if (offset >= 0)
131     {
132       std::vector<BouncyBrick*>::iterator i
133         = std::find(World::current()->bouncy_bricks.begin(), 
134                     World::current()->bouncy_bricks.end(), 
135                     this);
136       if (i != World::current()->bouncy_bricks.end())
137         World::current()->bouncy_bricks.erase(i);
138     }
139 }
140
141 void
142 BouncyBrick::draw()
143 {
144   SDL_Rect dest;
145   
146   if (base.x >= scroll_x - 32 &&
147       base.x <= scroll_x + screen->w)
148     {
149       dest.x = (int)(base.x - scroll_x);
150       dest.y = (int)base.y;
151       dest.w = 32;
152       dest.h = 32;
153
154       Level* plevel = World::current()->get_level();
155
156       // FIXME: overdrawing hack to clean the tile from the screen to
157       // paint it later at on offseted position
158       if(plevel->bkgd_image[0] == '\0')
159         {
160           fillrect(base.x - scroll_x, base.y,
161                    32,32, 
162                    plevel->bkgd_top.red, plevel->bkgd_top.green, plevel->bkgd_top.blue, 0);
163 // FIXME: doesn't respect the gradient, futhermore is this necessary at all??
164         }
165       else
166         {
167           int s = ((int)scroll_x / 2)%640;
168           plevel->img_bkgd->draw_part(dest.x + s, dest.y, 
169                                       dest.x, dest.y,dest.w,dest.h);
170         }
171
172       Tile::draw(base.x - scroll_x,
173                  base.y + offset,
174                  shape);
175     }
176 }
177
178 void
179 FloatingScore::init(float x, float y, int s)
180 {
181   base.x = x;
182   base.y = y - 16;
183   timer.init(true);
184   timer.start(1000);
185   value = s;
186 }
187
188 void
189 FloatingScore::action(double frame_ratio)
190 {
191   base.y = base.y - 2 * frame_ratio;
192
193   if(!timer.check())
194     {
195       std::vector<FloatingScore*>::iterator i
196         = std::find(World::current()->floating_scores.begin(), 
197                     World::current()->floating_scores.end(), 
198                     this);
199       if (i != World::current()->floating_scores.end())
200         World::current()->floating_scores.erase(i);
201     }
202 }
203
204 void
205 FloatingScore::draw()
206 {
207   char str[10];
208   sprintf(str, "%d", value);
209   gold_text->draw(str, (int)base.x + 16 - strlen(str) * 8, (int)base.y, 1);
210 }
211
212 /* EOF */
213