How do I Convert Rect2 to int Instead of float?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By davidpgil
:warning: Old Version Published before Godot 3 was released.

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.

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.

Akien | 2017-10-26 08:22

:bust_in_silhouette: Reply From: Akien

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.

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:

Any ideas?

davidpgil | 2017-10-26 10:03

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.

Akien | 2017-10-26 10:42

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 :slight_smile:

I’m noticing in the UI the numbers still seem to be floats. Is that normal?

davidpgil | 2017-10-26 14:01