ge211
ge211_sprites.h
1 #pragma once
2 
3 #include "ge211_color.h"
4 #include "ge211_forward.h"
5 #include "ge211_geometry.h"
6 #include "ge211_time.h"
7 #include "ge211_render.h"
8 #include "ge211_resource.h"
9 
10 #include <vector>
11 #include <sstream>
12 
13 namespace ge211 {
14 
18 namespace sprites {
19 
33 class Sprite
34 {
35 public:
43  virtual Dimensions dimensions() const = 0;
44 
45  virtual ~Sprite() {}
46 
47 private:
48  friend detail::Engine;
49  friend detail::Placed_sprite;
50  friend Multiplexed_sprite;
51 
52  virtual void render(detail::Renderer&,
53  Position,
54  Transform const&) const = 0;
55 
56  virtual void prepare(detail::Renderer const&) const {}
57 };
58 
59 } // end namespace sprites
60 
61 namespace detail {
62 
63 // A `Texture_sprite` is a `Sprite` that can be rendered by copying
64 // a texture. Instead of specifying how to render themselves directly,
65 // derived classes must specify how to get a `Texture` representing
66 // the sprite. The dimensions of the sprite are the dimensions of the
67 // resulting texture. The return type of `Texture const&` means that
68 // `get_texture_` cannot just create and return a texture, but must
69 // store it somewhere. This is because `Texture`s will usually be
70 // cached. (Otherwise, you wouldn't use a `Texture_sprite`.)
71 class Texture_sprite : public Sprite
72 {
73 public:
74  Dimensions dimensions() const override;
75 
76 private:
77  void render(detail::Renderer&, Position, Transform const&) const override;
78  void prepare(detail::Renderer const&) const override;
79 
80  virtual Texture const& get_texture_() const = 0;
81 };
82 
83 // A `Render_sprite` works by allowing its derived classes to render
84 // themselves onto an `SDL_Surface`, which it creates. It then converts
85 // that surface to a `Texture`, which it caches.
86 //
87 // The constructor of the derived class should pass the required
88 // dimensions to the `Render_sprite` constructor. Then, in its own
89 // constructor, use `as_surface` to access the underlying surface, and
90 // render the sprite image to that surface.
91 class Render_sprite : public Texture_sprite
92 {
93 protected:
96  explicit Render_sprite(Dimensions);
97 
100  void fill_surface(Color);
101 
104  void fill_rectangle(Rectangle, Color);
105 
108  void set_pixel(Position, Color);
109 
110 private:
111  Texture texture_;
112  Texture const& get_texture_() const override;
113 
116  SDL_Surface* as_surface();
117 
118  static delete_ptr<SDL_Surface> create_surface_(Dimensions);
119 };
120 
121 } // end namespace detail
122 
123 namespace sprites {
124 
126 class Rectangle_sprite : public detail::Render_sprite
127 {
128 public:
135 
137  void recolor(Color);
138 };
139 
141 class Circle_sprite : public detail::Render_sprite
142 {
143 public:
151  explicit Circle_sprite(int radius, Color = Color::white());
152 
154  void recolor(Color);
155 
156 private:
157  int radius_() const;
158 };
159 
161 class Image_sprite : public detail::Texture_sprite
162 {
163 public:
168  explicit Image_sprite(std::string const& filename);
169 
170 private:
171  detail::Texture const& get_texture_() const override;
172 
173  static detail::Texture load_texture_(std::string const& filename);
174 
175  detail::Texture texture_;
176 };
177 
179 class Text_sprite : public detail::Texture_sprite
180 {
181 public:
186  Text_sprite();
187 
195  Text_sprite(std::string const&, Font const&);
196 
199  bool empty() const;
200 
202  operator bool() const;
203 
204  // Defined below.
205  class Builder;
206 
208  void reconfigure(Builder const&);
209 
210 private:
211  explicit Text_sprite(Builder const&);
212 
213  void assert_initialized_() const;
214 
215  detail::Texture const& get_texture_() const override;
216 
217  static detail::Texture create_texture(Builder const&);
218 
219  detail::Texture texture_;
220 };
221 
235 class Text_sprite::Builder
236 {
237 public:
240 
242  explicit Builder(Font const&);
243 
245  Text_sprite build() const;
246 
248 
251 
255  template<class T>
256  Builder& add_message(T const& value)
257  {
258  message_ << value;
259  return *this;
260  }
261 
275  template<class T>
276  Builder& operator<<(T const& value)
277  {
278  return add_message(value);
279  }
280 
283  Builder& message(std::string const&);
286  Builder& font(Font const&);
289  Builder& color(Color);
293  Builder& antialias(bool);
298  Builder& word_wrap(int);
299 
301 
304 
306  std::string message() const;
308  Font const& font() const;
310  Color color() const;
312  bool antialias() const;
314  int word_wrap() const;
315 
317 
318 private:
319  std::ostringstream message_;
320  const Font* font_;
321  Color color_;
322  bool antialias_;
323  uint32_t word_wrap_;
324 };
325 
328 class Multiplexed_sprite : public Sprite
329 {
330 public:
332  void reset();
333 
334 protected:
337  virtual const Sprite& select_(Duration age) const = 0;
338 
339 private:
340  void render(detail::Renderer& renderer, Position position,
341  Transform const& transform) const override;
342 
343  Timer since_;
344 };
345 
346 } // end namespace sprites
347 
348 namespace detail {
349 
350 struct Placed_sprite
351 {
352  const Sprite* sprite;
353  Position xy;
354  int z;
355  Transform transform;
356 
357  Placed_sprite(Sprite const&, Position, int, Transform const&) noexcept;
358 
359  void render(Renderer&) const;
360 };
361 
362 bool operator<(Placed_sprite const&, Placed_sprite const&) noexcept;
363 
364 } // end namespace detail
365 
376 class Sprite_set
377 {
378 public:
389  Sprite_set& add_sprite(Sprite const&, Position, int z = 0);
390 
395  Sprite_set& add_sprite(Sprite const&, Position, int z, Transform const&);
396 
397 private:
398  friend detail::Engine;
399 
400  Sprite_set();
401  std::vector<detail::Placed_sprite> sprites_;
402 };
403 
404 }
int word_wrap() const
Gets the wrapping width that will be used.
A Sprite that displays a bitmap image.
Builder(Font const &)
Constructs a new Text_sprite::Builder with the given Font.
void recolor(Color)
Changes the color of this circle sprite.
Text_sprite build() const
Builds the configured Text_sprite.
A class for timing intervals. The result is a Duration.
Definition: ge211_time.h:242
void reset()
Resets the age of the sprite to 0.
bool antialias() const
Gets whether anti-aliasing will be used.
The game engine namespace.
Definition: ge211.h:17
Circle_sprite(int radius, Color=Color::white())
Constructs a circle sprite from its radius and optionally a Color, which defaults to white...
Builder & operator<<(T const &value)
Adds to the builder&#39;s message.
Font const & font() const
Gets the font that will be used.
Represents a font that can be used to render a sprites::Text_sprite.
virtual Dimensions dimensions() const =0
Returns the current dimensions of this Sprite.
Image_sprite(std::string const &filename)
Constructs an image sprite, given the filename of the image to display.
Sprite_set & add_sprite(Sprite const &, Position, int z=0)
Adds the given sprite at the given x–y geometry::Position and optional z coordinate, which defaults to 0.
Color color() const
Gets the color that will be used.
Builder & add_message(T const &value)
Adds to the builder&#39;s message.
A Sprite that allows switching between other sprites based on the time at rendering.
A sprite is an image that knows how to render itself to the screen at a given location, under a particular transformation.
Definition: ge211_sprites.h:33
virtual const Sprite & select_(Duration age) const =0
Override this to specify what sprite to render, based on the age of this sprite.
A Sprite that renders as a solid circle.
Represents the dimensions of an object, or more generally, the displacement between two Basic_positio...
Definition: ge211_forward.h:73
A position in the T-valued Cartesian plane.
Definition: ge211_forward.h:74
std::string message() const
Gets the configured message.
A rendering transform, which can scale, flip, and rotate.
A Sprite that displays text.
bool empty() const
Is this Text_sprite empty? (If so, you shouldn&#39;t try to use it.)
static constexpr Color white() noexcept
Solid white.
Definition: ge211_color.h:57
void reconfigure(Builder const &)
Resets this text sprite with the configuration from the given Builder.
Text_sprite()
Constructs an empty text sprite.
A length of time.
Definition: ge211_time.h:30
For representing colors.
Definition: ge211_color.h:22
void recolor(Color)
Changes the color of this rectangle sprite.
Rectangle_sprite(Dimensions, Color=Color::white())
Constructs a rectangle sprite from required Dimensions and an optional Color, which defaults to white...
Builder-style API for configuring and constructing Text_sprites.