+1 vote

I have a Rect2 that I am animating and I want to limit the animation to only whole pixel accurate increments. How do I do this?

I have tried doing this with get_rect_region() and set_rect_region() with no luck. Any hints would be helpful. I know the answer must be simple, but I am in the middle of figuring it out and could use all the help I can get.

Thank you in advance for your assistance.

in Engine by (88 points)
recategorized by

Note: I edited the post to use `some_text` for inline code formatting, looks much better than without it otherwise _ characters are interpreted as italic delimiters in Markdown.

1 Answer

+1 vote
Best answer

Rect2 (reference) is composed of two properties, pos (position in 3.0+) and size which of the Vector2 type (reference).

Vector2 is indeed composed of two floats, so to get it snapped to integer values, you can use for example Vector2.floor() (reference) which will give you the integral part of the components.

So this might give you want you need:

var my_rect = Rect2(Vector2(10.3, -52.9), Vector2(10.0, 23.4))
my_rect.pos = my_rect.pos.floor()
my_rect.size = my_rect.size.floor()
print(my_rect)    # should be ((10.0, -52.0), (10.0, 23.0))

(pseudo code, untested)

What's in the Rect2/Vector2s is still floats, but without decimal points; if you then need integers to make calculations, you can cast to int with the int() function, e.g. int(my_rect.size.y) # should be 23.

by (1,903 points)
selected by

Thank you. I think this is working but my implementation has problems. Please have a look at the code that is attached to the Sprite I want to limit:

extends Sprite

# get position of the sprite
onready var node = get_node(".")
onready var my_rect = node.get_region_rect()

# enable every frame processing
func _ready():
    set_fixed_process(true)
    my_rect.pos = my_rect.pos.floor()
    self.set_region_rect(my_rect)

func _fixed_process(delta):
    print(node.get_region_rect())

Here is the output:
Output of Above Code

Any ideas?

You would have to to it in every frame of _fixed_process:

my_rect = get_region_rect()
my_rect.pos = my_rect.pos.floor()
set_region_rect(my_rect)

But actually, I wonder if enabling 2D pixel snapping might not do exactly what you need, see this blog post for tips: Godot Engine and pixel art: A better love story than Twilight.

Thank you! That did it.

You see, I want a pixel-perfect retro look. I have a background in the game industry from the GameBoy, GameBoy Advance and Nintendo DS days. I want to recreate the look and feel of those consoles.

On those consoles floats weren't used because they are expensive for their processors to calculate. I think removing floats from transformations will create a subtle visual effects of a more jagged look, which is what I am aiming for. I am removing all smoothness from my project :)

I'm noticing in the UI the numbers still seem to be floats. Is that normal?
enter image description here

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.