Gamedev Framework (gf)  0.6.0
A C++11 framework for 2D games
Map.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2017 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_MAP_H
22 #define GF_MAP_H
23 
24 #include "Array2D.h"
25 #include "Flags.h"
26 #include "Portability.h"
27 #include "Vector.h"
28 
29 namespace gf {
30 #ifndef DOXYGEN_SHOULD_SKIP_THIS
31 inline namespace v1 {
32 #endif
33 
34  /**
35  * @ingroup game
36  * @brief A property of a cell
37  *
38  * @sa gf::CellFlags, gf::SquareMap
39  */
40  enum class CellProperty : uint8_t {
41  Transparent = 0x01, ///< The cell is transparent
42  Walkable = 0x02, ///< The cell is walkable
43  Visible = 0x10, ///< The cell is visible (computed by FoV)
44  Explored = 0x20, ///< The cell has been explored (computed by FoV)
45  };
46 
47  /**
48  * @ingroup game
49  * @brief Flags composed of cell properties
50  *
51  * @sa gf::CellProperty
52  */
53  using CellFlags = Flags<CellProperty>;
54 
55  /**
56  * @ingroup game
57  * @brief An empty cell
58  *
59  * An empty cell is transparent and walkable.
60  *
61  * @sa gf::CellProperty, gf::SquareMap
62  */
63  constexpr CellFlags EmptyCell = combineFlags(CellProperty::Transparent, CellProperty::Walkable);
64 
65  /**
66  * @ingroup game
67  * @brief Algorithm for computing a field of vision
68  *
69  * @sa gf::SquareMap
70  */
71  enum class FieldOfVision {
72  Basic, ///< A basic algorithm based on ray casting
73  };
74 
75  /**
76  * @ingroup game
77  * @brief Constant to indicate if the limit is part of the field of vision
78  *
79  * The limit is generally a wall that is next to a visible ground cell.
80  *
81  * @sa gf::SquareMap
82  */
83  enum class FieldOfVisionLimit {
84  Included, ///< The limits are included in the field of vision
85  Excluded, ///< The limits are *not* included in the field of vision
86  };
87 
88  /**
89  * @ingroup game
90  * @brief Algorithm for computing a route
91  *
92  * @sa gf::SquareMap
93  */
94  enum class Route {
95  AStar, ///< The A* algorithm
96  Dijkstra, ///< The Dijkstra algorithm
97  };
98 
99  /**
100  * @ingroup game
101  * @brief A square map
102  *
103  * A square map is a model of map where cells are organized in a square grid.
104  * This type of map is quite common in games. gf provides some useful
105  * algorithms related to square maps: field of vision, route finding.
106  *
107  * A cell can be transparent and/or walkable. By default, all cells are
108  * neither transparent nor walkable i.e. they are walls. The transparent
109  * property of a cell is used to compute the field of vision. The walkable
110  * property of a cell is used to compute routes. A cell can be transparent
111  * and not walkable (e.g. lava or water), it can be walkable and not
112  * transparent (e.g. a secret passage).
113  *
114  * @sa gf::CellProperty
115  */
117  public:
118 
119 
120  /**
121  * @brief Constructor
122  *
123  * @param size The size of the map
124  */
125  SquareMap(Vector2i size);
126 
127  /**
128  * @brief Get the size of the map
129  *
130  * @returns The size of the map
131  */
132  Vector2i getSize() const;
133 
134  /**
135  * @brief Get a range of the positions of the map
136  *
137  * @returns A 2D range of all the positions
138  *
139  * @sa Array2D::getPositionRange()
140  */
141  PositionRange<int> getRange() const;
142 
143  /**
144  * @name Cell properties
145  * @{
146  */
147 
148  /**
149  * @brief Set the properties of a cell
150  *
151  * This function directly set all the properties of a cell. You should use
152  * the other functions that set a particular property.
153  *
154  * @param pos The position of the cell
155  * @param flags The properties of the cell
156  *
157  * @sa setTransparent(), setWalkable(), setEmpty()
158  */
159  void setCell(Vector2i pos, CellFlags flags);
160 
161  /**
162  * @brief Initialize the cells with some properties
163  *
164  * @param flags The properties to set
165  */
166  void clear(CellFlags flags);
167 
168  /**
169  * @brief Make a cell transparent
170  *
171  * @param pos The position of the cell
172  *
173  * @sa isTransparent()
174  */
175  void setTransparent(Vector2i pos);
176 
177  /**
178  * @brief Check if a cell is transparent
179  *
180  * @returns True if the cell is transparent
181  *
182  * @sa setTransparent()
183  */
184  bool isTransparent(Vector2i pos) const;
185 
186  /**
187  * @brief Make a cell walkable
188  *
189  * @param pos The position of the cell
190  *
191  * @sa isWalkable()
192  */
193  void setWalkable(Vector2i pos);
194 
195  /**
196  * @brief Check if a cell is walkable
197  *
198  * @sa setWalkable()
199  */
200  bool isWalkable(Vector2i pos) const;
201 
202  /**
203  * @brief Make a cell empty
204  *
205  * An empty cell is walkable and transparent
206  *
207  * @param pos The position of the cell
208  */
209  void setEmpty(Vector2i pos);
210 
211  /**
212  * @}
213  */
214 
215  /**
216  * @name Field of Vision
217  * @{
218  */
219 
220  /**
221  * @brief Make the whole map not visible
222  *
223  * You should call this function before computing a new field of vision.
224  *
225  * @sa computeFieldOfVision()
226  */
227  void clearFieldOfVision();
228 
229  /**
230  * @brief Make the whole map not explored
231  *
232  * You should call this function before exploring a new map.
233  *
234  * @sa computeFieldOfVision()
235  */
236  void clearExplored();
237 
238  /**
239  * @brief Compute a field of vision
240  *
241  * The map is not cleared before computing the field of vision. The
242  * algorithm use the transparent property of the cells. After calling this
243  * function, some cells are marked visible.
244  *
245  * This algorithm marks visible cells as explored.
246  *
247  * @param pos The position of the entity
248  * @param maxRadius The maximum radius that the entity can see
249  * @param limit Is the limit included in the field of vision?
250  * @param algorithm The algorithm to use for computing the field of vision
251  *
252  * @sa clearFieldOfVision(), isInFieldOfVision()
253  */
254  void computeFieldOfVision(Vector2i pos, int maxRadius = 0, FieldOfVisionLimit limit = FieldOfVisionLimit::Included, FieldOfVision algorithm = FieldOfVision::Basic);
255 
256  /**
257  * @brief Compute a local field of vision
258  *
259  * The map is not cleared before computing the field of vision. The
260  * algorithm use the transparent property of the cells. After calling this
261  * function, some cells are marked visible.
262  *
263  * This algorithm does not mark visible cells as explored. It can be used
264  * for computing an ennemy field of view without modifying the explored
265  * area of the hero.
266  *
267  * @param pos The position of the entity
268  * @param maxRadius The maximum radius that the entity can see
269  * @param limit Is the limit included in the field of vision?
270  * @param algorithm The algorithm to use for computing the field of vision
271  *
272  * @sa clearFieldOfVision(), isInFieldOfVision()
273  */
274  void computeLocalFieldOfVision(Vector2i pos, int maxRadius = 0, FieldOfVisionLimit limit = FieldOfVisionLimit::Included, FieldOfVision algorithm = FieldOfVision::Basic);
275 
276  /**
277  * @brief Check if a cell is visible
278  *
279  * Cells can be made visible by computing a field of vision.
280  *
281  * @returns True if the cell is visible
282  *
283  * @sa computeFieldOfVision()
284  */
285  bool isInFieldOfVision(Vector2i pos) const;
286 
287  /**
288  * @brief Check if a cell is explored
289  *
290  * Cells are explored if they have been in the field of vision after a
291  * call to clearExplored().
292  *
293  * @sa computeFieldOfVision(), isInFieldOfVision()
294  */
295  bool isExplored(Vector2i pos) const;
296 
297  /**
298  * @}
299  */
300 
301  /**
302  * @name Route
303  * @{
304  */
305 
306  /**
307  * @brief Compute a route between two points
308  *
309  * The algorithm use the walkable property of the cells. Diagonal movement
310  * can be allowed and its cost can be adjusted (defaults to
311  * @f$ \sqrt{2} @f$).
312  *
313  * @param origin The origin of the route
314  * @param target The target of the route
315  * @param diagonalCost The cost of going diagonal between two cells (0 means no diagonal movement)
316  * @param algorithm The algorithm to use for computing the route
317  * @returns The route between the two points (included)
318  */
320 
321  /**
322  * @}
323  */
324 
325  private:
326  Array2D<CellFlags, int> m_cells;
327  };
328 
329 #ifndef DOXYGEN_SHOULD_SKIP_THIS
330 }
331 
332 template<>
333 struct EnableBitmaskOperators<CellProperty> {
334  static constexpr bool value = true;
335 };
336 #endif
337 }
338 
339 
340 
341 #endif // GF_MAP_H
void setWalkable(Vector2i pos)
Make a cell walkable.
A two-dimensional array.
Definition: Array2D.h:63
void clearExplored()
Make the whole map not explored.
void setTransparent(Vector2i pos)
Make a cell transparent.
Route
Algorithm for computing a route.
Definition: Map.h:94
void clearFieldOfVision()
Make the whole map not visible.
void computeFieldOfVision(Vector2i pos, int maxRadius=0, FieldOfVisionLimit limit=FieldOfVisionLimit::Included, FieldOfVision algorithm=FieldOfVision::Basic)
Compute a field of vision.
Bitfield relying on an enumeration.
Definition: Flags.h:68
PositionRange< int > getRange() const
Get a range of the positions of the map.
The limits are included in the field of vision.
void setEmpty(Vector2i pos)
Make a cell empty.
CellProperty
A property of a cell.
Definition: Map.h:40
bool isExplored(Vector2i pos) const
Check if a cell is explored.
The cell is visible (computed by FoV)
bool isInFieldOfVision(Vector2i pos) const
Check if a cell is visible.
A basic algorithm based on ray casting.
void clear(CellFlags flags)
Initialize the cells with some properties.
FieldOfVisionLimit
Constant to indicate if the limit is part of the field of vision.
Definition: Map.h:83
The Dijkstra algorithm.
The namespace for gf classes.
Definition: Action.h:34
void setCell(Vector2i pos, CellFlags flags)
Set the properties of a cell.
FieldOfVision
Algorithm for computing a field of vision.
Definition: Map.h:71
std::vector< Vector2i > computeRoute(Vector2i origin, Vector2i target, float diagonalCost=Sqrt2, Route algorithm=Route::AStar)
Compute a route between two points.
Vector2i getSize() const
Get the size of the map.
A square map.
Definition: Map.h:116
bool isWalkable(Vector2i pos) const
Check if a cell is walkable.
SquareMap(Vector2i size)
Constructor.
bool isTransparent(Vector2i pos) const
Check if a cell is transparent.
The A* algorithm.
A 2D range.
Definition: Range.h:225
void computeLocalFieldOfVision(Vector2i pos, int maxRadius=0, FieldOfVisionLimit limit=FieldOfVisionLimit::Included, FieldOfVision algorithm=FieldOfVision::Basic)
Compute a local field of vision.
The cell is walkable.
The cell is transparent.
The cell has been explored (computed by FoV)
#define GF_API
Definition: Portability.h:35
The limits are not included in the field of vision.
constexpr CellFlags EmptyCell
An empty cell.
Definition: Map.h:63