- optionally preserve center when modifying box size

- sprite scale modifier and scale quality setting
- get filled texture method
- get map keys utility method
This commit is contained in:
Frank DeMarco 2020-07-31 12:10:21 -04:00
parent 16e1cc19d0
commit 555c1e51a3
10 changed files with 114 additions and 26 deletions

View File

@ -10,7 +10,8 @@
config parameters on command line, effects chain, asset dict with metadata,
move added sprite locations by offset when location is changed, gradients,
level select code input, logging, variable screen resolution, debug display,
loading wheel animation, shadowed sprite, separate update and draw
loading wheel animation, shadowed sprite, separate update and draw, sprite
movement cage
:) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :)

View File

@ -47,10 +47,15 @@ glm::vec2 Box::get_size() const
return glm::vec2(get_w(), get_h());
}
void Box::set_size(const glm::vec2& size)
void Box::set_size(const glm::vec2& size, bool preserve_center)
{
glm::vec2 center = get_center();
set_w(size.x);
set_h(size.y);
if (preserve_center)
{
set_center(center);
}
}
float Box::get_top() const
@ -179,10 +184,15 @@ void Box::clear()
set_size(glm::vec2(0, 0));
}
void Box::scale(float amount)
void Box::scale(float amount, bool preserve_center)
{
glm::vec2 center = get_center();
set_w(get_w() * amount);
set_h(get_h() * amount);
if (preserve_center)
{
set_center(center);
}
}
void Box::move(const glm::vec2& delta)

View File

@ -23,7 +23,7 @@ struct Box
void set_w(float);
void set_h(float);
glm::vec2 get_size() const;
void set_size(const glm::vec2&);
void set_size(const glm::vec2&, bool = false);
float get_top() const;
float get_right() const;
float get_bottom() const;
@ -49,7 +49,7 @@ struct Box
SDL_FRect* get_rect();
SDL_Rect get_int_rect();
void clear();
void scale(float);
void scale(float, bool = false);
void move(const glm::vec2&);
std::string get_class_name() { return "Box"; }
std::ostream& to_string (std::ostream&) const;

View File

