Pygame – center text in moving rect

Question:

i’m making a drop the number game in pygame and have squares which will fall from the top of the screen to the bottom whilst having a numeric value and that number being displayed on each square. I am struggling to get the text centered on the square and it is made more difficult when each number can have 1 – 4 digits in them

class sqr:
    def __init__(self):
        self.colours = [(255,0,0), (0,255,0), (0,0,255)]
        self.Xpositions = [0,125,245,365,485]
        self.OnScreen = False
        self.X = random.choice(self.Xpositions) 
        self.Y = 0
        self.colour = random.choice(self.colours)
        self.number = random.choice([20,40,80])
        self.numberFont =  pygame.font.Font("TitilliumWeb-Black.ttf", 48)

    def drawSquare(self, colour,  X, Y):
        pygame.draw.rect(screen, colour, (X, Y, 120, 120))

    def numberTextFunc(self, X, Y):
        numberText = self.numberFont.render(f"{self.number}", True, (87, 63, 63))
        screen.blit(numberText, (X , Y))

square = sqr()

gameRunning = True
while gameRunning:

    background = screen.fill((0,100,140))
    
    #draw lines for grid
    for i in range(5):
        pygame.draw.rect(screen, (0,0,0), (line[i], 0 , 5, 800))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameRunning = False

    #square
    square.drawSquare(square.colour, square.X, square.Y)
    square.numberTextFunc(square.X, square.Y)
    square.OnScreen = True

    square.Y += 1

    if square.Y >= 680:
        square.Y = 680

    pygame.display.update()
Asked By: logan9997

||

Answers:

Use pygame.Surface.get_rect to get the text rectangle. pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0). Set the center of the text rectangle by the center of the square. Use the text reectnagle to blit the text. The second argument of blit is either a tuple (x, y) or a rectangle. With a rectangle, only the upper left corner of the rectangle is taken into account. Therefore you can pass the text rectangle directly to blit:

class sqr:
    # [...]

    def numberTextFunc(self, X, Y):
        numberText = self.numberFont.render(f"{self.number}", True, (87, 63, 63))
        rect = pygame.Rect(X, Y, 120, 120)
        textRect = numberText.get_rect(center = rect.center)
        screen.blit(numberText, textRect)

You can simplify your code. X and Y are attributes of the object. Hence there is no need to pass the coordinates to the methods:

class sqr:
    def __init__(self):
        self.colours = [(255,0,0), (0,255,0), (0,0,255)]
        self.Xpositions = [0,125,245,365,485]
        self.OnScreen = False
        self.X = random.choice(self.Xpositions) 
        self.Y = 0
        self.colour = random.choice(self.colours)
        self.number = random.choice([20,40,80])
        self.numberFont =  pygame.font.Font("TitilliumWeb-Black.ttf", 48)

    def drawSquare(self, colour):
        pygame.draw.rect(screen, colour, (self.X, self.Y, 120, 120))

    def numberTextFunc(self):
        numberText = self.numberFont.render(f"{self.number}", True, (87, 63, 63))
        rect = pygame.Rect(self.X, self.Y, 120, 120)
        textRect = numberText.get_rect(center = rect.center)
        screen.blit(numberText, textRect)
gameRunning = True
while gameRunning:

    background = screen.fill((0,100,140))

    #draw lines for grid
    for i in range(5):
        pygame.draw.rect(screen, (0,0,0), (line[i], 0 , 5, 800))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameRunning = False

    #square
    square.drawSquare(square.colour)
    square.numberTextFunc()
    square.OnScreen = True

    square.Y += 1
    if square.Y >= 680:
        square.Y = 680

    pygame.display.update()
Answered By: Rabbid76
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.