Pythonic way to handle coordinates

The Music Guy musicguy at alphaios.net
Sat Jan 17 04:50:23 EST 2009


On Jan 17, 2:48 am, pdora... at pas-de-pub-merci.mac.com (Pierre-Alain
Dorange) wrote:
> Hi,
> I'm used python for 3 months now to develop small arcade games (with
> pygame module).
>
> I just got a question about coordinates handling.
> My games are in 2D so i deal with x,y coordinates for sprites (but woudl
> be the same u-issue in 3D).
>
> At the beginning i simply use x and y to pass to my methods
> ie : sprite.move(x,y)
> easy
>
> after looking closely to pygame code, i noticed that pygame implement a
> Rect class but no Point class, and instead require tuple for
> coordinates.
> ie : pygame.draw.line(surface,color,start,end)
> where start and end are tuple, like (x,y).
>
> I found this nice and rewrote my API to use tuples instead of 2
> variables...
> so i got could do :
>         loc=(x,y)
>         sprite.move(loc) or sprite.move((x,y))
>         ...
>         loc=sprite.get_pos()
>
> Nice, but i got a problem when my methodes return tuple, as it's
> unmutable i could not modify them and i got to used tempory variables to
> do that, not very clean :
>         loc=sprite.get_pos()
>         loc[0]+=10  < ERROR
>         ...
>         x=loc[0]+10
>         loc=(x,loc[1])
> i could also do :
>         (x,y)=sprite.get_pos()
>         x+=10
>         sprite.set_pos((x,y))
> The second method could not be used when i'm instead one of my method, i
> need to used the first one.
>
> What is the elegant way to handle coordinates ?
> Do i need to continue using tuples or do i need to write a Point class.
> I feel a point class would be nice, because i could implement operators
> with it ? But i think Point class must exist allready ?
>
> --
> Pierre-Alain Dorange
>
> Ce message est sous licence Creative Commons "by-nc-sa-2.0"
>         <http://creativecommons.org/licenses/by-nc-sa/2.0/fr/>

Hi there,

First of all, Pygame will accept any sequence of two integers (or even
floats) and not just tuples, so you don't need to implement all your
coordinates as tuples, and thus you can use lists, which are mutable.

Second of all, for this situation I do the same as the Rect object and
implement .x and .y properties for objects that need individual access
of those coordinates. Example:

>>> # WARNING: This code was written on-the-fly and has not been
tested...
>>> class MySprite(object):
>>>    def __init__(self, pos):
>>>        # This is a list, not a tuple. Pygame won't mind.
>>>        # Also, note that the type of the pos is implicitly
>>>        # type checked.
>>>        self._pos = map(int, pos[:2])
>>>
>>>    def set_x(self, x):
>>>        self._pos[0] = int(x)
>>>    x = property(lambda self: self._pos[0], set_x)
>>>
>>>    def set_y(self, y):
>>>        self._pos[1] = int(y)
>>>    y = property(lambda self: self._pos[1], set_y)
>>>
>>>    def set_pos(self, pos):
>>>        self._pos = map(int, pos[:2])
>>>    # Note that the return value is converted to tuple to prevent
>>>    # constructs like `mysprite.pos[0] = "foo"`, which would cause an
>>>    # invalid type of value to be assigned for the x coordinates.
>>>    pos = property(lambda self: tuple(self._pos), set_pos)
>>>
>>> spr = MySprite((3,4))
>>> spr.x
3
>>> spr.y
4
>>> spr.x = 8
>>> spr.pos
(8,4)

My SDK implements a lot of things like this. Check it out if you're
looking for more examples: http://code.google.com/p/scrollback

-TMG



More information about the Python-list mailing list