1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
|
#ifndef PLAYGROUND_H
#define PLAYGROUND_H
#include <vector>
#include <list>
#include <set>
#include <map>
#include "File.h"
#include "XMLElements.h"
#include "Matrix.h"
#include "SDLTools.h"
#include "ObjectVisitors.h"
//----------------------------------------------------------------------------
class PlayGround
{
friend class PlayGroundTest;
friend class CollisionTest;
typedef Matrix<bool> BackgroundMatrix;
typedef Matrix<int> GravityMatrix;
typedef Matrix<int> VelocityMatrix;
typedef Matrix<unsigned> FrictionMatrix;
public:
typedef std::vector<SDL_Rect> UpdateRects;
~PlayGround();
/// (Re)initialize sm_instance from the given XML node.
static void init(const char *mission, const XMLNode *playGroundNode);
/// Destroy the sm_instance PlayGround.
static void destroy();
static inline PlayGround *getInstance()
{
return sm_instance;
}
//------------------------------------------------------------------------
const Platform *isInLandingZone(const Ship *ship) const;
inline bool isBackgroundTile(Uint16 x, Uint16 y) const
{
return m_background.get(x, y);
}
/**
* @return true, if there are only background tiles between the
* tile coordinates (x1/y1) and (x2/y2), else false.
*/
bool isBackgroundBetween(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2) const;
inline const SDL_Surface *getCollisionSurface() const
{
return m_collisionSurface;
}
inline const SDL_Surface *getMapSurface() const
{
return m_mapSurface;
}
inline const SDL_Surface *getShadowSurface() const
{
return m_shadowSurface;
}
inline const SDL_Rect &getBoundingBox() const
{
return m_boundingBox;
}
//------------------------------------------------------------------------
inline void setXGravityAll(int gx)
{
m_xGravity.setAll(gx);
}
inline void setYGravityAll(int gy)
{
m_yGravity.setAll(gy);
}
inline void setXGravity(Uint16 x, Uint16 y, int gx)
{
m_xGravity.set(x, y, gx);
}
inline void setYGravity(Uint16 x, Uint16 y, int gy)
{
m_yGravity.set(x, y, gy);
}
inline void addXGravity(Uint16 x, Uint16 y, int gx)
{
m_xGravity.set(x, y, m_xGravity.get(x, y) + gx);
}
inline void addYGravity(Uint16 x, Uint16 y, int gy)
{
m_yGravity.set(x, y, m_yGravity.get(x, y) + gy);
}
int getXGravity(const SDL_Rect &r) const;
int getYGravity(const SDL_Rect &r) const;
//------------------------------------------------------------------------
inline void setXVelocityAll(int vx)
{
m_xVelocity.setAll(vx);
}
inline void setYVelocityAll(int vy)
{
m_yVelocity.setAll(vy);
}
inline void setXVelocity(Uint16 x, Uint16 y, int vx)
{
m_xVelocity.set(x, y, vx);
}
inline void setYVelocity(Uint16 x, Uint16 y, int vy)
{
m_yVelocity.set(x, y, vy);
}
inline void addXVelocity(Uint16 x, Uint16 y, int vx)
{
m_xVelocity.set(x, y, m_xVelocity.get(x, y) + vx);
}
inline void addYVelocity(Uint16 x, Uint16 y, int vy)
{
m_yVelocity.set(x, y, m_yVelocity.get(x, y) + vy);
}
int getXVelocity(const SDL_Rect &r) const;
int getYVelocity(const SDL_Rect &r) const;
//------------------------------------------------------------------------
inline void setFrictionAll(int friction)
{
m_friction.setAll(friction);
}
inline void setFriction(Uint16 x, Uint16 y, unsigned friction)
{
m_friction.set(x, y, friction);
}
inline void addFriction(Uint16 x, Uint16 y, unsigned friction)
{
m_friction.set(x, y, m_friction.get(x, y) + friction);
}
unsigned getFriction(const SDL_Rect &r) const;
//------------------------------------------------------------------------
/**
* Called by RescueGame::Running::onShipLanded()
* to search for a crate, the ship landed on.
*
* @return The crate, or NULL if no such crate exists,
* or the ship hasn't enough capacity.
*/
Crate *hasCrateFor(const Ship *ship) const;
/**
* Checks if the object collides with the collision surface.
*/
bool collidesWith(const ObjectBase *object) const;
/**
* Checks if the particle collides with the collision surface.
*/
bool collidesWithParticle(const ParticleBase *particle) const;
//------------------------------------------------------------------------
/**
* Called by the main loop to update the PlayGround
* including all objects inside the PlayGround.
* A list of update rectangles will be generated
* and stored in m_updateRects.
* These rectangles will be used by the main loop
* to update the screen content.
*
* @throw SDLException if the blitting of an object failed.
*/
void update();
/**
* Called by PlayGroundMenu to create a preview.
*/
void updateForPreview();
/**
* Called by UpdateObjectsVisitor to add a SDL_Rect to update.
*/
inline void addUpdateRect(const SDL_Rect &r)
{
m_updateRects.push_back(r);
}
/**
* @return A const reference to the SDL_Rects to update.
*/
inline const UpdateRects &getUpdateRects() const
{
return m_updateRects;
}
protected:
PlayGround();
/// Called by readMapFrom().
void resize(Uint16 xTiles, Uint16 yTiles);
/// Called by create() to initialize the map data.
void readMapFrom(const char *mission, const char *map);
/// The collision surface, containing only non-background tiles of the map.
SDL_Surface *m_collisionSurface;
/// The map surface, containing all tiles of the map.
SDL_Surface *m_mapSurface;
/// The shadow surface, containing everything.
SDL_Surface *m_shadowSurface;
/// The bounding box of the whole map.
SDL_Rect m_boundingBox;
/// m_background.get(x, y) indicates, if the tile x/y is a background tile.
BackgroundMatrix m_background;
/// The x-gravity matrix in resolution of the background tiles.
GravityMatrix m_xGravity;
/// The y-gravity matrix in resolution of the background tiles.
GravityMatrix m_yGravity;
/// The x-velocity matrix in resolution of the background tiles.
VelocityMatrix m_xVelocity;
/// The y-velocity matrix in resolution of the background tiles.
VelocityMatrix m_yVelocity;
/// The friction in resulution of the background tiles.
FrictionMatrix m_friction;
/// The SDL_Rects to update for the current frame.
UpdateRects m_updateRects;
private:
/// Helper-method for readMapFromFile() to read version 1 maps.
void readMapV1(File &f);
/// Helper-method for readMapFromFile() to read version 2 maps.
void readMapV2(File &f);
/// Helper-method for isBackgroundBetween().
bool do_isBackgroundBetweenX(Uint16 x1, Uint16 y1,
Uint16 x2, Uint16 y2) const;
/// Helper-method for isBackgroundBetween().
bool do_isBackgroundBetweenY(Uint16 x1, Uint16 y1,
Uint16 x2, Uint16 y2) const;
/// The current active PlayGround instance.
static PlayGround *sm_instance;
};
#endif //PLAYGROUND_H
|