- memleak fix and menu fix from MatzeB
[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     World::current()->bouncy_distros.erase(static_cast<std::vector<BouncyDistro>::iterator>(this));
44 }
45
46 void
47 BouncyDistro::draw()
48 {
49   img_distro[0]->draw(base.x - scroll_x,
50                       base.y);
51 }
52
53
54 void
55 BrokenBrick::init(Tile* tile_, float x, float y, float xm, float ym)
56 {
57   tile    = tile_;
58   base.x  = x;
59   base.y  = y;
60   base.xm = xm;
61   base.ym = ym;
62
63   timer.init(true);
64   timer.start(200);
65 }
66
67 void
68 BrokenBrick::action(double frame_ratio)
69 {
70   base.x = base.x + base.xm * frame_ratio;
71   base.y = base.y + base.ym * frame_ratio;
72
73   if (!timer.check())
74     World::current()->broken_bricks.erase(static_cast<std::vector<BrokenBrick>::iterator>(this));
75 }
76
77 void
78 BrokenBrick::draw()
79 {
80   SDL_Rect src, dest;
81   src.x = rand() % 16;
82   src.y = rand() % 16;
83   src.w = 16;
84   src.h = 16;
85
86   dest.x = (int)(base.x - scroll_x);
87   dest.y = (int)base.y;
88   dest.w = 16;
89   dest.h = 16;
90   
91   if (tile->images.size() > 0)
92     tile->images[0]->draw_part(src.x,src.y,dest.x,dest.y,dest.w,dest.h);
93 }
94
95 void
96 BouncyBrick::init(float x, float y)
97 {
98   base.x   = x;
99   base.y   = y;
100   offset   = 0;
101   offset_m = -BOUNCY_BRICK_SPEED;
102   shape    = World::current()->get_level()->gettileid(x, y);
103 }
104
105 void
106 BouncyBrick::action(double frame_ratio)
107 {
108   offset = (offset + offset_m * frame_ratio);
109
110   /* Go back down? */
111   if (offset < -BOUNCY_BRICK_MAX_OFFSET)
112     offset_m = BOUNCY_BRICK_SPEED;
113
114
115   /* Stop bouncing? */
116   if (offset >= 0)
117     World::current()->bouncy_bricks.erase(static_cast<std::vector<BouncyBrick>::iterator>(this));
118 }
119
120 void
121 BouncyBrick::draw()
122 {
123   int s;
124   SDL_Rect dest;
125   
126   if (base.x >= scroll_x - 32 &&
127       base.x <= scroll_x + screen->w)
128     {
129       dest.x = (int)(base.x - scroll_x);
130       dest.y = (int)base.y;
131       dest.w = 32;
132       dest.h = 32;
133
134       Level* plevel = World::current()->get_level();
135
136       // FIXME: overdrawing hack to clean the tile from the screen to
137       // paint it later at on offseted position
138       if(plevel->bkgd_image[0] == '\0')
139         {
140           fillrect(base.x - scroll_x, base.y,
141                    32,32, 
142                    plevel->bkgd_top.red, plevel->bkgd_top.green, plevel->bkgd_top.blue, 0);
143 // FIXME: doesn't respect the gradient, futhermore is this necessary at all??
144         }
145       else
146         {
147           s = (int)scroll_x / 30;
148           plevel->img_bkgd->draw_part(dest.x + s, dest.y, 
149                                       dest.x, dest.y,dest.w,dest.h);
150         }
151
152       Tile::draw(base.x - scroll_x,
153                  base.y + offset,
154                  shape);
155     }
156 }
157
158 void
159 FloatingScore::init(float x, float y, int s)
160 {
161   base.x = x;
162   base.y = y - 16;
163   timer.init(true);
164   timer.start(1000);
165   value = s;
166 }
167
168 void
169 FloatingScore::action(double frame_ratio)
170 {
171   base.y = base.y - 2 * frame_ratio;
172
173   if(!timer.check())
174     World::current()->floating_scores.erase(static_cast<std::vector<FloatingScore>::iterator>(this));
175 }
176
177 void
178 FloatingScore::draw()
179 {
180   char str[10];
181   sprintf(str, "%d", value);
182   gold_text->draw(str, (int)base.x + 16 - strlen(str) * 8, (int)base.y, 1);
183 }
184
185 /* EOF */
186