Активное текстурирование с помощью pygame (возможно? Какие концепции посмотреть в ?)

У меня есть два изображения:

Mask Texture

Я хотел бы по существу «вырезать» черную фигуру из мозаичного элемента текстуры, чтобы в итоге получилось что-то вроде этого:

Cutout

За исключением прозрачного вокруг формы. Возможно ли это с помощью Pygame? Этот пример мне пришлось создать в GIMP.

Кроме того, будет ли это слишком тяжелым для производительности для каждого кадра для нескольких спрайтов в среде реального времени? (30+ кадров в секунду)

6
задан agscala 27 August 2010 в 00:16
поделиться

1 ответ

Я сделал решение, но оно не самое лучшее ни по скорости, ни по красоте. Вы можете использовать двойное копирование с настройкой цветовых ключей для прозрачности. Таким образом, маска должна иметь только два цвета: черный и белый. Обратите внимание, что вы не можете использовать это для изображений с альфа-каналом на пиксель (RGBA) только для изображений RGB. Другое ограничение заключается в том, что рекомендуется, чтобы размер текстуры и изображения маски был одинаковым (в противном случае вы должны использовать области для блитинга).

Проще говоря, шаг за шагом:

  • создайте поверхность с маской. фон должен быть белым (255,255,255), маскируемые части должны быть черными (0,0,0)
  • создать или загрузить текстуру на поверхность
  • установить ключ цвета прозрачности для маски для черного цвета
  • блит маску на текстуру (или на копию текстуры). в этот момент черные части маски не сливаются с текстурой, потому что мы установили черный цвет прозрачным с помощью метода set_colorkey
  • , теперь устанавливаем цветовой ключ текстуры (или копии текстуры) на белый. помните, что наша текущая поверхность текстуры имеет белые и текстурированные части.
  • слепить текстуру на экран. белые части не будут засвечены, потому что мы сделали его прозрачным с помощью colorkey

Пример кода:

#!/usr/bin/python
# -*- coding:utf8 -*-

import pygame, sys

#init pygame
pygame.init()

#init screen
screen=pygame.display.set_mode((800,600))
screen.fill((255,0,255))

#loading the images
texture=pygame.image.load("texture.jpg").convert()
texture_rect=texture.get_rect()
texture_rect.center=(200,300)
mask=pygame.Surface((texture_rect.width,texture_rect.height)) # mask should have only 2 colors: black and white
mask.fill((255,255,255))
pygame.draw.circle(mask,(0,0,0),(texture_rect.width/2,texture_rect.height/2),int(texture_rect.width*0.3))
mask_rect=mask.get_rect()
mask_rect.center=(600,300)

tmp_image=texture.copy() # make a copy of the texture to keep it unchanged for future usage
mask.set_colorkey((0,0,0)) # we want the black colored parts of the mask to be transparent
tmp_image.blit(mask,(0,0)) # blit the mask to the texture. the black parts are transparent so we see the pixels of the texture there

tmp_rect=tmp_image.get_rect()
tmp_rect.center=(400,300)
tmp_image.set_colorkey((255,255,255))
screen.blit(texture,texture_rect)
screen.blit(mask,mask_rect)
screen.blit(tmp_image,tmp_rect)

pygame.display.flip()

while 1:
    event=pygame.event.wait()
    if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key in [pygame.K_ESCAPE, pygame.K_q]):
        sys.exit()

Я рекомендую не использовать jpg в качестве маски из-за его формата с потерями, я рекомендую bmp или png (bmp лучше). Помните, что он не использует альфу, поэтому края не будут сглажены, так что это не очень хорошее решение для 2010 года :)

Вот скриншот результата: masked blitting

Редактировать: Привет еще раз,

Я провел несколько тестов с BLEND_ADD, и результаты были многообещающими.Вот код:

import pygame, sys

#init pygame
pygame.init()

#init screen
screen=pygame.display.set_mode((800,600))
screen.fill((255,0,255))

#loading the images
texture=pygame.image.load("texture.jpg").convert_alpha()
texture_rect=texture.get_rect()
texture_rect.center=(200,300)
mask=pygame.image.load("mask2.png").convert_alpha()
mask_rect=mask.get_rect()
mask_rect.center=(600,300)

textured_mask=mask.copy()
textured_rect=textured_mask.get_rect()
textured_rect.center=400,300

textured_mask.blit(texture,(0,0),None,pygame.BLEND_ADD)

screen.blit(texture,texture_rect)
screen.blit(mask,mask_rect)
screen.blit(textured_mask,textured_rect)

pygame.display.flip()

while 1:
    event=pygame.event.wait()
    if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key in [pygame.K_ESCAPE, pygame.K_q]):
        sys.exit()

И результат: result

С помощью этого решения вы можете получить попиксельное альфа-текстурирование. Обратите внимание, что маска должна быть изображением с альфа-каналом, чтобы нельзя было использовать jpg. Лучше всего использовать png.

Изображение текстуры (texture.jpg): texture

Изображение маски (mask2.png): mask

7
ответ дан 8 December 2019 в 20:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: