Skip to content

Commit 6dbae30

Browse files
committed
Add tile_animation_mode option:
- to tile animation properties - when "Default" each animation starts at time 0. - when "Random Start Times" each animation starts at random time.
1 parent 543750a commit 6dbae30

File tree

6 files changed

+98
-4
lines changed

6 files changed

+98
-4
lines changed

doc/classes/TileSetAtlasSource.xml

+26
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@
8080
Returns how many animation frames has the tile at coordinates [param atlas_coords].
8181
</description>
8282
</method>
83+
<method name="get_tile_animation_mode" qualifiers="const">
84+
<return type="int" enum="TileSetAtlasSource.TileAnimationMode" />
85+
<param index="0" name="atlas_coords" type="Vector2i" />
86+
<description>
87+
Returns the [enum TileAnimationMode] of the tile at [param atlas_coords]. See also [method set_tile_animation_mode].
88+
</description>
89+
</method>
8390
<method name="get_tile_animation_separation" qualifiers="const">
8491
<return type="Vector2i" />
8592
<param index="0" name="atlas_coords" type="Vector2i" />
@@ -215,6 +222,14 @@
215222
Sets how many animation frames the tile at coordinates [param atlas_coords] has.
216223
</description>
217224
</method>
225+
<method name="set_tile_animation_mode">
226+
<return type="void" />
227+
<param index="0" name="atlas_coords" type="Vector2i" />
228+
<param index="1" name="mode" type="int" enum="TileSetAtlasSource.TileAnimationMode" />
229+
<description>
230+
Sets the [enum TileAnimationMode] of the tile at [param atlas_coords] to [param mode]. See also [method get_tile_animation_mode].
231+
</description>
232+
</method>
218233
<method name="set_tile_animation_separation">
219234
<return type="void" />
220235
<param index="0" name="atlas_coords" type="Vector2i" />
@@ -250,4 +265,15 @@
250265
Disabling this setting might lead a small performance improvement, as generating the internal texture requires both memory and processing time when the TileSetAtlasSource resource is modified.
251266
</member>
252267
</members>
268+
<constants>
269+
<constant name="TILE_ANIMATION_MODE_DEFAULT" value="0" enum="TileAnimationMode">
270+
Tile animations start at same time, looking identical.
271+
</constant>
272+
<constant name="TILE_ANIMATION_MODE_RANDOM_START_TIMES" value="1" enum="TileAnimationMode">
273+
Tile animations start at random times, looking varied.
274+
</constant>
275+
<constant name="TILE_ANIMATION_MODE_MAX" value="2" enum="TileAnimationMode">
276+
Represents the size of the [enum TileAnimationMode] enum.
277+
</constant>
278+
</constants>
253279
</class>

