Skip to content

Commit

Permalink
Fix invalid frame index when Sprite2D's hframes or vframes has been c…
Browse files Browse the repository at this point in the history
…hanged

(cherry picked from commit 484c5b5)
  • Loading branch information
miv391 authored and YuriSizov committed Jan 25, 2024
1 parent eb25ef6 commit c2d38b4
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 8 deletions.
6 changes: 3 additions & 3 deletions doc/classes/Sprite2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@
If [code]true[/code], texture is flipped vertically.
</member>
<member name="frame" type="int" setter="set_frame" getter="get_frame" default="0">
Current frame to display from sprite sheet. [member hframes] or [member vframes] must be greater than 1.
Current frame to display from sprite sheet. [member hframes] or [member vframes] must be greater than 1. This property is automatically adjusted when [member hframes] or [member vframes] are changed to keep pointing to the same visual frame (same column and row). If that's impossible, this value is reset to [code]0[/code].
</member>
<member name="frame_coords" type="Vector2i" setter="set_frame_coords" getter="get_frame_coords" default="Vector2i(0, 0)">
Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member hframes] or [member vframes] must be greater than 1.
</member>
<member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1">
The number of columns in the sprite sheet.
The number of columns in the sprite sheet. When this property is changed, [member frame] is adjusted so that the same visual frame is maintained (same row and column). If that's impossible, [member frame] is reset to [code]0[/code].
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2(0, 0)">
The texture's drawing offset.
Expand All @@ -84,7 +84,7 @@
[Texture2D] object to draw.
</member>
<member name="vframes" type="int" setter="set_vframes" getter="get_vframes" default="1">
The number of rows in the sprite sheet.
The number of rows in the sprite sheet. When this property is changed, [member frame] is adjusted so that the same visual frame is maintained (same row and column). If that's impossible, [member frame] is reset to [code]0[/code].
</member>
</members>
<signals>
Expand Down
6 changes: 3 additions & 3 deletions doc/classes/Sprite3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
</tutorials>
<members>
<member name="frame" type="int" setter="set_frame" getter="get_frame" default="0">
Current frame to display from sprite sheet. [member hframes] or [member vframes] must be greater than 1.
Current frame to display from sprite sheet. [member hframes] or [member vframes] must be greater than 1. This property is automatically adjusted when [member hframes] or [member vframes] are changed to keep pointing to the same visual frame (same column and row). If that's impossible, this value is reset to [code]0[/code].
</member>
<member name="frame_coords" type="Vector2i" setter="set_frame_coords" getter="get_frame_coords" default="Vector2i(0, 0)">
Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member hframes] or [member vframes] must be greater than 1.
</member>
<member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1">
The number of columns in the sprite sheet.
The number of columns in the sprite sheet. When this property is changed, [member frame] is adjusted so that the same visual frame is maintained (same row and column). If that's impossible, [member frame] is reset to [code]0[/code].
</member>
<member name="region_enabled" type="bool" setter="set_region_enabled" getter="is_region_enabled" default="false">
If [code]true[/code], the sprite will use [member region_rect] and display only the specified part of its texture.
Expand All @@ -28,7 +28,7 @@
[Texture2D] object to draw. If [member GeometryInstance3D.material_override] is used, this will be overridden. The size information is still used.
</member>
<member name="vframes" type="int" setter="set_vframes" getter="get_vframes" default="1">
The number of rows in the sprite sheet.
The number of rows in the sprite sheet. When this property is changed, [member frame] is adjusted so that the same visual frame is maintained (same row and column). If that's impossible, [member frame] is reset to [code]0[/code].
</member>
</members>
<signals>
Expand Down
17 changes: 17 additions & 0 deletions scene/2d/sprite_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ Vector2i Sprite2D::get_frame_coords() const {
void Sprite2D::set_vframes(int p_amount) {
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of vframes cannot be smaller than 1.");
vframes = p_amount;
if (frame >= vframes * hframes) {
frame = 0;
}
queue_redraw();
item_rect_changed();
notify_property_list_changed();
Expand All @@ -272,7 +275,21 @@ int Sprite2D::get_vframes() const {

void Sprite2D::set_hframes(int p_amount) {
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of hframes cannot be smaller than 1.");
if (vframes > 1) {
// Adjust the frame to fit new sheet dimensions.
int original_column = frame % hframes;
if (original_column >= p_amount) {
// Frame's column was dropped, reset.
frame = 0;
} else {
int original_row = frame / hframes;
frame = original_row * p_amount + original_column;
}
}
hframes = p_amount;
if (frame >= vframes * hframes) {
frame = 0;
}
queue_redraw();
item_rect_changed();
notify_property_list_changed();
Expand Down
21 changes: 19 additions & 2 deletions scene/3d/sprite_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -804,8 +804,11 @@ Vector2i Sprite3D::get_frame_coords() const {
}

void Sprite3D::set_vframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of vframes cannot be smaller than 1.");
vframes = p_amount;
if (frame >= vframes * hframes) {
frame = 0;
}
_queue_redraw();
notify_property_list_changed();
}
Expand All @@ -815,8 +818,22 @@ int Sprite3D::get_vframes() const {
}

void Sprite3D::set_hframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of hframes cannot be smaller than 1.");
if (vframes > 1) {
// Adjust the frame to fit new sheet dimensions.
int original_column = frame % hframes;
if (original_column >= p_amount) {
// Frame's column was dropped, reset.
frame = 0;
} else {
int original_row = frame / hframes;
frame = original_row * p_amount + original_column;
}
}
hframes = p_amount;
if (frame >= vframes * hframes) {
frame = 0;
}
_queue_redraw();
notify_property_list_changed();
}
Expand Down

0 comments on commit c2d38b4

Please sign in to comment.