Pygame: Как рисовать в не прямоугольной области отсечения - PullRequest
5 голосов
/ 09 мая 2011

Привет, я хотел бы установить в области отсечения прямоугольника Pygame (в данном случае это символ "P"), где строго ограничено, где рисовать другие объекты.

Есть ли вариант?

Большое спасибо

Ответы [ 2 ]

4 голосов
/ 09 мая 2011

Давайте посмотрим, правильно ли я понимаю ваш вопрос: вы хотите «перетянуть» изображение на поверхность, но сделать это через маску, которая позволила бы только определенным пикселям источника фактически оказаться на поверхности?

У меня была именно эта проблема, и сначала я подумал, что это будет возможно только через PIL. Однако после некоторого чтения и экспериментов выясняется, что это можно сделать с помощью довольно неясных «специальных флагов» Pygame. Ниже приведена функция, которая, надеюсь, делает то, что вы хотите.

def blit_mask(source, dest, destpos, mask, maskrect):
    """
    Blit an source image to the dest surface, at destpos, with a mask, using
    only the maskrect part of the mask.
    """
    tmp = source.copy()
    tmp.blit(mask, maskrect.topleft, maskrect, special_flags=pygame.BLEND_RGBA_MULT)
    dest.blit(tmp, destpos, dest.get_rect().clip(maskrect))

Маска должна быть белой там, где вы хотите, чтобы она была прозрачной, и черной в противном случае.

2 голосов
/ 11 мая 2011

А вот полный код, который блит 2 раза в тексте "Hello World!: D". Наслаждайтесь.

import pygame, sys, time
from pygame.constants import QUIT
pygame.init()

windowSurface = pygame.display.set_mode((800, 600), 0, 32)
pygame.display.set_caption('Hello World!')

WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

basicFont = pygame.font.SysFont("Times New Roman", 100)

text = basicFont.render('Hello world! :D', True, WHITE)

def blit_mask(source, dest, destpos, mask, maskrect):

        """
        Blit an source image to the dest surface, at destpos, with a mask, using
        only the maskrect part of the mask.
        """
        windowSurface.fill(WHITE)
        tmp = source.copy()

        tmp.blit(mask, destpos, maskrect, special_flags=pygame.BLEND_RGBA_MULT)  # mask 1 green


        tmp.blit(red, (destpos[0]+100,0), maskrect, special_flags=pygame.BLEND_RGBA_MULT)  # mask 2 red

        dest.blit(tmp, (0,0), dest.get_rect().clip(maskrect))

        pygame.display.update()

red = pygame.Surface((200,100))
red.fill(RED)

green = pygame.Surface((100,100),0)
green.fill(GREEN)

for a in range(700):
    blit_mask(text, windowSurface , (a,0), green, (0,0,800,600))

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
...