editor/plugins/tiles/tile_set_atlas_source_editor.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,12 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_set(const StringName &p_na
246246
}
247247
emit_signal(SNAME("changed"), "animation_speed");
248248
return true;
249+
} else if (p_name == "animation_mode") {
250+
for (TileSelection tile : tiles) {
251+
tile_set_atlas_source->set_tile_animation_mode(tile.tile, VariantCaster<TileSetAtlasSource::TileAnimationMode>::cast(p_value));
252+
}
253+
emit_signal(SNAME("changed"), "animation_mode");
254+
return true;
249255
} else if (p_name == "animation_frames_count") {
250256
for (TileSelection tile : tiles) {
251257
int frame_count = p_value;
@@ -349,6 +355,9 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_get(const StringName &p_na
349355
} else if (p_name == "animation_speed") {
350356
r_ret = tile_set_atlas_source->get_tile_animation_speed(coords);
351357
return true;
358+
} else if (p_name == "animation_mode") {
359+
r_ret = tile_set_atlas_source->get_tile_animation_mode(coords);
360+
return true;
352361
} else if (p_name == "animation_frames_count") {
353362
r_ret = tile_set_atlas_source->get_tile_animation_frames_count(coords);
354363
return true;
@@ -417,6 +426,7 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<Pro
417426
p_list->push_back(PropertyInfo(Variant::INT, PNAME("animation_columns")));
418427
p_list->push_back(PropertyInfo(Variant::VECTOR2I, PNAME("animation_separation")));
419428
p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("animation_speed")));
429+
p_list->push_back(PropertyInfo(Variant::INT, PNAME("animation_mode"), PROPERTY_HINT_ENUM, "Default,Random Start Times"));
420430
p_list->push_back(PropertyInfo(Variant::INT, PNAME("animation_frames_count"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Frames,animation_frame_"));
421431
// Not optimal, but returns value for the first tile. This is similar to what MultiNodeEdit does.
422432
if (tile_set_atlas_source->get_tile_animation_frames_count(tiles.front()->get().tile) == 1) {

scene/2d/tile_map.cpp

+16-3
Original file line numberDiff line numberDiff line change
@@ -1317,8 +1317,21 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
13171317
ci = prev_ci;
13181318
}
13191319

1320+
Vector2 p_position = E_cell.key - tile_position;
1321+
Vector2 p_atlas_coords = c.get_atlas_coords();
1322+
1323+
// Random animation offset.
1324+
real_t p_random_animation_offset = 0.0;
1325+
if (atlas_source->get_tile_animation_mode(p_atlas_coords) != TileSetAtlasSource::TILE_ANIMATION_MODE_DEFAULT) {
1326+
Array to_hash;
1327+
to_hash.push_back(p_position);
1328+
to_hash.push_back(q.layer);
1329+
to_hash.push_back(Variant(this));
1330+
p_random_animation_offset = RandomPCG(to_hash.hash()).randf();
1331+
}
1332+
13201333
// Drawing the tile in the canvas item.
1321-
draw_tile(ci, E_cell.key - tile_position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, get_self_modulate(), tile_data);
1334+
draw_tile(ci, p_position, tile_set, c.source_id, p_atlas_coords, c.alternative_tile, -1, get_self_modulate(), tile_data, p_random_animation_offset);
13221335

13231336
// --- Occluders ---
13241337
for (int i = 0; i < tile_set->get_occlusion_layers_count(); i++) {
@@ -1436,7 +1449,7 @@ void TileMap::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
14361449
}
14371450
}
14381451

1439-
void TileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override) {
1452+
void TileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_animation_offset) {
14401453
ERR_FAIL_COND(!p_tile_set.is_valid());
14411454
ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id));
14421455
ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords));
@@ -1504,7 +1517,7 @@ void TileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<
15041517
real_t time = 0.0;
15051518
for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) {
15061519
real_t frame_duration = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame) / speed;
1507-
RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, time, time + frame_duration, 0.0);
1520+
RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, time, time + frame_duration, p_animation_offset);
15081521

15091522
Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame);
15101523
tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());

scene/2d/tile_map.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ class TileMap : public Node2D {
313313
void set_quadrant_size(int p_size);
314314
int get_quadrant_size() const;
315315

316-
static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr);
316+
static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_animation_offset = 0.0);
317317

318318
// Layers management.
319319
int get_layers_count() const;

