1 /*************************************************************************/
2 /* parallax_background.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 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 #include "parallax_background.h"
31 #include "parallax_layer.h"
32
_notification(int p_what)33 void ParallaxBackground::_notification(int p_what) {
34
35 switch (p_what) {
36
37 case NOTIFICATION_ENTER_TREE: {
38
39 group_name = "__cameras_" + itos(get_viewport().get_id());
40 add_to_group(group_name);
41
42 } break;
43 case NOTIFICATION_EXIT_TREE: {
44
45 remove_from_group(group_name);
46 } break;
47 }
48 }
49
_camera_moved(const Matrix32 & p_transform)50 void ParallaxBackground::_camera_moved(const Matrix32 &p_transform) {
51
52 set_scroll_offset(p_transform.get_origin());
53 set_scroll_scale(p_transform.get_scale().dot(Vector2(0.5, 0.5)));
54 }
55
set_scroll_scale(float p_scale)56 void ParallaxBackground::set_scroll_scale(float p_scale) {
57
58 scale = p_scale;
59 }
60
get_scroll_scale() const61 float ParallaxBackground::get_scroll_scale() const {
62
63 return scale;
64 }
65
set_scroll_offset(const Point2 & p_ofs)66 void ParallaxBackground::set_scroll_offset(const Point2 &p_ofs) {
67
68 offset = p_ofs;
69
70 _update_scroll();
71 }
72
_update_scroll()73 void ParallaxBackground::_update_scroll() {
74
75 if (!is_inside_tree())
76 return;
77
78 Vector2 ofs = base_offset + offset * base_scale;
79
80 Size2 vps = get_viewport_size();
81
82 ofs = -ofs;
83 if (limit_begin.x < limit_end.x) {
84
85 if (ofs.x < limit_begin.x)
86 ofs.x = limit_begin.x;
87 else if (ofs.x + vps.x > limit_end.x)
88 ofs.x = limit_end.x - vps.x;
89 }
90
91 if (limit_begin.y < limit_end.y) {
92
93 if (ofs.y < limit_begin.y)
94 ofs.y = limit_begin.y;
95 else if (ofs.y + vps.y > limit_end.y)
96 ofs.y = limit_end.y - vps.y;
97 }
98 ofs = -ofs;
99
100 final_offset = ofs;
101
102 for (int i = 0; i < get_child_count(); i++) {
103
104 ParallaxLayer *l = get_child(i)->cast_to<ParallaxLayer>();
105 if (!l)
106 continue;
107
108 if (ignore_camera_zoom)
109 l->set_base_offset_and_scale(ofs, 1.0);
110 else
111 l->set_base_offset_and_scale(ofs, scale);
112 }
113 }
114
get_scroll_offset() const115 Point2 ParallaxBackground::get_scroll_offset() const {
116
117 return offset;
118 }
119
set_scroll_base_offset(const Point2 & p_ofs)120 void ParallaxBackground::set_scroll_base_offset(const Point2 &p_ofs) {
121
122 base_offset = p_ofs;
123 _update_scroll();
124 }
125
get_scroll_base_offset() const126 Point2 ParallaxBackground::get_scroll_base_offset() const {
127
128 return base_offset;
129 }
130
set_scroll_base_scale(const Point2 & p_ofs)131 void ParallaxBackground::set_scroll_base_scale(const Point2 &p_ofs) {
132
133 base_scale = p_ofs;
134 _update_scroll();
135 }
136
get_scroll_base_scale() const137 Point2 ParallaxBackground::get_scroll_base_scale() const {
138
139 return base_scale;
140 }
141
set_limit_begin(const Point2 & p_ofs)142 void ParallaxBackground::set_limit_begin(const Point2 &p_ofs) {
143
144 limit_begin = p_ofs;
145 _update_scroll();
146 }
147
get_limit_begin() const148 Point2 ParallaxBackground::get_limit_begin() const {
149
150 return limit_begin;
151 }
152
set_limit_end(const Point2 & p_ofs)153 void ParallaxBackground::set_limit_end(const Point2 &p_ofs) {
154
155 limit_end = p_ofs;
156 _update_scroll();
157 }
158
get_limit_end() const159 Point2 ParallaxBackground::get_limit_end() const {
160
161 return limit_end;
162 }
163
set_ignore_camera_zoom(bool ignore)164 void ParallaxBackground::set_ignore_camera_zoom(bool ignore) {
165
166 ignore_camera_zoom = ignore;
167 }
168
is_ignore_camera_zoom()169 bool ParallaxBackground::is_ignore_camera_zoom() {
170
171 return ignore_camera_zoom;
172 }
173
get_final_offset() const174 Vector2 ParallaxBackground::get_final_offset() const {
175
176 return final_offset;
177 }
178
_bind_methods()179 void ParallaxBackground::_bind_methods() {
180
181 ObjectTypeDB::bind_method(_MD("_camera_moved"), &ParallaxBackground::_camera_moved);
182 ObjectTypeDB::bind_method(_MD("set_scroll_offset", "ofs"), &ParallaxBackground::set_scroll_offset);
183 ObjectTypeDB::bind_method(_MD("get_scroll_offset"), &ParallaxBackground::get_scroll_offset);
184 ObjectTypeDB::bind_method(_MD("set_scroll_base_offset", "ofs"), &ParallaxBackground::set_scroll_base_offset);
185 ObjectTypeDB::bind_method(_MD("get_scroll_base_offset"), &ParallaxBackground::get_scroll_base_offset);
186 ObjectTypeDB::bind_method(_MD("set_scroll_base_scale", "scale"), &ParallaxBackground::set_scroll_base_scale);
187 ObjectTypeDB::bind_method(_MD("get_scroll_base_scale"), &ParallaxBackground::get_scroll_base_scale);
188 ObjectTypeDB::bind_method(_MD("set_limit_begin", "ofs"), &ParallaxBackground::set_limit_begin);
189 ObjectTypeDB::bind_method(_MD("get_limit_begin"), &ParallaxBackground::get_limit_begin);
190 ObjectTypeDB::bind_method(_MD("set_limit_end", "ofs"), &ParallaxBackground::set_limit_end);
191 ObjectTypeDB::bind_method(_MD("get_limit_end"), &ParallaxBackground::get_limit_end);
192 ObjectTypeDB::bind_method(_MD("set_ignore_camera_zoom", "ignore"), &ParallaxBackground::set_ignore_camera_zoom);
193 ObjectTypeDB::bind_method(_MD("is_ignore_camera_zoom"), &ParallaxBackground::is_ignore_camera_zoom);
194
195 ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll/offset"), _SCS("set_scroll_offset"), _SCS("get_scroll_offset"));
196 ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll/base_offset"), _SCS("set_scroll_base_offset"), _SCS("get_scroll_base_offset"));
197 ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll/base_scale"), _SCS("set_scroll_base_scale"), _SCS("get_scroll_base_scale"));
198 ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll/limit_begin"), _SCS("set_limit_begin"), _SCS("get_limit_begin"));
199 ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll/limit_end"), _SCS("set_limit_end"), _SCS("get_limit_end"));
200 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll/ignore_camera_zoom"), _SCS("set_ignore_camera_zoom"), _SCS("is_ignore_camera_zoom"));
201 }
202
ParallaxBackground()203 ParallaxBackground::ParallaxBackground() {
204
205 base_scale = Vector2(1, 1);
206 scale = 1.0;
207 set_layer(-1); //behind all by default
208 }
209