Floating animation slowly moves object upwards Pygame

Viewed 144

I'm writing a script for an object that's supposed to hover in place, but instead, it slowly moves upwards. Heres the code:

(Init function)

self.vy = 0
self.dy = 0.1

(Update function)

 self.vy += self.dy
 if self.vy > 1 or self.vy < -1:
     self.dy *= -1
 self.imgRect.centery += self.vy
1 Answers

From the pygame.Rect doc

The coordinates for Rect objects are all integers

I investigated this and found that when you try and set a rect's coordinate (In this case centery) to a float, it takes the closest integer below the float and uses that.

I whipped up this little test to see it in action:

import pygame
pygame.init()
window = pygame.display.set_mode((500,500), pygame.SCALED)

rect = pygame.Rect(250,250,50,50)

dy = 0.1
vy = 0
intended_centery = 275
while True:
    pygame.time.delay(1000)

    vy+= dy
    if vy > 1 or vy < -1:
        dy *= -1
    rect.centery+= vy
    intended_centery += vy
    print("\nWhat you want:{}\nWhat you get: {}".format(intended_centery,rect.centery))

And the output shows that yes, the intended_centery is working like what you want, but the rect.centery only continues to decreases (so moves up)

The reason this is happening is, since the Rect takes the integer below the float when you pass a float, when you are trying to increase the centery (move down) it continually takes the int below vy. Until vy >= 1, the rect.centery += vy will be adding 0, since 0.1 - 0.9's int below is 0. So nothing useful will happen.

BUT when you are moving it back up, once vy < 0 (-0.1 to -0.9), it will take the int below the float... which will be -1!


So the result is that you effectively only continue to move up and don't move back down to get the hover motion you want

The reason that Rect.centery rounds floats like this is because it is using "_ int _" to convert floats to ints. And when you run the test I made it even prints a DeprecationWarning for this. This is the exact thing causing your problem


As far as I can tell there is no way to get the exact desired effect.

However you could use Python's builtin round() method to get close to what you want, however centery will only increase and decrease by 1's which might not work for you since I'm assuming you want that accuracy from using floats for a reason. But it will "work" as in it will move up and down equally

Anyways, hope this helped (BTW I did testing and everything in python 3)

Related