scene/resources/tile_set.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -3923,6 +3923,9 @@ bool TileSetAtlasSource::_set(const StringName &p_name, const Variant &p_value)
39233923
} else if (components[1] == "animation_speed") {
39243924
set_tile_animation_speed(coords, p_value);
39253925
return true;
3926+
} else if (components[1] == "animation_mode") {
3927+
set_tile_animation_mode(coords, VariantCaster<TileSetAtlasSource::TileAnimationMode>::cast(p_value));
3928+
return true;
39263929
} else if (components[1] == "animation_frames_count") {
39273930
set_tile_animation_frames_count(coords, p_value);
39283931
return true;
@@ -3990,6 +3993,9 @@ bool TileSetAtlasSource::_get(const StringName &p_name, Variant &r_ret) const {
39903993
} else if (components[1] == "animation_speed") {
39913994
r_ret = get_tile_animation_speed(coords);
39923995
return true;
3996+
} else if (components[1] == "animation_mode") {
3997+
r_ret = get_tile_animation_mode(coords);
3998+
return true;
39933999
} else if (components[1] == "animation_frames_count") {
39944000
r_ret = get_tile_animation_frames_count(coords);
39954001
return true;
@@ -4065,6 +4071,13 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const {
40654071
}
40664072
tile_property_list.push_back(property_info);
40674073

4074+
// animation_mode.
4075+
property_info = PropertyInfo(Variant::INT, "animation_mode", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR);
4076+
if (E_tile.value.animation_mode == TILE_ANIMATION_MODE_DEFAULT) {
4077+
property_info.usage ^= PROPERTY_USAGE_STORAGE;
4078+
}
4079+
tile_property_list.push_back(property_info);
4080+
40684081
// animation_frames_count.
40694082
tile_property_list.push_back(PropertyInfo(Variant::INT, "animation_frames_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE));
40704083

@@ -4227,6 +4240,20 @@ real_t TileSetAtlasSource::get_tile_animation_speed(const Vector2i p_atlas_coord
42274240
return tiles[p_atlas_coords].animation_speed;
42284241
}
42294242

4243+
void TileSetAtlasSource::set_tile_animation_mode(const Vector2i p_atlas_coords, TileSetAtlasSource::TileAnimationMode p_mode) {
4244+
ERR_FAIL_COND_MSG(!tiles.has(p_atlas_coords), vformat("TileSetAtlasSource has no tile at %s.", Vector2i(p_atlas_coords)));
4245+
4246+
tiles[p_atlas_coords].animation_mode = p_mode;
4247+
4248+
emit_signal(SNAME("changed"));
4249+
}
4250+
4251+
TileSetAtlasSource::TileAnimationMode TileSetAtlasSource::get_tile_animation_mode(const Vector2i p_atlas_coords) const {
4252+
ERR_FAIL_COND_V_MSG(!tiles.has(p_atlas_coords), TILE_ANIMATION_MODE_DEFAULT, vformat("TileSetAtlasSource has no tile at %s.", Vector2i(p_atlas_coords)));
4253+
4254+
return tiles[p_atlas_coords].animation_mode;
4255+
}
4256+
42304257
void TileSetAtlasSource::set_tile_animation_frames_count(const Vector2i p_atlas_coords, int p_frames_count) {
42314258
ERR_FAIL_COND_MSG(!tiles.has(p_atlas_coords), vformat("TileSetAtlasSource has no tile at %s.", Vector2i(p_atlas_coords)));
42324259
ERR_FAIL_COND(p_frames_count < 1);
@@ -4552,6 +4579,8 @@ void TileSetAtlasSource::_bind_methods() {
45524579
ClassDB::bind_method(D_METHOD("get_tile_animation_separation", "atlas_coords"), &TileSetAtlasSource::get_tile_animation_separation);
45534580
ClassDB::bind_method(D_METHOD("set_tile_animation_speed", "atlas_coords", "speed"), &TileSetAtlasSource::set_tile_animation_speed);
45544581
ClassDB::bind_method(D_METHOD("get_tile_animation_speed", "atlas_coords"), &TileSetAtlasSource::get_tile_animation_speed);
4582+
ClassDB::bind_method(D_METHOD("set_tile_animation_mode", "atlas_coords", "mode"), &TileSetAtlasSource::set_tile_animation_mode);
4583+
ClassDB::bind_method(D_METHOD("get_tile_animation_mode", "atlas_coords"), &TileSetAtlasSource::get_tile_animation_mode);
45554584
ClassDB::bind_method(D_METHOD("set_tile_animation_frames_count", "atlas_coords", "frames_count"), &TileSetAtlasSource::set_tile_animation_frames_count);
45564585
ClassDB::bind_method(D_METHOD("get_tile_animation_frames_count", "atlas_coords"), &TileSetAtlasSource::get_tile_animation_frames_count);
45574586
ClassDB::bind_method(D_METHOD("set_tile_animation_frame_duration", "atlas_coords", "frame_index", "duration"), &TileSetAtlasSource::set_tile_animation_frame_duration);
@@ -4574,6 +4603,10 @@ void TileSetAtlasSource::_bind_methods() {
45744603
ClassDB::bind_method(D_METHOD("_update_padded_texture"), &TileSetAtlasSource::_update_padded_texture);
45754604
ClassDB::bind_method(D_METHOD("get_runtime_texture"), &TileSetAtlasSource::get_runtime_texture);
45764605
ClassDB::bind_method(D_METHOD("get_runtime_tile_texture_region", "atlas_coords", "frame"), &TileSetAtlasSource::get_runtime_tile_texture_region);
4606+
4607+
BIND_ENUM_CONSTANT(TILE_ANIMATION_MODE_DEFAULT)
4608+
BIND_ENUM_CONSTANT(TILE_ANIMATION_MODE_RANDOM_START_TIMES)
4609+
BIND_ENUM_CONSTANT(TILE_ANIMATION_MODE_MAX)
45774610
}
45784611

45794612
TileSetAtlasSource::~TileSetAtlasSource() {

scene/resources/tile_set.h

+12
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,13 @@ class TileSetSource : public Resource {
590590
class TileSetAtlasSource : public TileSetSource {
591591
GDCLASS(TileSetAtlasSource, TileSetSource);
592592

593+
public:
594+
enum TileAnimationMode {
595+
TILE_ANIMATION_MODE_DEFAULT,
596+
TILE_ANIMATION_MODE_RANDOM_START_TIMES,
597+
TILE_ANIMATION_MODE_MAX,
598+
};
599+
593600
private:
594601
struct TileAlternativesData {
595602
Vector2i size_in_atlas = Vector2i(1, 1);
@@ -599,6 +606,7 @@ class TileSetAtlasSource : public TileSetSource {
599606
int animation_columns = 0;
600607
Vector2i animation_separation;
601608
real_t animation_speed = 1.0;
609+
TileSetAtlasSource::TileAnimationMode animation_mode = TILE_ANIMATION_MODE_DEFAULT;
602610
LocalVector<real_t> animation_frames_durations;
603611

604612
// Alternatives
@@ -699,6 +707,8 @@ class TileSetAtlasSource : public TileSetSource {
699707
Vector2i get_tile_animation_separation(const Vector2i p_atlas_coords) const;
700708
void set_tile_animation_speed(const Vector2i p_atlas_coords, real_t p_speed);
701709
real_t get_tile_animation_speed(const Vector2i p_atlas_coords) const;
710+
void set_tile_animation_mode(const Vector2i p_atlas_coords, const TileSetAtlasSource::TileAnimationMode p_mode);
711+
TileSetAtlasSource::TileAnimationMode get_tile_animation_mode(const Vector2i p_atlas_coords) const;
702712
void set_tile_animation_frames_count(const Vector2i p_atlas_coords, int p_frames_count);
703713
int get_tile_animation_frames_count(const Vector2i p_atlas_coords) const;
704714
void set_tile_animation_frame_duration(const Vector2i p_atlas_coords, int p_frame_index, real_t p_duration);
@@ -930,4 +940,6 @@ VARIANT_ENUM_CAST(TileSet::TileShape);
930940
VARIANT_ENUM_CAST(TileSet::TileLayout);
931941
VARIANT_ENUM_CAST(TileSet::TileOffsetAxis);
932942

943+
VARIANT_ENUM_CAST(TileSetAtlasSource::TileAnimationMode);
944+
933945
#endif // TILE_SET_H

0 commit comments

Comments
 (0)