Python Forum

Full Version: Surface and rectangle in pygame
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello eveyone,

Just a stupid question:
in many tutorials found on internet to draw object on the window we use surfaces and rectangles.
first we create a surface, then with the method getrect we create a rectangle around that surface,
but when i have to move the object we move only the rectangle, what it means?
We move only the rectangle, and the surface? Remain in the original position?
There is a way to combine thi two object and move them with a command?
But first of all why we create a surfaces for a rectangles? we cant' t create a big surface with the dimension of the window and on this big surface create rectangles?

Are a lot of question, but i don' t andurstand this surface - rectangle system

sorry for the bad english Big Grin
I don't understand very well the question, but if you want to draw a rectangle on the screen you can just use this simple program
import pygame as py
screen: py.Surface = py.display.set_mode((700, 700))
running = True
color = (195, 195, 195)
py.draw.rect(screen, (color), (30, 20, 100, 200)) # draw a rect on the screen at the coordinate (30, 20) with a width of #100 and a height of 200
while running:
    for event in py.event.get():
        if event.type == py.QUIT: # allow to leave the loop
            running = False
            break
    py.display.flip()
but I think that the tutorial you saw said to do a thing like this:
import pygame as py
rectangle = py.Surface((100, 200))
color = (195, 195, 195)
rectangle.fill(color)
screen = py.display.set_mode((700, 700))
screen.blit(rectangle, (30, 20))
while running:
    for event in py.event.get():
        if event.type == py.QUIT: # allow to leave the loop
            running = False
            break
    py.display.flip()
And I think you tutorial said you to do that because I think it's less expansive to blit a surface onto another than use py.draw.rect (but i am not sure)
I think you want a Sprite.

A sprite has a surface (called image) and a rectangle (called rect). It also has a method "draw()" that draws the sprite. If your sprite class does not have a draw() method, the default draw() method draws the surface at the location of the rectangle.
"""Demonstrate how sprites work."""
import pygame

class MySprite(pygame.sprite.Sprite):
    """You create sprite classes for things on your screen that move or change."""
    def __init__(self, pos=(0, 0)):
        super().__init__()
        self.target = (150, 150)
        # Sprites must have an image and a rect.  When the sprite's draw()
        # method is called, the image is drawn at the rectangle's location.
        self.image = pygame.surface.Surface((20, 20))
        self.image.fill("red")
        self.rect = self.image.get_rect()
        self.rect.x, self.rect.y = pos

    def update(self):
        """Sprites can have an update() method that is called by the
        group the sprite belongs to.  When the update method is called,
        the sprite should update the image and/or rect to prepare for
        the draw() method."""
        dx = max(-1, min(1, self.target[0] - self.rect.x))
        dy = max(-1, min(1, self.target[1] - self.rect.y))
        if dx == 0 and dy == 0:
            self.kill()
        else:
            self.rect.x += dx
            self.rect.y += dy


def main():
    screen = pygame.display.set_mode((300, 300))
    sprites = pygame.sprite.Group()
    clock = pygame.time.Clock()
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                break
            elif event.type == pygame.MOUSEBUTTONDOWN:
                for sprite in sprites.sprites():
                    sprite.target = event.pos
                sprites.add(MySprite(event.pos))

        screen.fill("blue")
        sprites.update()  # Update all sprite positions
        sprites.draw(screen)  # Draw the sprites
        pygame.display.flip()
        clock.tick(60)


main()
I have a question, why did you use property for target, if you rename self._target to self.target and delete the 2 property that would achieve the same?
An artifact ftom a different example. I didn't notice I removed all the setter code. I modified the post to not use a property.
(May-14-2023, 01:53 PM)Fabrizio_fg Wrote: [ -> ]but when i have to move the object we move only the rectangle, what it means?
We move only the rectangle, and the surface? Remain in the original position?
There is a way to combine thi two object and move them with a command?
But first of all why we create a surfaces for a rectangles? we cant' t create a big surface with the dimension of the window and on this big surface create rectangles?
Rectangle is use to position the surface. It just uses the x and y.
Rectangle is also use for collisions.
Surface can be use over and over again. Just set a new position.
Why cant you have big surface ? You can a bigger surface than the screen.

Tip. Take it one step at a time. Add one line of code. Run it. To see how it effect program.
Thanks for the answers, i couldn't quite understand the connection between surfaces and rectangles but now it's clearer.