# Pygame surfaces and their Rects

I am trying to understand how pygame surfaces work. I am confused about Rect position of Surface object. If I try blit surface on screen at some position then Surface is drawn at right position, but Rect of the surface is still at position (0, 0)... I tried write my own surface class with new rect, but i am not sure if is that right solution. My goal is that i could move surface like image with rect.move() or something like that. If there is any solution to do that i would be happy to read it.

If helps i write some code for better understanding my problem. (run it first, and then uncomment two lines of code and run again to see the diference):

import pygame
from pygame.locals import *

class SurfaceR(pygame.Surface):
def __init__(self, size, position):
pygame.Surface.__init__(self, size)
self.rect = pygame.Rect(position, size)
self.position = position
self.size = size

def get_rect(self):
return self.rect

def main():
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Screen!?")
clock = pygame.time.Clock()
fps = 30

white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)

surface = pygame.Surface((70,200))
surface.fill(red)

surface_re = SurfaceR((300, 50), (100, 300))
surface_re.fill(blue)

while True:
for event in pygame.event.get():
if event.type == QUIT:
return 0

screen.blit(surface, (100,50))
screen.blit(surface_re, surface_re.position)

#pygame.draw.rect(screen, white, surface.get_rect())
#pygame.draw.rect(screen, white, surface_re.get_rect())

pygame.display.update()
clock.tick(fps)

if __name__ == "__main__":
main()


Per the documentation:

Surface.get_rect(**kwargs): return Rect Returns a new rectangle covering the entire surface. This rectangle will always start at 0, 0 with a width. and height the same size as the image.

You can pass keyword argument values to this function. These named values will be applied to the attributes of the Rect before it is returned. An example would be 'mysurf.get_rect(center=(100,100))' to create a rectangle for the Surface centered at a given position.

The rectangle is used to calculate collisions, if what you're looking for is movement try using blit:

Surface.blit draw one image onto another Surface.blit(source, dest, area=None, special_flags = 0): return Rect Draws a source Surface onto this Surface. The draw can be positioned with the dest argument. Dest can either be pair of coordinates representing the upper left corner of the source. A Rect can also be passed as the destination and the topleft corner of the rectangle will be used as the position for the blit. The size of the destination rectangle does not effect the blit.

Here's a nice Tutorial of movement in pygame: http://www.pygame.org/docs/tut/MoveIt.html

Surfaces don't have a position on the screen they're only an image, the get_rect() method is just to get its dimensions.

Your approach extending the Surface class it's ok but it's not pretty standard. In Pygame you have a Sprite class which is used to keep track of surfaces on the screen. In fact you should extend Sprite class to create your own objects (player, enemies, etc).

You can read more in the tutorial or in the reference.