@ -58,8 +58,8 @@ bool Delegate::compare(SDL_Event& event, const std::vector<std::string>& command
bool Delegate::compare(SDL_Event& event, const std::string& command, bool neutral, bool cancel)
{
return event.type == command_event_type &&
(command == "" || command == *static_cast<std::string*>(event.user.data1)) &&
(neutral || (cancel == *static_cast<bool*>(event.user.data2)));
(command == "" || command == get_event_command(event)) &&
(neutral || (cancel == get_event_cancel_state(event)));
}
bool Delegate::compare_cancel(SDL_Event& event, const std::string& command)
@ -76,3 +76,13 @@ void Delegate::cancel_propagation()
{
cancelling_propagation = true;
}
const std::string& Delegate::get_event_command(SDL_Event& event) const
{
return *static_cast<std::string*>(event.user.data1);
}
bool Delegate::get_event_cancel_state(SDL_Event& event) const
{
return *static_cast<bool*>(event.user.data2);
}

View File

@ -33,6 +33,8 @@ struct Delegate : Node
bool compare_cancel(SDL_Event&, const std::string& = "");
bool compare_neutral(SDL_Event&, const std::string& = "");
void cancel_propagation();
const std::string& get_event_command(SDL_Event&) const;
bool get_event_cancel_state(SDL_Event&) const;
template<typename T>
void subscribe(void(T::*f)(SDL_Event&), T* o, int type = command_event_type)

View File

@ -23,6 +23,7 @@ struct Node
void set_parent(Node*);
void activate();
void deactivate();
virtual void reset() { deactivate(); };
bool is_active() const;
nlohmann::json& get_configuration();
Delegate& get_delegate();

View File

@ -51,7 +51,10 @@ void Sprite::load()
void Sprite::load_file(fs::path path)
{
Game *game = get_root();
const char* previous_scale_quality = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, scale_quality.c_str());
SDL_Texture *texture = IMG_LoadTexture(game->renderer, path.string().c_str());
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, previous_scale_quality);
if (not texture)
{
game->print_sdl_error("Could not load image");
@ -64,6 +67,7 @@ void Sprite::load_file(fs::path path)
void Sprite::add_frame(SDL_Texture* texture)
{
bool preserve_center = frames.size() > 0;
frames.push_back(texture);
Frameset& all_frames_frameset = get_all_frames_frameset();
all_frames_frameset.clear();
@ -75,7 +79,7 @@ void Sprite::add_frame(SDL_Texture* texture)
{
member.second.set_size();
}
update_size();
update_size(preserve_center);
}
Frameset& Sprite::get_all_frames_frameset()
@ -96,7 +100,7 @@ Frameset& Sprite::set_frameset(std::string name)
{
current_frameset_name = name;
frame_animation.set_frame_length(get_current_frameset().get_frame_length());
update_size();
update_size(true);
return get_current_frameset();
}
@ -119,22 +123,27 @@ void Sprite::add_box(glm::vec2 position, bool absolute)
boxes.emplace_back(glm::vec2(position.x, position.y), glm::vec2(get_w(), get_h()));
}
void Sprite::update_size()
void Sprite::update_size(bool preserve_center)
{
for (Box& box : boxes)
for (int ii = 0; ii < boxes.size(); ii++)
{
box.set_size(get_current_frameset().get_size());
get_box(ii).set_size(get_current_frameset().get_size(), preserve_center);
if (scale != 1)
{
get_box(ii).scale(scale, preserve_center);
}
}
}
void Sprite::set_scale(float s)
{
scale = s;
for (auto& member : framesets)
{
member.second.set_size(member.second.get_size() * s);
}
update_size();
update_size(true);
}
void Sprite::set_scale_quality(const std::string& quality)
{
scale_quality = quality;
}
float Sprite::get_scale() const
@ -256,6 +265,11 @@ glm::vec2 Sprite::get_east(int index)
return get_box(index).get_east();
}
glm::vec2 Sprite::get_south(int index)
{
return get_box(index).get_south();
}
glm::vec2 Sprite::get_west(int index)
{
return get_box(index).get_west();
@ -266,6 +280,11 @@ glm::vec2 Sprite::get_center(int index)
return get_box(index).get_center();
}
void Sprite::set_south(const glm::vec2& south)
{
move(south - get_south(), false);
}
void Sprite::set_nw(const glm::vec2& nw)
{
move(nw - get_nw(), false);
@ -362,9 +381,9 @@ void Sprite::update()
SDL_Rect wrap_frame_rect = wrap_frame.get_int_rect();
SDL_RenderSetClipRect(renderer, &wrap_frame_rect);
}
for (Box& box : boxes)
for (int ii = 0; ii < boxes.size(); ii++)
{
SDL_RenderCopyF(renderer, texture, NULL, box.get_rect());
SDL_RenderCopyF(renderer, texture, NULL, get_box(ii).get_rect());
}
if (wrap.x || wrap.y)
{
@ -400,7 +419,7 @@ float Frameset::get_frame_length() const
void Frameset::reset()
{
current_index = 0;
set_order_index(0);
}
void Frameset::clear()
@ -409,9 +428,19 @@ void Frameset::clear()
reset();
}
int Frameset::get_order_index() const
{
return order_index;
}
void Frameset::set_order_index(int index)
{
order_index = index;
}
int Frameset::get_current_frame_index() const
{
return order[current_index];
return order[get_order_index()];
}
glm::vec2 Frameset::measure() const
@ -469,7 +498,7 @@ void Frameset::increment_index()
void Frameset::increment_index(int increment)
{
current_index = (current_index + increment) % order.size();
set_order_index((order_index + increment) % order.size());
}
int Frameset::get_frame_count() const

View File

