1 /*
2  * Copyright (C) 2006-2019 Christopho, Solarus - http://www.solarus-games.org
3  *
4  * Solarus is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Solarus is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #ifndef SOLARUS_SPRITE_H
18 #define SOLARUS_SPRITE_H
19 
20 #include "solarus/core/Common.h"
21 #include "solarus/graphics/Drawable.h"
22 #include "solarus/graphics/SpritePtr.h"
23 #include "solarus/lua/ScopedLuaRef.h"
24 #include <map>
25 #include <string>
26 
27 namespace Solarus {
28 
29 class Size;
30 class SpriteAnimation;
31 class SpriteAnimationSet;
32 class Tileset;
33 
34 /**
35  * \brief Represents an animated sprite.
36  *
37  * A sprite is represented as a set of animations
38  * (i.e. an instance of SpriteAnimationSet),
39  * a current animation,
40  * a current direction and a current frame.
41  * Several sprites can have the same animation set (i.e. they share
42  * the same SpriteAnimationSet object).
43  *
44  * A sprite can be drawn directly on a surface, or it can
45  * be attached to a map entity.
46  */
47 class Sprite: public Drawable {
48 
49   public:
50 
51     // initialization
52     static void initialize();
53     static void quit();
54 
55     // creation and destruction
56     explicit Sprite(const std::string& id);
57 
58     void set_tileset(const Tileset& tileset);
59 
60     // animation set
61     const std::string& get_animation_set_id() const;
62     const SpriteAnimationSet& get_animation_set() const;
63     void enable_pixel_collisions();
64     bool are_pixel_collisions_enabled() const;
65 
66     // size and origin point
67     virtual Size get_size() const override;
68     const Size& get_max_size() const;
69     virtual Point get_origin() const override;
70     const Rectangle& get_max_bounding_box() const;
71 
72     // animation state
73     const std::string& get_current_animation() const;
74     void set_current_animation(const std::string& animation_name);
75     bool has_animation(const std::string& animation_name) const;
76     int get_current_direction() const;
77     int get_nb_directions() const;
78     void set_current_direction(int current_direction);
79     int get_nb_frames() const;
80     int get_current_frame() const;
81     void set_current_frame(int current_frame, bool notify_script = true);
82     Rectangle get_current_frame_rectangle() const;
83     uint32_t get_frame_delay() const;
84     void set_frame_delay(uint32_t frame_delay);
85     uint32_t get_next_frame_date() const;
86     void set_synchronized_to(const SpritePtr& other);
87 
88     bool is_animation_started() const;
89     void start_animation();
90     void restart_animation();
91     void stop_animation();
92 
93     virtual void set_suspended(bool suspended) override;
94     bool get_ignore_suspend() const;
95     void set_ignore_suspend(bool ignore_suspend);
96     bool is_paused() const;
97     void set_paused(bool suspended);
98     bool is_animation_looping() const;
99     bool is_animation_finished() const;
100     bool is_last_frame_reached() const;
101     bool has_frame_changed() const;
102 
103     // effects
104     bool is_blinking() const;
105     void set_blinking(uint32_t blink_delay);
106 
107     // collisions
108     bool test_collision(const Sprite& other, int x1, int y1, int x2, int y2) const;
109 
110     // update and draw
111     virtual void update() override;
112     void draw_intermediate() const;
113 
114     Rectangle clamp_region(const Rectangle& region) const;
115 
116     virtual void raw_draw(Surface& dst_surface, const DrawInfos& infos) const override;
117     virtual void raw_draw_region(Surface& dst_surface, const DrawInfos& infos) const override;
118 
119     virtual Rectangle get_region() const override;
120 
121     // Lua
122     const ScopedLuaRef& get_finished_callback() const;
123     void set_finished_callback(const ScopedLuaRef& finished_callback_ref);
124     virtual const std::string& get_lua_type_name() const override;
125 
126   private:
127 
128     static SpriteAnimationSet& get_animation_set(const std::string& id);
129     int get_next_frame() const;
130     Surface& get_intermediate_surface() const ;
131     void set_frame_changed(bool frame_changed);
132     void notify_finished();
133 
134     // animation set
135     static std::map<std::string, SpriteAnimationSet*> all_animation_sets;
136     const std::string animation_set_id;  /**< id of this sprite's animation set */
137     SpriteAnimationSet& animation_set;   /**< animation set of this sprite */
138 
139     // current state of the sprite
140 
141     std::string current_animation_name;  /**< name of the current animation */
142     SpriteAnimation* current_animation;  /**< the current animation or nullptr if the sprite sheet has no animation */
143     int current_direction;             /**< current direction of the animation (the first one is number 0);
144                                         * it can be different from the movement direction
145                                         * of the entity, because sometimes a sprite can
146                                         * go backwards. */
147     int current_frame;                 /**< current frame of the animation (the first one is number 0) */
148     bool frame_changed;                /**< indicates that the frame has just changed */
149 
150     uint32_t frame_delay;              /**< delay between two frames in milliseconds */
151     uint32_t next_frame_date;          /**< date of the next frame */
152 
153     bool ignore_suspend;               /**< true to continue playing the animation even when the game is suspended */
154     bool paused;                       /**< true if the animation is paused */
155     bool finished;                     /**< true if the animation has been stopped because the last frame is finished */
156     SpritePtr
157         synchronize_to;                /**< another sprite to synchronize the frame to
158                                         * when they have the same animation name (or nullptr) */
159 
160     // effects
161     mutable SurfacePtr
162         intermediate_surface;          /**< an intermediate surface used to show transitions and other effects */
163     uint32_t blink_delay;              /**< blink delay of the sprite, or zero if the sprite is not blinking */
164     bool blink_is_sprite_visible;      /**< when blinking, true if the sprite is visible or false if it is invisible */
165     uint32_t blink_next_change_date;   /**< date of the next change when blinking: visible or not */
166 
167     ScopedLuaRef
168         finished_callback_ref;         /**< Lua ref to an action to do when this movement finishes.
169                                         * Automatically cleared when executed. */
170 
171 };
172 
173 }
174 
175 #endif
176 
177