MatzeB: that shoudl fix the cases where you die when picking up an iceflower
[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
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       World::current()->broken_bricks.erase(static_cast<std::vector<BrokenBrick>::iterator>(this));
83     }
84 }
85
86 void
87 BrokenBrick::draw()
88 {
89   SDL_Rect src, dest;
90   src.x = rand() % 16;
91   src.y = rand() % 16;
92   src.w = 16;
93   src.h = 16;
94
95   dest.x = (int)(base.x - scroll_x);
96   dest.y = (int)base.y;
97   dest.w = 16;
98   dest.h = 16;
99   
100   if (tile->images.size() > 0)
101     tile->images[0]->draw_part(src.x,src.y,dest.x,dest.y,dest.w,dest.h);
102 }
103
104 void
105 BouncyBrick::init(float x, float y)
106 {
107   base.x   = x;
108   base.y   = y;
109   offset   = 0;
110   offset_m = -BOUNCY_BRICK_SPEED;
111   shape    = World::current()->get_level()->gettileid(x, y);
112 }
113
114 void
115 BouncyBrick::action(double frame_ratio)
116 {
117   offset = (offset + offset_m * frame_ratio);
118
119   /* Go back down? */
120   if (offset < -BOUNCY_BRICK_MAX_OFFSET)
121     offset_m = BOUNCY_BRICK_SPEED;
122
123
124   /* Stop bouncing? */
125   if (offset >= 0)
126     World::current()->bouncy_bricks.erase(static_cast<std::vector<BouncyBrick>::iterator>(this));
127 }
128
129 void
130 BouncyBrick::draw()
131 {
132   SDL_Rect dest;
133   
134   if (base.x >= scroll_x - 32 &&
135       base.x <= scroll_x + screen->w)
136     {
137       dest.x = (int)(base.x - scroll_x);
138       dest.y = (int)base.y;
139       dest.w = 32;
140       dest.h = 32;
141
142       Level* plevel = World::current()->get_level();
143
144       // FIXME: overdrawing hack to clean the tile from the screen to
145       // paint it later at on offseted position
146       if(plevel->bkgd_image[0] == '\0')
147         {
148           fillrect(base.x - scroll_x, base.y,
149                    32,32, 
150                    plevel->bkgd_top.red, plevel->bkgd_top.green, plevel->bkgd_top.blue, 0);
151 // FIXME: doesn't respect the gradient, futhermore is this necessary at all??
152         }
153       else
154         {
155           int s = ((int)scroll_x / 2)%640;
156           plevel->img_bkgd->draw_part(dest.x + s, dest.y, 
157                                       dest.x, dest.y,dest.w,dest.h);
158         }
159
160       Tile::draw(base.x - scroll_x,
161                  base.y + offset,
162                  shape);
163     }
164 }
165
166 void
167 FloatingScore::init(float x, float y, int s)
168 {
169   base.x = x;
170   base.y = y - 16;
171   timer.init(true);
172   timer.start(1000);
173   value = s;
174 }
175
176 void
177 FloatingScore::action(double frame_ratio)
178 {
179   base.y = base.y - 2 * frame_ratio;
180
181   if(!timer.check())
182     World::current()->floating_scores.erase(static_cast<std::vector<FloatingScore>::iterator>(this));
183 }
184
185 void
186 FloatingScore::draw()
187 {
188   char str[10];
189   sprintf(str, "%d", value);
190   gold_text->draw(str, (int)base.x + 16 - strlen(str) * 8, (int)base.y, 1);
191 }
192
193 /* EOF */
194