@ -29,6 +29,7 @@ struct Sprite : Node
bool hidden = false;
glm::vec2 step = {0, 0};
float scale = 1;
std::string scale_quality = "nearest";
Uint8 alpha_mod = 255;
std::map<std::string, Frameset> framesets;
std::string current_frameset_name;
@ -48,8 +49,9 @@ struct Sprite : Node
Frameset& get_current_frameset();
Box& get_box(int = 0);
void add_box(glm::vec2, bool = false);
void update_size();
void update_size(bool = false);
void set_scale(float);
void set_scale_quality(const std::string&);
float get_scale() const;
bool is_loaded() const;
void unload();
@ -72,10 +74,12 @@ struct Sprite : Node
glm::vec2 get_north(int = 0);
glm::vec2 get_ne(int = 0);
glm::vec2 get_east(int = 0);
glm::vec2 get_south(int = 0);
glm::vec2 get_west(int = 0);
glm::vec2 get_center(int = 0);
void set_nw(const glm::vec2&);
void set_ne(const glm::vec2&);
void set_south(const glm::vec2&);
void set_center(const glm::vec2&);
void add_wrap(bool, bool);
void add_wrap(bool, bool, Box);
@ -91,7 +95,7 @@ struct Frameset
Sprite* sprite;
std::vector<int> order;
int current_index = 0;
int order_index = 0;
float frame_length = 0;
bool reversed = false;
glm::vec2 size;
@ -104,6 +108,8 @@ struct Frameset
float get_frame_length() const;
void reset();
void clear();
int get_order_index() const;
void set_order_index(int);
int get_current_frame_index() const;
glm::vec2 measure() const;
void set_size();

View File

@ -18,9 +18,10 @@ Box sfw::get_texture_box(SDL_Texture* texture)
return Box(glm::vec2(0, 0), glm::vec2(w, h));
}
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, int r, int g, int b, int a)
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(renderer, r, g, b, a);
SDL_RenderFillRect(renderer, NULL);
}
@ -40,6 +41,20 @@ void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Texture
}
}
SDL_Texture* sfw::get_filled_texture(SDL_Renderer* renderer, glm::vec2 size, const SDL_Color& color, Uint32 format)
{
SDL_Texture* texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
sfw::fill_texture(renderer, texture, color.r, color.g, color.b, color.a);
return texture;
}
SDL_Texture* sfw::get_filled_texture(SDL_Renderer* renderer, glm::vec2 size, SDL_Texture* tile, Uint32 format)
{
SDL_Texture* texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
sfw::fill_texture(renderer, texture, tile);
return texture;
}
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, Uint32 format)
{
Box box = get_texture_box(base);

View File

@ -28,8 +28,10 @@ namespace sfw
glm::vec2 get_step(glm::vec2, glm::vec2, float);
void set_magnitude(glm::vec2&, float);
Box get_texture_box(SDL_Texture*);
void fill_texture(SDL_Renderer*, SDL_Texture*, int, int, int, int = 0xff);
void fill_texture(SDL_Renderer*, SDL_Texture*, Uint8, Uint8, Uint8, Uint8 = 0xff);
void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*);
SDL_Texture* get_filled_texture(SDL_Renderer*, glm::vec2, const SDL_Color&, Uint32 = SDL_PIXELFORMAT_RGBA32);
SDL_Texture* get_filled_texture(SDL_Renderer*, glm::vec2, SDL_Texture*, Uint32 = SDL_PIXELFORMAT_RGBA32);
SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*, Uint32 = SDL_PIXELFORMAT_RGBA32);
SDL_Texture* get_remapped_texture(
SDL_Renderer*, SDL_Texture*, const std::map<SDL_Color, SDL_Color>&, Uint32 = SDL_PIXELFORMAT_RGBA32);
@ -43,6 +45,18 @@ namespace sfw
void print_error(const std::string&);
void print_sdl_error(const std::string&);
template<typename Key, typename Value, template <typename...> class Map>
std::vector<Key> get_keys(const Map<Key, Value>& map)
{
std::vector<Key> keys;
keys.reserve(map.size());
for (auto& member : map)
{
keys.push_back(member.first);
}
return keys;
}
template<typename T1, typename T2>
bool is_in_container(T1& container, T2& member)
{