Граничные блоки в Pygame - PullRequest
       4

Граничные блоки в Pygame

0 голосов
/ 03 января 2019

Я пытаюсь сделать несколько простых блоков с черной рамкой в ​​Pygame.Я сделал так, чтобы создать прямоугольник, а затем заполнить его дважды, один раз цветом контура (черный), а затем снова фактическим цветом блока (но используя rect.inflate ()), чтобы заполнить только подмножествоблок, тем самым создавая границу.Моя проблема заключается в следующем: когда я делаю только один блок, это работает как шарм.Однако, если сделать больше подряд, первый блок будет сделан правильно, а дополнительные блоки будут просто черными, чего я не понимаю.Мой MWE для создания этой проблемы приведен ниже:

import pygame

class Block(pygame.sprite.Sprite):
    def __init__(self, area, pos):
        super().__init__()
        self.area = area
        self.pos = pos
        self.image = pygame.Surface(self.area)
        self.rect = self.image.get_rect(topleft = self.pos)

def draw_brick(brick, outline_color, fill_color):
    # Fill with the outline color
    brick.image.fill(outline_color, brick.rect)
    # Fill with the actual block color
    brick.image.fill(fill_color, brick.rect.inflate(-10, -10))
    return brick.image

def get_brick(area, pos, outline_color, fill_color):
    # Create brick object
    b = Block(area, pos)
    # Draw the object
    b.image = draw_brick(b, outline_color, fill_color)
    return b


# Initialize
pygame.init()

# Set up screen
screen = pygame.display.set_mode((960, 540))

# Colors
white = [255,255,255]
black = [0,0,0]
red = [255,0,0]

# Clock
clock = pygame.time.Clock()

# Make bricks
nbricks = 2
length = int(960. / nbricks)
width = 54
area = (length, width)
y = 0
bricks = []
for i in range(nbricks):
    x = i * (length + 1)
    pos = (x, y)
    bricks.append(get_brick(area, pos, black, red))

# Main loop
running = True

while running:
    # Check for events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    # Draw to screen
    screen.fill(white)
    for b in bricks:
        screen.blit(b.image, (b.rect.x, b.rect.y))
    pygame.display.flip()
    clock.tick(60)

# Clean up
pygame.quit()

Я попытался пройти через pdb и проверил, что атрибуты topleft, topright, bottomleft, bottomright и center у каждого прямоугольника блока (и завышенныеправы) верны.Блоки нарисованы в правильном месте, но цвет второго полностью черный, а не красный с черной рамкой, как у первого блока, что меня смущает.Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 января 2019

GeeTransit уже говорил вам, что не так с вашим кодом (в основном смешивая относительные и абсолютные координаты), но я думаю, что ваш код слишком сложен.

Это можно упростить до этого.

import pygame

class Block(pygame.sprite.Sprite):
    def __init__(self, rect, outline_color, fill_color):
        super().__init__()
        self.image = pygame.Surface(rect.size)
        self.image.fill(outline_color)
        self.image.fill(fill_color, self.image.get_rect().inflate(-10, -10))
        self.rect = rect

pygame.init()
screen = pygame.display.set_mode((960, 540))

# Colors
white = [255,255,255]
black = [0,0,0]
red = [255,0,0]

clock = pygame.time.Clock()

nbricks = 2
length = int(960. / nbricks)
height = 54

y = 0
bricks = pygame.sprite.Group()
for i in range(nbricks):
    x = i * (length + 1)
    bricks.add(Block(pygame.Rect(x, y, length, height), black, red))

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill(white)
    bricks.draw(screen)
    pygame.display.flip()
    clock.tick(60)

Теперь у нас есть две функции и куча переменных меньше, класс Block является автономным (он умеет самостоятельно рисовать Surface) и использует Group (вместо списка) для рисования помогает содержать основной цикл в чистоте.

0 голосов
/ 03 января 2019

Я понял, что случилось.В вашем коде:

self.rect = self.image.get_rect(topleft = self.pos)

Этот self.rect получает размер изображения и его положение, которое должно обрабатываться с помощью self.pos.

. Следующий код использует это, чтобы сделать его центр цветным.

def draw_brick(brick, outline_color, fill_color):
    # Fill with the outline color
    brick.image.fill(outline_color, brick.rect)
    # Fill with the actual block color
    brick.image.fill(fill_color, brick.rect.inflate(-10, -10))
    return brick.image

brick.rect возвращается туда, где он должен заполнить цвет.brick.rect неправильно помещает цвет в неправильном месте.

Попробуйте вместо этого:

import pygame

class Block(pygame.sprite.Sprite):
    def __init__(self, area, pos):
        super().__init__()
        self.area = area
        self.pos = pos
        self.image = pygame.Surface(self.area)
        self.rect = self.image.get_rect()  # note the removed 'topleft = self.pos'

def draw_brick(brick, outline_color, fill_color):
    # Fill with the outline color
    brick.image.fill(outline_color, brick.rect)
    # Fill with the actual block color
    brick.image.fill(fill_color, brick.rect.inflate(-10, -10))
    return brick.image

def get_brick(area, pos, outline_color, fill_color):
    # Create brick object
    b = Block(area, pos)
    # Draw the object
    b.image = draw_brick(b, outline_color, fill_color)
    return b


# Initialize
pygame.init()

# Set up screen
screen = pygame.display.set_mode((960, 540))

# Colors
white = [255,255,255]
black = [0,0,0]
red = [255,0,0]

# Clock
clock = pygame.time.Clock()

# Make bricks
nbricks = 2
length = int(960. / nbricks)
width = 54
area = (length, width)
y = 0
bricks = []
for i in range(nbricks):
    x = i * (length + 1)
    pos = (x, y)
    bricks.append(get_brick(area, pos, black, red))

# Main loop
running = True

while running:
    # Check for events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    # Draw to screen
    screen.fill(white)
    for b in bricks:
        screen.blit(b.image, b.pos)        # note it uses b.pos instead of b.rect
    pygame.display.flip()
    clock.tick(60)

# Clean up
pygame.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...