Skip to content

Commit

Permalink
Move SpriteFrames to its own file in the resources folder
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronfranke committed Mar 16, 2021
1 parent a384fac commit a94cef0
Show file tree
Hide file tree
Showing 5 changed files with 345 additions and 275 deletions.
208 changes: 0 additions & 208 deletions scene/2d/animated_sprite_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,214 +105,6 @@ Rect2 AnimatedSprite2D::_get_rect() const {
return Rect2(ofs, s);
}

void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");

if (p_at_pos >= 0 && p_at_pos < E->get().frames.size()) {
E->get().frames.insert(p_at_pos, p_frame);
} else {
E->get().frames.push_back(p_frame);
}

emit_changed();
}

int SpriteFrames::get_frame_count(const StringName &p_anim) const {
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist.");

return E->get().frames.size();
}

void SpriteFrames::remove_frame(const StringName &p_anim, int p_idx) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");

E->get().frames.remove(p_idx);
emit_changed();
}

void SpriteFrames::clear(const StringName &p_anim) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");

E->get().frames.clear();
emit_changed();
}

void SpriteFrames::clear_all() {
animations.clear();
add_animation("default");
}

void SpriteFrames::add_animation(const StringName &p_anim) {
ERR_FAIL_COND_MSG(animations.has(p_anim), "SpriteFrames already has animation '" + p_anim + "'.");

animations[p_anim] = Anim();
}

bool SpriteFrames::has_animation(const StringName &p_anim) const {
return animations.has(p_anim);
}

void SpriteFrames::remove_animation(const StringName &p_anim) {
animations.erase(p_anim);
}

void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &p_next) {
ERR_FAIL_COND_MSG(!animations.has(p_prev), "SpriteFrames doesn't have animation '" + String(p_prev) + "'.");
ERR_FAIL_COND_MSG(animations.has(p_next), "Animation '" + String(p_next) + "' already exists.");

Anim anim = animations[p_prev];
animations.erase(p_prev);
animations[p_next] = anim;
}

Vector<String> SpriteFrames::_get_animation_list() const {
Vector<String> ret;
List<StringName> al;
get_animation_list(&al);
for (List<StringName>::Element *E = al.front(); E; E = E->next()) {
ret.push_back(E->get());
}

return ret;
}

void SpriteFrames::get_animation_list(List<StringName> *r_animations) const {
for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
r_animations->push_back(E->key());
}
}

Vector<String> SpriteFrames::get_animation_names() const {
Vector<String> names;
for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
names.push_back(E->key());
}
names.sort();
return names;
}

void SpriteFrames::set_animation_speed(const StringName &p_anim, float p_fps) {
ERR_FAIL_COND_MSG(p_fps < 0, "Animation speed cannot be negative (" + itos(p_fps) + ").");
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
E->get().speed = p_fps;
}

float SpriteFrames::get_animation_speed(const StringName &p_anim) const {
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist.");
return E->get().speed;
}

void SpriteFrames::set_animation_loop(const StringName &p_anim, bool p_loop) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
E->get().loop = p_loop;
}

bool SpriteFrames::get_animation_loop(const StringName &p_anim) const {
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V_MSG(!E, false, "Animation '" + String(p_anim) + "' doesn't exist.");
return E->get().loop;
}

void SpriteFrames::_set_frames(const Array &p_frames) {
clear_all();
Map<StringName, Anim>::Element *E = animations.find(SceneStringNames::get_singleton()->_default);
ERR_FAIL_COND(!E);

E->get().frames.resize(p_frames.size());
for (int i = 0; i < E->get().frames.size(); i++) {
E->get().frames.write[i] = p_frames[i];
}
}

Array SpriteFrames::_get_frames() const {
return Array();
}

Array SpriteFrames::_get_animations() const {
Array anims;
for (Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
Dictionary d;
d["name"] = E->key();
d["speed"] = E->get().speed;
d["loop"] = E->get().loop;
Array frames;
for (int i = 0; i < E->get().frames.size(); i++) {
frames.push_back(E->get().frames[i]);
}
d["frames"] = frames;
anims.push_back(d);
}

return anims;
}

void SpriteFrames::_set_animations(const Array &p_animations) {
animations.clear();
for (int i = 0; i < p_animations.size(); i++) {
Dictionary d = p_animations[i];

ERR_CONTINUE(!d.has("name"));
ERR_CONTINUE(!d.has("speed"));
ERR_CONTINUE(!d.has("loop"));
ERR_CONTINUE(!d.has("frames"));

Anim anim;
anim.speed = d["speed"];
anim.loop = d["loop"];
Array frames = d["frames"];
for (int j = 0; j < frames.size(); j++) {
RES res = frames[j];
anim.frames.push_back(res);
}

animations[d["name"]] = anim;
}
}

void SpriteFrames::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_animation", "anim"), &SpriteFrames::add_animation);
ClassDB::bind_method(D_METHOD("has_animation", "anim"), &SpriteFrames::has_animation);
ClassDB::bind_method(D_METHOD("remove_animation", "anim"), &SpriteFrames::remove_animation);
ClassDB::bind_method(D_METHOD("rename_animation", "anim", "newname"), &SpriteFrames::rename_animation);

