1 /*  $Id: RSprite.h,v 1.5 2016/04/30 14:33:27 sarrazip Exp $
2     RSprite.h - Sprite with floating point coordinates in a 2D game.
3 
4     flatzebra - Generic 2D Game Engine library
5     Copyright (C) 1999-2003 Pierre Sarrazin <http://sarrazip.com/>
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., 51 Franklin Street, Fifth Floor, Boston, MA
20     02110-1301, USA.
21 */
22 
23 #ifndef _H_RSprite
24 #define _H_RSprite
25 
26 #include <flatzebra/Couple.h>
27 #include <flatzebra/RCouple.h>
28 #include <flatzebra/PixmapArray.h>
29 
30 #include <vector>
31 
32 
33 namespace flatzebra {
34 
35 
36 typedef std::vector<class RSprite *> RSpriteList;
37 
38 
39 class RSprite
40 /*  RSprite in a 2D game.
41 */
42 {
43 public:
44     RSprite(const PixmapArray &pixmapArray,
45             const RCouple &pos = RCouple(),
46             const RCouple &speed = RCouple(),
47             const RCouple &accel = RCouple(),
48             const RCouple &collBoxPos = RCouple(),
49             const RCouple &collBoxSize = RCouple());
50     /*  Initializes the sprite with the given pixmap array and coordinates.
51         Keeps a pointer to 'pixmapArray' but does NOT become the owner
52         of the pixmap array.
53         Keeps copies of the other parameters.
54 
55         The "collision box" is the box that is used in detecting
56         collisions between this sprite and other sprites.
57         'collBoxPos' must be a position with respect to top left corner
58         of sprite's rectangle.
59     */
60 
61     virtual ~RSprite();
62     /*  Does not free the pixmap array given to the constructor.
63     */
64 
65     size_t getNumPixmaps() const;
66     /*  Returns the number of pixmaps in this sprite.
67     */
68 
69     SDL_Surface *getPixmap(size_t i) const;
70     /*  Returns the pixmap at index 'i' is this sprite's pixmap list.
71         This index is zero-based.
72         No check is made to ensure that i is valid.
73     */
74 
75     const PixmapArray *getPixmapArray() const;
76     /*  Returns the (non null) pointer to this sprite's pixmap array.
77     */
78 
79     const RCouple &getPos() const;
80     const RCouple &getSpeed() const;
81     const RCouple &getAccel() const;
82     const Couple &getSize() const;
83     RCouple &getPos();
84     RCouple &getSpeed();
85     RCouple &getAccel();
86     Couple &getSize();
87     /*  Returns a reference to the coordinates of this sprite.
88     */
89 
90     RCouple getCenterPos() const;
91     /*  Returns the position of the center of this sprite.
92     */
93 
94     void setCenterPos(const RCouple &c);
95     /*  Sets the (top-left) position so that 'c' becomes the center position.
96     */
97 
98     RCouple getLowerLeftPos() const;
99     /*  Returns the position of the lower left corner of the rectangle
100         that contains the sprite.
101     */
102 
103     RCouple getLowerRightPos() const;
104     /*  Returns the position of the lower right corner of the rectangle
105         that contains the sprite.
106         This position is the sum of the sprite's position and its size.
107     */
108 
109     RCouple getCollBoxPos() const;
110     RCouple getCollBoxSize() const;
111     void setCollBoxPos(const RCouple &c);
112     void setCollBoxSize(const RCouple &c);
113     /*  Returns or changes the coordinates of this sprite's collision box.
114         The position is relative to the top left corner of the sprite.
115     */
116 
117     void setPos(const RCouple &c);
118     void setSpeed(const RCouple &c);
119     void setAccel(const RCouple &c);
120     void addSpeedToPos();
121     void subSpeedFromPos();
122     void addAccelToSpeed();
123     void subAccelFromSpeed();
124     /*  Change the coordinates of the sprite.
125     */
126 
127     bool collidesWithRSprite(const RSprite &s) const;
128     /*  Returns true if the collision box of sprite 's' has an intersection
129         with the collision box of this sprite.
130     */
131 
132     void setTimeToLive(unsigned long t);
133     unsigned long getTimeToLive() const;
134     unsigned long decTimeToLive();
135     void clearTimeToLive();
136     /*  Manage the time to live variable.
137         decTimeToLive() does not decrement the value if it is already zero;
138         it returns the resulting value.
139     */
140 
141 
142     size_t currentPixmapIndex;  // index into thePixmapArray
143     /*  The current pixmap index can be used to have this sprite object
144         remember which image is currently used.
145         setCurrentPixmapIndex() does not check if 'i' is valid;
146         'i' must be lower than the size of this sprite's PixmapArray.
147 
148         'currentPixmapIndex' is initially zero.
149     */
150 
151 
152     long *values;  // array
153     size_t numUserValues;
154 
155     void boundPosition(Couple settingSizeInPixels);
156     /*  If the position of sprite 's' is out of the setting (whose size
157         is given by 'settingSizeInPixels'), then this position is adjusted
158         to bring the sprite back in.
159         It is assumed that the top left corner of the setting is (0, 0).
160     */
161 
162 protected:  // data became protected with version 0.1 @sarrazip 20010203
163 
164     /*  All the following RCouple objects are in pixels.
165         All pixmaps in the pixmap array must have the same size.
166     */
167 
168     const PixmapArray *thePixmapArray;  // not owned by this object
169 
170     RCouple pos;    // in pixels
171     RCouple speed;  // in pixels
172     RCouple accel;  // in pixels
173     Couple size;    // in (integer) pixels
174     unsigned long timeToLive;
175             // number of ticks left for this sprite;
176             // often used to count other things.
177 
178     RCouple collBoxPos;
179             // position of collision box w.r.t. to top left corner of sprite
180     RCouple collBoxSize;
181 
182 private:
183     /*        Forbidden operations:
184     */
185     RSprite(const RSprite &x);
186     RSprite &operator = (const RSprite &x);
187 };
188 
189 
190 /*  INLINE METHODS
191 */
192 
193 inline
194 const RCouple &
getPos()195 RSprite::getPos() const
196 {
197     return pos;
198 }
199 
200 inline
201 const RCouple &
getSpeed()202 RSprite::getSpeed() const
203 {
204     return speed;
205 }
206 
207 inline
208 const RCouple &
getAccel()209 RSprite::getAccel() const
210 {
211     return accel;
212 }
213 
214 inline
215 const Couple &
getSize()216 RSprite::getSize() const
217 {
218     return size;
219 }
220 
221 inline
222 RCouple &
getPos()223 RSprite::getPos()
224 {
225     return pos;
226 }
227 
228 inline
229 RCouple &
getSpeed()230 RSprite::getSpeed()
231 {
232     return speed;
233 }
234 
235 inline
236 RCouple &
getAccel()237 RSprite::getAccel()
238 {
239     return accel;
240 }
241 
242 inline
243 Couple &
getSize()244 RSprite::getSize()
245 {
246     return size;
247 }
248 
249 inline
250 RCouple
getCenterPos()251 RSprite::getCenterPos() const
252 {
253     return pos + size / 2;
254 }
255 
256 inline
257 void
setCenterPos(const RCouple & c)258 RSprite::setCenterPos(const RCouple &c)
259 {
260     pos = c - size / 2;
261 }
262 
263 
264 inline
265 RCouple
getLowerLeftPos()266 RSprite::getLowerLeftPos() const
267 {
268     return RCouple(pos.x, pos.y + size.y);
269 }
270 
271 
272 inline
273 RCouple
getLowerRightPos()274 RSprite::getLowerRightPos() const
275 {
276     return pos + size;
277 }
278 
279 inline
280 RCouple
getCollBoxPos()281 RSprite::getCollBoxPos() const
282 {
283     return collBoxPos;
284 }
285 
286 inline
287 RCouple
getCollBoxSize()288 RSprite::getCollBoxSize() const
289 {
290     return collBoxSize;
291 }
292 
293 inline
294 void
setCollBoxPos(const RCouple & c)295 RSprite::setCollBoxPos(const RCouple &c)
296 {
297     collBoxPos = c;
298 }
299 
300 inline
301 void
setCollBoxSize(const RCouple & c)302 RSprite::setCollBoxSize(const RCouple &c)
303 {
304     collBoxSize = c;
305 }
306 
307 inline
308 void
setPos(const RCouple & c)309 RSprite::setPos(const RCouple &c)
310 {
311     pos = c;
312 }
313 
314 inline
315 void
setSpeed(const RCouple & c)316 RSprite::setSpeed(const RCouple &c)
317 {
318     speed = c;
319 }
320 
321 inline
322 void
setAccel(const RCouple & c)323 RSprite::setAccel(const RCouple &c)
324 {
325     accel = c;
326 }
327 
328 inline
329 void
addSpeedToPos()330 RSprite::addSpeedToPos()
331 {
332     pos += speed;
333 }
334 
335 inline
336 void
subSpeedFromPos()337 RSprite::subSpeedFromPos()
338 {
339     pos -= speed;
340 }
341 
342 inline
343 void
addAccelToSpeed()344 RSprite::addAccelToSpeed()
345 {
346     speed += accel;
347 }
348 
349 inline
350 void
subAccelFromSpeed()351 RSprite::subAccelFromSpeed()
352 {
353     speed -= accel;
354 }
355 
356 inline
357 void
setTimeToLive(unsigned long t)358 RSprite::setTimeToLive(unsigned long t)
359 {
360     timeToLive = t;
361 }
362 
363 inline
364 unsigned long
getTimeToLive()365 RSprite::getTimeToLive() const
366 {
367     return timeToLive;
368 }
369 
370 inline
371 unsigned long
decTimeToLive()372 RSprite::decTimeToLive()
373 {
374     if (timeToLive != 0)
375         --timeToLive;
376     return timeToLive;
377 }
378 
379 inline
380 void
clearTimeToLive()381 RSprite::clearTimeToLive()
382 {
383     timeToLive = 0;
384 }
385 
386 inline
387 size_t
getNumPixmaps()388 RSprite::getNumPixmaps() const
389 {
390     return thePixmapArray->getNumImages();
391 }
392 
393 inline
394 SDL_Surface *
getPixmap(size_t i)395 RSprite::getPixmap(size_t i) const
396 {
397     return thePixmapArray->getImage(i);
398 }
399 
400 inline
401 const PixmapArray *
getPixmapArray()402 RSprite::getPixmapArray() const
403 {
404     return thePixmapArray;
405 }
406 
407 
408 }  // namespace flatzebra
409 
410 
411 #endif  /* _H_RSprite */
412