What is the most comprehensible way to create a Rect object from a center point and a size in PyGame?

Viewed 77

I want to crate an pygame.Rect object from a center point (xc, yc) and a size (w, h). pygame.Rect just provides a constructor with the top left point and the size.

Of course I can calculate the top left point:

rect = pygame.Rect(xc - w // 2, yc - h // 2, w, h)

Or I can set the location via the virtual attribute center:

rect = pygame.Rect(0, 0, w, h)
rect.center = xc, yc

If I want to completely confuse someone, I use inflate:

rect = pygame.Rect(xc, yc, 0, 0).inflate(w, h)

Or even clamp:

rect = pygame.Rect(0, 0, w, h).clamp((xc, yc, 0, 0))

Not any of this methods satisfies me. Either I have to calculate something, I have to write several lines of code, or I have to use a function that completely hides what is happening. I also don't want to write a function (or lambda) as I think this is completely over the top for creating a simple rectangle.

So my question is:

How do you usually create such a rectangle with a self-explanatory line of code so everyone can see what is happening at a glance? Is there a much easier method? Do I miss something?

1 Answers

Interesting question Rabbid76.

I personally try to write code such that a person with only a general understanding of programming concepts can read the code. This includes absolute beginners (95% of people making PyGame questions), and converts from other languages.

This is why I mostly shy-away from using Python's if x < y < z:, and blah = [ x for x in some-complex-iff-loop ], et.al. syntax. (And that's also why I always put my if conditions in brackets.) Sure if you know python well it doesn't matter, but for an example of why it's important, go try to read a Perl script from the mid 2010's and you see stuff like:

print @$_, "\n" foreach ( @tgs );

It didn't have to be written like that, they could have used a loop-block with some instructive variable names, and not $_, etc.

So bearing the above in mind, the question comes down to - Which is the easiest to read and understand.

So for my 2-cents worth, it has to be option #2:

rect = pygame.Rect(0, 0, w, h)
rect.center = xc, yc

It's absolutely clear to a syntax-ignorant code reader that a rectangle is being created, and some kind of centre-point is being set.

But to make the code more "self documenting", it could be wrapped in a function call:

def getRectAround( centre_point, width, height ):
    """ Return a pygame.Rect of size width by height, 
        centred around the given centre_point """
    rectangle = pygame.Rect( 0, 0, w, h )      # make new rectangle
    rectangle.center = centre_point            # centre rectangle
    return rectangle

# ...

rect = getRectAround( ( x, y ), w, h )

Sometimes more code is better.

Related