ClassDB::bind_method(D_METHOD("get_animation_names"), &SpriteFrames::get_animation_names);

ClassDB::bind_method(D_METHOD("set_animation_speed", "anim", "speed"), &SpriteFrames::set_animation_speed);
ClassDB::bind_method(D_METHOD("get_animation_speed", "anim"), &SpriteFrames::get_animation_speed);

ClassDB::bind_method(D_METHOD("set_animation_loop", "anim", "loop"), &SpriteFrames::set_animation_loop);
ClassDB::bind_method(D_METHOD("get_animation_loop", "anim"), &SpriteFrames::get_animation_loop);

ClassDB::bind_method(D_METHOD("add_frame", "anim", "frame", "at_position"), &SpriteFrames::add_frame, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("get_frame_count", "anim"), &SpriteFrames::get_frame_count);
ClassDB::bind_method(D_METHOD("get_frame", "anim", "idx"), &SpriteFrames::get_frame);
ClassDB::bind_method(D_METHOD("set_frame", "anim", "idx", "txt"), &SpriteFrames::set_frame);
ClassDB::bind_method(D_METHOD("remove_frame", "anim", "idx"), &SpriteFrames::remove_frame);
ClassDB::bind_method(D_METHOD("clear", "anim"), &SpriteFrames::clear);
ClassDB::bind_method(D_METHOD("clear_all"), &SpriteFrames::clear_all);

ClassDB::bind_method(D_METHOD("_set_frames"), &SpriteFrames::_set_frames);
ClassDB::bind_method(D_METHOD("_get_frames"), &SpriteFrames::_get_frames);

ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "frames", PROPERTY_HINT_NONE, "", 0), "_set_frames", "_get_frames"); //compatibility

ClassDB::bind_method(D_METHOD("_set_animations"), &SpriteFrames::_set_animations);
ClassDB::bind_method(D_METHOD("_get_animations"), &SpriteFrames::_get_animations);

ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_animations", "_get_animations"); //compatibility
}

SpriteFrames::SpriteFrames() {
add_animation(SceneStringNames::get_singleton()->_default);
}

void AnimatedSprite2D::_validate_property(PropertyInfo &property) const {
if (!frames.is_valid()) {
return;
Expand Down
67 changes: 1 addition & 66 deletions scene/2d/animated_sprite_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,74 +32,9 @@
#define ANIMATED_SPRITE_2D_H

#include "scene/2d/node_2d.h"
#include "scene/resources/sprite_frames.h"
#include "scene/resources/texture.h"

class SpriteFrames : public Resource {
GDCLASS(SpriteFrames, Resource);

struct Anim {
float speed = 5.0;
bool loop = true;
Vector<Ref<Texture2D>> frames;
};

Map<StringName, Anim> animations;

Array _get_frames() const;
void _set_frames(const Array &p_frames);

Array _get_animations() const;
void _set_animations(const Array &p_animations);

Vector<String> _get_animation_list() const;

protected:
static void _bind_methods();

public:
void add_animation(const StringName &p_anim);
bool has_animation(const StringName &p_anim) const;
void remove_animation(const StringName &p_anim);
void rename_animation(const StringName &p_prev, const StringName &p_next);

void get_animation_list(List<StringName> *r_animations) const;
Vector<String> get_animation_names() const;

void set_animation_speed(const StringName &p_anim, float p_fps);
float get_animation_speed(const StringName &p_anim) const;

void set_animation_loop(const StringName &p_anim, bool p_loop);
bool get_animation_loop(const StringName &p_anim) const;

void add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos = -1);
int get_frame_count(const StringName &p_anim) const;
_FORCE_INLINE_ Ref<Texture2D> get_frame(const StringName &p_anim, int p_idx) const {
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist.");
ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
if (p_idx >= E->get().frames.size()) {
return Ref<Texture2D>();
}

return E->get().frames[p_idx];
}

void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture2D> &p_frame) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
ERR_FAIL_COND(p_idx < 0);
if (p_idx >= E->get().frames.size()) {
return;
}
E->get().frames.write[p_idx] = p_frame;
}
void remove_frame(const StringName &p_anim, int p_idx);
void clear(const StringName &p_anim);
void clear_all();

SpriteFrames();
};

class AnimatedSprite2D : public Node2D {
GDCLASS(AnimatedSprite2D, Node2D);

Expand Down
2 changes: 1 addition & 1 deletion scene/3d/sprite_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
#ifndef SPRITE_3D_H
#define SPRITE_3D_H

#include "scene/2d/animated_sprite_2d.h"
#include "scene/3d/visual_instance_3d.h"
#include "scene/resources/sprite_frames.h"

class SpriteBase3D : public GeometryInstance3D {
GDCLASS(SpriteBase3D, GeometryInstance3D);
Expand Down
Loading

0 comments on commit a94cef0

Please sign in to comment.