1 #include "ge211_sprites.h" 2 #include "ge211_error.h" 12 using namespace detail;
14 Sprite_set::Sprite_set() {}
20 sprites_.emplace_back(sprite, xy, z, t);
26 return add_sprite(sprite, xy, z,
Transform{});
32 int z,
const Transform& transform) noexcept
33 : sprite{&sprite}, xy{xy}, z{z}, transform{transform}
36 void Placed_sprite::render(Renderer& dst)
const 38 sprite->render(dst, xy, transform);
41 bool operator<(
const Placed_sprite& s1,
const Placed_sprite& s2) noexcept
48 return get_texture_().dimensions();
51 void Texture_sprite::render(Renderer& renderer,
53 const Transform& transform)
const 55 if (transform.is_identity())
56 renderer.copy(get_texture_(), position);
58 renderer.copy(get_texture_(), position, transform);
61 void Texture_sprite::prepare(
const Renderer& renderer)
const 63 renderer.prepare(get_texture_());
66 delete_ptr<SDL_Surface> Render_sprite::create_surface_(Dimensions dimensions)
68 SDL_Surface* surface =
69 SDL_CreateRGBSurfaceWithFormat(0,
73 SDL_PIXELFORMAT_RGBA32);
75 return {surface, &SDL_FreeSurface};
78 throw Host_error{
"Could not create sprite surface"};
81 Render_sprite::Render_sprite(Dimensions dimensions)
82 : texture_{create_surface_(dimensions)}
85 const Texture& Render_sprite::get_texture_()
const 90 SDL_Surface* Render_sprite::as_surface()
92 SDL_Surface* result = texture_.as_surface();
93 if (result)
return result;
95 throw Ge211_logic_error{
"Render_sprite::as_surface: already a texture"};
98 void Render_sprite::fill_surface(Color color)
100 auto surface = as_surface();
101 SDL_FillRect(surface,
nullptr, color.to_sdl_(surface->format));
104 void Render_sprite::fill_rectangle(Rectangle rect, Color color)
106 auto surface = as_surface();
107 SDL_Rect rect_buf = rect;
108 SDL_FillRect(surface, &rect_buf, color.to_sdl_(surface->format));
111 void Render_sprite::set_pixel(Position xy, Color color)
113 fill_rectangle({xy.x, xy.y, 1, 1}, color);
120 static Dimensions check_rectangle_dimensions(Dimensions dims)
122 if (dims.width <= 0 || dims.height <= 0) {
123 throw Client_logic_error(
124 "Rectangle_sprite: width and height must both be positive");
131 : Render_sprite{check_rectangle_dimensions(dims)}
141 static Dimensions compute_circle_dimensions(
int radius)
147 return {radius * 2, radius * 2};
151 : Render_sprite{compute_circle_dimensions(radius)}
153 const int cx = radius;
154 const int cy = radius;
156 for (
int y = 0; y < radius; ++y) {
157 for (
int x = 0; x < radius; ++x) {
158 if (x * x + y * y < radius * radius) {
159 set_pixel({cx + x, cy + y}, color);
160 set_pixel({cx + x, cy - y - 1}, color);
161 set_pixel({cx - x - 1, cy + y}, color);
162 set_pixel({cx - x - 1, cy - y - 1}, color);
173 int Circle_sprite::radius_()
const 179 Image_sprite::load_texture_(
const std::string& filename)
181 File_resource file(filename);
182 SDL_Surface* raw = IMG_Load_RW(file.get_raw(), 0);
183 if (raw)
return Texture(raw);
185 throw Image_error::could_not_load(filename);
189 : texture_{load_texture_(filename)} {}
191 const Texture& Image_sprite::get_texture_()
const 197 Text_sprite::create_texture(
const Builder& config)
201 std::string message = config.message();
206 if (config.word_wrap() > 0) {
207 raw = TTF_RenderUTF8_Blended_Wrapped(
208 config.font().get_raw_(),
210 config.color().to_sdl_(),
211 static_cast<uint32_t
>(config.word_wrap()));
213 auto render = config.antialias() ?
214 &TTF_RenderUTF8_Blended :
215 &TTF_RenderUTF8_Solid;
216 raw = render(config.font().get_raw_(),
218 config.color().to_sdl_());
222 throw Host_error{
"Could not render text: “" + message +
"”"};
228 : texture_{create_texture(config)} {}
237 const Texture& Text_sprite::get_texture_()
const 239 assert_initialized_();
243 void Text_sprite::assert_initialized_()
const 245 if (texture_.empty())
246 throw Client_logic_error{
"Attempt to render empty Text_sprite"};
250 : message_{}, font_{&font}, color_{
Color::white()}, antialias_{
true},
255 message_.str(message);
273 antialias_ = antialias;
279 if (word_wrap < 0) word_wrap = 0;
280 word_wrap_ =
static_cast<uint32_t
>(word_wrap);
291 return message_.str();
311 return static_cast<int>(word_wrap_);
316 texture_ = create_texture(config);
321 return texture_.empty();
324 Text_sprite::operator bool()
const 334 void Multiplexed_sprite::render(detail::Renderer& renderer,
338 const Sprite& selection = select_(since_.elapsed_time());
339 selection.render(renderer, position, transform);
int word_wrap() const
Gets the wrapping width that will be used.
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.
void reset()
Resets the age of the sprite to 0.
Coordinate width
The width of the object.
A Sprite that renders as a solid rectangle.
bool antialias() const
Gets whether anti-aliasing will be used.
The game engine namespace.
Circle_sprite(int radius, Color=Color::white())
Constructs a circle sprite from its radius and optionally a Color, which defaults to white...
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.
A sprite is an image that knows how to render itself to the screen at a given location, under a particular transformation.
A Sprite that renders as a solid circle.
Represents the dimensions of an object, or more generally, the displacement between two Basic_positio...
A position in the T-valued Cartesian plane.
std::string message() const
Gets the configured message.
A Sprite that displays text.
bool empty() const
Is this Text_sprite empty? (If so, you shouldn't try to use it.)
static constexpr Color white() noexcept
Solid white.
void reconfigure(Builder const &)
Resets this text sprite with the configuration from the given Builder.
Text_sprite()
Constructs an empty text sprite.
An exception that indicates that a logic error was performed by the client.
A collection of positioned sprites ready to be rendered to the screen.
Basic_dimensions< int > Dimensions
Type alias for the most common use of Basic_dimensions, which is with a coordinate type of int...
void recolor(Color)
Changes the color of this rectangle sprite.
Builder-style API for configuring and constructing Text_sprites.