ge211  2021.5.1
A student game engine
ge211_sprites.hxx
1 #pragma once
2 
3 #include "ge211_color.hxx"
4 #include "ge211_forward.hxx"
5 #include "ge211_geometry.hxx"
6 #include "ge211_noexcept.hxx"
7 #include "ge211_time.hxx"
8 #include "ge211_render.hxx"
9 #include "ge211_resource.hxx"
10 
11 #include <vector>
12 #include <sstream>
13 
14 namespace ge211 {
15 
19 namespace sprites {
20 
38 class Sprite
39 {
40 public:
48  virtual Dims<int> dimensions() const = 0;
49 
50  virtual ~Sprite() {}
51 
52 private:
53  friend class detail::Engine;
54  friend struct detail::Placed_sprite;
55  friend Multiplexed_sprite;
56 
57  virtual void render(detail::Renderer&,
58  Posn<int>,
59  Transform const&) const = 0;
60 
61  virtual void prepare(detail::Renderer const&) const {}
62 };
63 
64 } // end namespace sprites
65 
66 namespace detail {
67 
68 // A `Texture_sprite` is a `Sprite` that can be rendered by copying
69 // a texture. Instead of specifying how to render themselves directly,
70 // derived classes must specify how to get a `Texture` representing
71 // the sprite. The dimensions of the sprite are the dimensions of the
72 // resulting texture. The return type of `Texture const&` means that
73 // `get_texture_` cannot just create and return a texture, but must
74 // store it somewhere. This is because `Texture`s will usually be
75 // cached. (Otherwise, you wouldn't use a `Texture_sprite`.)
76 class Texture_sprite : public Sprite
77 {
78 public:
79  Dims<int> dimensions() const override;
80 
81 private:
82  void render(detail::Renderer&, Posn<int>, Transform const&) const override;
83  void prepare(detail::Renderer const&) const override;
84 
85  virtual Texture const& get_texture_() const = 0;
86 };
87 
88 } // end namespace detail
89 
90 namespace internal {
91 
104 class Render_sprite : public detail::Texture_sprite
105 {
106 protected:
111  explicit Render_sprite(Dims<int>);
112 
120  bool can_paint() const;
121 
129  void fill_surface(Color);
130 
139 
147  void set_pixel(Posn<int>, Color);
148 
159 
160 private:
161  detail::Texture texture_;
162 
163  detail::Texture const& get_texture_() const override;
164 
165  void fill_rectangle_(Rect<int>, Color, char const* who);
166 
167  Borrowed<SDL_Surface> raw_surface_(char const* who);
168 
169  static detail::Uniq_SDL_Surface
170  create_surface_(Dims<int>);
171 };
172 
173 } // end namespace internal
174 
175 namespace sprites {
176 
179 {
180 public:
187 
189  void recolor(Color);
190 };
191 
194 {
195 public:
203  explicit Circle_sprite(int radius, Color = Color::white());
204 
206  void recolor(Color);
207 
208 private:
209  int radius_() const;
210 };
211 
213 class Image_sprite : public detail::Texture_sprite
214 {
215 public:
220  explicit Image_sprite(std::string const& filename);
221 
222 private:
223  detail::Texture const& get_texture_() const override;
224 
225  static detail::Texture load_texture_(std::string const& filename);
226 
227  detail::Texture texture_;
228 };
229 
231 class Text_sprite : public detail::Texture_sprite
232 {
233 public:
272  Text_sprite();
273 
298  Text_sprite(std::string const&, Font const&);
299 
302  bool empty() const;
303 
305  explicit operator bool() const;
306 
307  // Defined below.
308  class Builder;
309 
311  void reconfigure(Builder const&);
312 
313 private:
314  explicit Text_sprite(Builder const&);
315 
316  void assert_initialized_() const;
317 
318  detail::Texture const& get_texture_() const override;
319 
320  static detail::Texture create_texture(Builder const&);
321 
322  detail::Texture texture_;
323 };
324 
363 {
364 public:
367 
369  explicit Builder(Font const&);
370 
372  Text_sprite build() const;
373 
375 
378 
382  template <typename PRINTABLE>
383  Builder& add_message(PRINTABLE const& value)
384  {
385  message_ << value;
386  return *this;
387  }
388 
402  template <typename PRINTABLE>
403  Builder& operator<<(PRINTABLE const& value)
404  {
405  return add_message(value);
406  }
407 
410  Builder& message(std::string const&);
413  Builder& font(Font const&);
416  Builder& color(Color);
420  Builder& antialias(bool);
425  Builder& word_wrap(int);
426 
428 
431 
433  std::string message() const;
435  Font const& font() const;
437  Color color() const;
439  bool antialias() const;
441  int word_wrap() const;
442 
444 
445 private:
446  std::ostringstream message_;
447  const Font* font_;
448  Color color_;
449  bool antialias_;
450  uint32_t word_wrap_;
451 };
452 
456 {
457 public:
459  void reset();
460 
461 protected:
464  virtual const Sprite& select_(Duration age) const = 0;
465 
466 private:
467  void render(detail::Renderer& renderer, Posn<int> position,
468  Transform const& transform) const override;
469 
470  Timer since_;
471 };
472 
473 } // end namespace sprites
474 
475 namespace detail {
476 
477 struct Placed_sprite
478 {
479  const Sprite* sprite;
480  Posn<int> xy;
481  int z;
482  Transform transform;
483 
484  Placed_sprite(Sprite const&, Posn<int>, int, Transform const&) NOEXCEPT;
485 
486  void render(Renderer&) const;
487 };
488 
489 bool operator<(Placed_sprite const&, Placed_sprite const&) NOEXCEPT;
490 
491 } // end namespace detail
492 
509 {
510 public:
542  Sprite_set& add_sprite(Sprite const& sprite,
543  Posn<int> xy,
544  int z = 0,
545  Transform const& transform = Transform());
546 
547 private:
548  friend class detail::Engine;
549 
550  Sprite_set();
552 };
553 
554 }
ge211::internal::Render_sprite::can_paint
bool can_paint() const
Returns whether we can paint to this Render_sprite.
ge211::sprites::Image_sprite::Image_sprite
Image_sprite(std::string const &filename)
Constructs an image sprite, given the filename of the image to display.
Definition: ge211_sprites.cxx:197
ge211::Sprite_set
A collection of positioned Sprites ready to be rendered to the screen.
Definition: ge211_sprites.hxx:509
ge211::sprites::Circle_sprite::recolor
void recolor(Color)
Changes the color of this circle sprite.
Definition: ge211_sprites.cxx:177
std::string
ge211::time::Duration
A length of time.
Definition: ge211_time.hxx:31
ge211::sprites::Circle_sprite
A Sprite that renders as a solid circle.
Definition: ge211_sprites.hxx:194
ge211::sprites::Text_sprite::Builder::antialias
bool antialias() const
Gets whether anti-aliasing will be used.
Definition: ge211_sprites.cxx:313
std::vector< detail::Placed_sprite >
ge211::internal::Render_sprite::fill_surface
void fill_surface(Color)
Fills the whole surface with the given color.
Definition: ge211_sprites.cxx:75
ge211::sprites::Circle_sprite::Circle_sprite
Circle_sprite(int radius, Color=Color::white())
Constructs a circle sprite from its radius and optionally a Color, which defaults to white.
Definition: ge211_sprites.cxx:159
ge211::internal::Render_sprite::fill_rectangle
void fill_rectangle(Rect< int >, Color)
Fills the given rectangle in the given color.
Definition: ge211_sprites.cxx:81
ge211::internal::Render_sprite::Render_sprite
Render_sprite(Dims< int >)
Constructs a Render_sprite with the given pixel dimensions.
Definition: ge211_sprites.cxx:66
ge211::sprites::Text_sprite::Builder::word_wrap
int word_wrap() const
Gets the wrapping width that will be used.
Definition: ge211_sprites.cxx:318
ge211::internal::Render_sprite::raw_surface
Borrowed< SDL_Surface > raw_surface()
Gains access to the underlying SDL_Surface☛.
Definition: ge211_sprites.cxx:70
ge211::Color::white
static constexpr Color white()
Solid white.
Definition: ge211_color.hxx:58
ge211
The game engine namespace.
Definition: ge211.hxx:4
ge211::sprites::Text_sprite::empty
bool empty() const
Is this Text_sprite empty? (If so, you shouldn't try to use it.)
Definition: ge211_sprites.cxx:328
ge211::sprites::Multiplexed_sprite::reset
void reset()
Resets the age of the sprite to 0.
Definition: ge211_sprites.cxx:338
ge211::sprites::Rectangle_sprite::Rectangle_sprite
Rectangle_sprite(Dims< int >, Color=Color::white())
Constructs a rectangle sprite from required Dims and an optional Color, which defaults to white.
Definition: ge211_sprites.cxx:139
ge211::sprites::Text_sprite::Builder::font
Font const & font() const
Gets the font that will be used.
Definition: ge211_sprites.cxx:303
ge211::sprites::Sprite
A sprite is an image that knows how to render itself to the screen at a given location,...
Definition: ge211_sprites.hxx:39
ge211::sprites::Text_sprite::Text_sprite
Text_sprite()
Constructs an empty text sprite.
Definition: ge211_sprites.cxx:239
ge211::sprites::Rectangle_sprite::recolor
void recolor(Color)
Changes the color of this rectangle sprite.
Definition: ge211_sprites.cxx:145
ge211::geometry::Dims< int >
ge211::sprites::Text_sprite::Builder::build
Text_sprite build() const
Builds the configured Text_sprite.
Definition: ge211_sprites.cxx:293
ge211::sprites::Sprite::dimensions
virtual Dims< int > dimensions() const =0
Returns the current dimensions of this Sprite.
ge211::time::Timer
A class for timing intervals. The result is a Duration.
Definition: ge211_time.hxx:268
ge211::sprites::Multiplexed_sprite::select_
virtual const Sprite & select_(Duration age) const =0
Override this to specify what sprite to render, based on the age of this sprite.
ge211::sprites::Rectangle_sprite
A Sprite that renders as a solid rectangle.
Definition: ge211_sprites.hxx:179
ge211::sprites::Text_sprite
A Sprite that displays text.
Definition: ge211_sprites.hxx:232
ge211::sprites::Multiplexed_sprite
A Sprite that allows switching between other sprites based on the time at rendering.
Definition: ge211_sprites.hxx:456
std::ostringstream
ge211::sprites::Text_sprite::Builder::Builder
Builder(Font const &)
Constructs a new Text_sprite::Builder with the given Font.
Definition: ge211_sprites.cxx:258
ge211::internal::Render_sprite
A Render_sprite works by allowing its derived classes to render themselves pixel-by-pixel onto an SDL...
Definition: ge211_sprites.hxx:105
ge211::Color
For representing colors.
Definition: ge211_color.hxx:24
std::internal
T internal(T... args)
ge211::internal::Render_sprite::set_pixel
void set_pixel(Posn< int >, Color)
Sets one pixel to the given color.
Definition: ge211_sprites.cxx:86
ge211::Font
Represents a font that can be used to render a sprites::Text_sprite.
Definition: ge211_resource.hxx:70
ge211::geometry::Transform
A rendering transformation, which can scale, flip, and rotate.
Definition: ge211_geometry.hxx:793
ge211::geometry::Posn< int >
ge211::sprites::Text_sprite::reconfigure
void reconfigure(Builder const &)
Resets this text sprite with the configuration from the given Builder.
Definition: ge211_sprites.cxx:323
ge211::geometry::Rect
Represents a positioned rectangle.
Definition: ge211_geometry.hxx:461
ge211::Sprite_set::add_sprite
Sprite_set & add_sprite(Sprite const &sprite, Posn< int > xy, int z=0, Transform const &transform=Transform())
Adds the given sprite to the sprite set to render it in the next frame.
Definition: ge211_sprites.cxx:18
ge211::sprites::Text_sprite::Builder::add_message
Builder & add_message(PRINTABLE const &value)
Adds to the builder's message.
Definition: ge211_sprites.hxx:383
ge211::sprites::Text_sprite::Builder::color
Color color() const
Gets the color that will be used.
Definition: ge211_sprites.cxx:308
ge211::sprites::Text_sprite::Builder::operator<<
Builder & operator<<(PRINTABLE const &value)
Adds to the builder's message.
Definition: ge211_sprites.hxx:403
ge211::sprites::Text_sprite::Builder::message
std::string message() const
Gets the configured message.
Definition: ge211_sprites.cxx:298
ge211::sprites::Image_sprite
A Sprite that displays a bitmap image.
Definition: ge211_sprites.hxx:214
ge211::sprites::Text_sprite::Builder
Builder-style API for configuring and constructing Text_sprites.
Definition: ge211_sprites.hxx:363
ge211::Borrowed
OBJECT_TYPE * Borrowed
Type alias to indicate that the given pointer does not own its object.
Definition: ge211_util.hxx:19