aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api/Sprite.h
blob: 3565bedc1ec05cdfecf28361345db8ff0a6ae702 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once

#include "../Component.h"
#include "api/Asset.h"

#include "Color.h"
#include "types.h"

namespace crepe {

class SDLContext;
class Animator;
class AnimatorSystem;

/**
 * \brief Represents a renderable sprite component.
 *
 * A renderable sprite that can be displayed in the game. It includes a texture, color, and
 * flip settings, and is managed in layers with defined sorting orders.
 */
class Sprite : public Component {
public:
	//! settings to flip the image
	struct FlipSettings {
		//! horizantal flip
		bool flip_x = false;
		//! vertical flip
		bool flip_y = false;
	};

	//! Sprite data that does not have to be set in the constructor
	struct Data {
		/**
		 * \brief Sprite tint (multiplied)
		 *
		 * The sprite texture's pixels are multiplied by this color before being displayed
		 * (including alpha channel for transparency).
		 */
		Color color = Color::WHITE;

		//! Flip settings for the sprite
		FlipSettings flip;

		//! Layer sorting level of the sprite
		int sorting_in_layer = 0;

		//! Order within the sorting layer
		int order_in_layer = 0;

		/**
		 * \brief width and height of the sprite in game units
		 *
		 * - if exclusively width is specified, the height is calculated using the texture's aspect
		 *   ratio
		 * - if exclusively height is specified, the width is calculated using the texture's aspect
		 *   ratio
		 * - if both are specified the texture is streched to fit the specified size
		 */
		vec2 size = {0, 0};

		//! independent sprite angle. rotating clockwise direction in degrees
		float angle_offset = 0;

		//! independent sprite scale multiplier
		float scale_offset = 1;

		//! independent sprite offset position
		vec2 position_offset;

		/**
		 * \brief gives the user the option to render this in world space or in camera space
		 *
		 * - if true will this be rendered in world space this means that the sprite can be
		 *   rendered off the screen 
		 * - if false --> will the sprite be rendered in camera space. this means that the
		 *   coordinates given on the \c Sprite and \c Transform will be inside the camera 
		 */
		bool world_space = true;
	};

public:
	/**
	 * \param game_id Unique identifier for the game object this sprite belongs to.
	 * \param texture asset of the image
	 * \param ctx all the sprite data
	 */
	Sprite(game_object_id_t id, const Asset & texture, const Data & data);
	~Sprite();

	//! Texture used for the sprite
	const Asset source;

	Data data;

private:
	//! Reads the mask of sprite
	friend class SDLContext;

	//! Reads the all the variables plus the  mask
	friend class Animator;

	//! Reads the all the variables plus the  mask
	friend class AnimatorSystem;

	/**
	 * \aspect_ratio the ratio of the sprite image
	 *
	 * - this value will only be set by the \c Animator component for the ratio of the Animation
	 * - if \c Animator component is not added it will not use this ratio (because 0) and will use aspect_ratio of the Asset.
	 */
	float aspect_ratio = 0;

	struct Rect {
		int w = 0;
		int h = 0;
		int x = 0;
		int y = 0;
	};
	//! Render area of the sprite this will also be adjusted by the AnimatorSystem if an Animator
	// object is present in GameObject. this is in sprite pixels
	Rect mask;

protected:
	virtual std::unique_ptr<Component> save() const;
	Sprite(const Sprite &) = default;
	virtual void restore(const Component & snapshot);
	virtual Sprite & operator=(const Sprite &);
};

} // namespace crepe