1 /*************************************************************************/
2 /*  animated_sprite.h                                                    */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #ifndef ANIMATED_SPRITE_H
32 #define ANIMATED_SPRITE_H
33 
34 #include "scene/2d/node_2d.h"
35 #include "scene/resources/texture.h"
36 
37 class SpriteFrames : public Resource {
38 
39 	GDCLASS(SpriteFrames, Resource);
40 
41 	struct Anim {
42 
43 		float speed;
44 		bool loop;
45 		Vector<Ref<Texture> > frames;
46 
AnimAnim47 		Anim() {
48 			loop = true;
49 			speed = 5;
50 		}
51 
52 		StringName normal_name;
53 	};
54 
55 	Map<StringName, Anim> animations;
56 
57 	Array _get_frames() const;
58 	void _set_frames(const Array &p_frames);
59 
60 	Array _get_animations() const;
61 	void _set_animations(const Array &p_animations);
62 
63 	Vector<String> _get_animation_list() const;
64 
65 protected:
66 	static void _bind_methods();
67 
68 public:
69 	void add_animation(const StringName &p_anim);
70 	bool has_animation(const StringName &p_anim) const;
71 	void remove_animation(const StringName &p_anim);
72 	void rename_animation(const StringName &p_prev, const StringName &p_next);
73 
74 	void get_animation_list(List<StringName> *r_animations) const;
75 	Vector<String> get_animation_names() const;
76 
77 	void set_animation_speed(const StringName &p_anim, float p_fps);
78 	float get_animation_speed(const StringName &p_anim) const;
79 
80 	void set_animation_loop(const StringName &p_anim, bool p_loop);
81 	bool get_animation_loop(const StringName &p_anim) const;
82 
83 	void add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos = -1);
84 	int get_frame_count(const StringName &p_anim) const;
get_frame(const StringName & p_anim,int p_idx)85 	_FORCE_INLINE_ Ref<Texture> get_frame(const StringName &p_anim, int p_idx) const {
86 
87 		const Map<StringName, Anim>::Element *E = animations.find(p_anim);
88 		ERR_FAIL_COND_V_MSG(!E, Ref<Texture>(), "Animation '" + String(p_anim) + "' doesn't exist.");
89 		ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>());
90 		if (p_idx >= E->get().frames.size())
91 			return Ref<Texture>();
92 
93 		return E->get().frames[p_idx];
94 	}
95 
get_normal_frame(const StringName & p_anim,int p_idx)96 	_FORCE_INLINE_ Ref<Texture> get_normal_frame(const StringName &p_anim, int p_idx) const {
97 
98 		const Map<StringName, Anim>::Element *E = animations.find(p_anim);
99 		ERR_FAIL_COND_V_MSG(!E, Ref<Texture>(), "Animation '" + String(p_anim) + "' doesn't exist.");
100 		ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>());
101 
102 		const Map<StringName, Anim>::Element *EN = animations.find(E->get().normal_name);
103 
104 		if (!EN || p_idx >= EN->get().frames.size())
105 			return Ref<Texture>();
106 
107 		return EN->get().frames[p_idx];
108 	}
109 
set_frame(const StringName & p_anim,int p_idx,const Ref<Texture> & p_frame)110 	void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture> &p_frame) {
111 		Map<StringName, Anim>::Element *E = animations.find(p_anim);
112 		ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
113 		ERR_FAIL_COND(p_idx < 0);
114 		if (p_idx >= E->get().frames.size())
115 			return;
116 		E->get().frames.write[p_idx] = p_frame;
117 	}
118 	void remove_frame(const StringName &p_anim, int p_idx);
119 	void clear(const StringName &p_anim);
120 	void clear_all();
121 
122 	SpriteFrames();
123 };
124 
125 class AnimatedSprite : public Node2D {
126 
127 	GDCLASS(AnimatedSprite, Node2D);
128 
129 	Ref<SpriteFrames> frames;
130 	bool playing;
131 	bool backwards;
132 	StringName animation;
133 	int frame;
134 	float speed_scale;
135 
136 	bool centered;
137 	Point2 offset;
138 
139 	bool is_over;
140 	float timeout;
141 
142 	bool hflip;
143 	bool vflip;
144 
145 	void _res_changed();
146 
147 	float _get_frame_duration();
148 	void _reset_timeout();
149 	void _set_playing(bool p_playing);
150 	bool _is_playing() const;
151 	Rect2 _get_rect() const;
152 
153 protected:
154 	static void _bind_methods();
155 	void _notification(int p_what);
156 	virtual void _validate_property(PropertyInfo &property) const;
157 
158 public:
159 #ifdef TOOLS_ENABLED
160 	virtual Dictionary _edit_get_state() const;
161 	virtual void _edit_set_state(const Dictionary &p_state);
162 
163 	virtual void _edit_set_pivot(const Point2 &p_pivot);
164 	virtual Point2 _edit_get_pivot() const;
165 	virtual bool _edit_use_pivot() const;
166 	virtual Rect2 _edit_get_rect() const;
167 	virtual bool _edit_use_rect() const;
168 #endif
169 
170 	virtual Rect2 get_anchorable_rect() const;
171 
172 	void set_sprite_frames(const Ref<SpriteFrames> &p_frames);
173 	Ref<SpriteFrames> get_sprite_frames() const;
174 
175 	void play(const StringName &p_animation = StringName(), const bool p_backwards = false);
176 	void stop();
177 	bool is_playing() const;
178 
179 	void set_animation(const StringName &p_animation);
180 	StringName get_animation() const;
181 
182 	void set_frame(int p_frame);
183 	int get_frame() const;
184 
185 	void set_speed_scale(float p_speed_scale);
186 	float get_speed_scale() const;
187 
188 	void set_centered(bool p_center);
189 	bool is_centered() const;
190 
191 	void set_offset(const Point2 &p_offset);
192 	Point2 get_offset() const;
193 
194 	void set_flip_h(bool p_flip);
195 	bool is_flipped_h() const;
196 
197 	void set_flip_v(bool p_flip);
198 	bool is_flipped_v() const;
199 
200 	void set_modulate(const Color &p_color);
201 	Color get_modulate() const;
202 
203 	virtual String get_configuration_warning() const;
204 	AnimatedSprite();
205 };
206 
207 #endif // ANIMATED_SPRITE_H
208