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()
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()