Friday 15 July 2011

python - Frame-independent movement issue in PyGame with Rect class -



python - Frame-independent movement issue in PyGame with Rect class -

i'm writing simple game pygame, , i've run problem getting things moving properly. i'm not experienced game programming, i'm not sure if approach correct..

i have class ball, extends pygame's sprite class. each frame, ball object supposed move around screen. i'm using frame-independent(?)/time-based motion time delta returned pygame's clock object each time around. such as,

class ball(pygame.sprite.sprite): # . . . def update(self, delta): self.rect.x += delta * self.speed # speed pixels per sec self.rect.y += delta * self.speed # ... or supposed be, anyway

... , ...

class game(object): # . . . def play(self): self.clock = pygame.time.clock() while not self.done: delta = self.clock.tick(self.fps) / 1000.0 # time seconds self.ball.update(delta)

pygame's sprite class backed rect object (rect) tracks sprite's position. , rect's coordinates automatically converted integers whenever value updated. so, problem each time update() called, fraction-of-a-pixel motion lost, instead of beingness accumulated on time should. speed in "pixels per second" isn't accurate way. worse, if amount of motion per frame less 1 pixel, ball doesn't move @ frames, because it's rounded downwards zero. (i.e., no motion if pps < fps)

i'm not sure how deal this. tried adding separate x , y values ball aren't forced integers , updating rect every time change. way x , y values accumulate fractions of pixel normal. in,

class ball(pygame.sprite.sprite): # . . . def update(self, delta): self.x += delta * self.speed self.y += delta * self.speed def getx(self): homecoming self._x def setx(self, val): self._x = val # can float self.rect.x = val # converted int def gety(self): homecoming self._y def sety(self, val): self._y = val # can float self.rect.y = val # converted int x = property(getx,setx) y = property(gety,sety)

but ends beingness messy: it's easy update rect object when x , y change, not other way around. not mention rect object has lots of other useful coordinates can manipulated (like centerx, top, bottomleft, etc. -- why 1 still want move rect directly). i'd more or less end having re-implement whole rect class in ball, store floats before passes them downwards rect object, or else based on x , y, sacrificing of convenience of rect class either way.

is there smarter way handle this?

i don't know if still need answer, figured out bit ago , thought i'd give question reply since came across in trying figure out going on. (thanks helping me confirm issue, way.)

you can create utilize of python's round function. pretty much, throw want function, , it'll spit out rounded number.

the first way got working this:

x = box['rect'].x if leftdown: x -= 300 * deltatime if rightdown: x += 300 * deltatime box['rect'].x = round(x)

(where deltatime float, beingness fraction of second.)

as long you're putting float value through round function before applying it, should trick. doesn't have utilize separate variables or anything.

it may worth noting cannot draw in fractions of pixel. ever. if you're familiar lite-brite, pixels work in way, beingness single lit light. that's why number utilize in end has integer.

python pygame

No comments:

Post a Comment