Motonari
Motonari

Reputation: 73

Fill surface with outline in pygame

Desired outcome:

Actual outcome:

Question: How do I achieve my desired outcome?

My code:

import pygame
import random
from os import path
WIDTH = 480
HEIGHT = 720
FPS = 30
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
LIGHTGREY = (220, 220, 220)
pygame.init()
pygame.mixer.init()
pygame.display.set_caption("tests")
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

def fill_woutline(surface, fill_color, outline_color, rect, border=1):
    surface.fill(outline_color, rect)
    surface.fill(fill_color, rect.inflate(-border, -border))

class Bar(pygame.sprite.Sprite):
    def __init__(self, centerx, y, width, height, fill_color, outline_color, border=1):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((width, height))
        self.rect = self.image.get_rect()
        self.rect.centerx = centerx
        self.rect.y = y
        fill_woutline(self.image, fill_color, outline_color, self.rect, border)

all_bars = pygame.sprite.Group()
toolbar = Bar(25, 0, 50, 360, LIGHTGREY, BLACK, 2)
toolbar2 = Bar(100, 0, 50, 360, LIGHTGREY, BLACK, 2)
all_bars.add(toolbar, toolbar2)

while True:
    clock.tick(FPS)
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()
    screen.fill(WHITE)
    all_bars.draw(screen)
    pygame.display.flip()

Upvotes: 4

Views: 2409

Answers (1)

skrx
skrx

Reputation: 20438

The second argument of the fill method specifies the area of the surface that should be filled. If you blit/draw something on a surface then the topleft coords will always be (0, 0) independent of the surface's position on the screen. So because you pass the rects with the world coords, you never draw anything on the second bar (the surface is filled with black by default).

To fix the fill_woutline function, you can just generate a new rect and deflate it.

def fill_woutline(surface, fill_color, outline_color, border=1):
    surface.fill(outline_color)
    surface.fill(fill_color, surface.get_rect().inflate(-border, -border))

Upvotes: 2

Related Questions