2010-11-25 56 views
13

Có thể hiển thị các bề mặt PyGame với alpha có thể điều khiển không? Tôi muốn lấy một bề mặt với riêng mỗi pixel alpha và hiển thị nó với mức độ mờ thay đổi mà không ảnh hưởng đến dữ liệu bề mặt và giữ nguyên trong suốt tức là các vật thể trên bề mặt sẽ giữ hình dạng của chúng. mờ.PyGame: sprites mờ với mỗi pixel alpha

Nói cách khác, tôi muốn kết hợp alpha mỗi pixel từ hình ảnh nguồn với alpha trên mỗi mặt được tính toán trong thời gian chạy.

Trả lời

4

Sau khi kiểm tra cả tài liệu PyGame và SDL, tôi kết luận rằng những gì tôi hỏi không thể thực hiện được trong PyGame khi sử dụng các chức năng chuẩn.

Tài liệu SDL tuyên bố rằng alpha mỗi pixel và alpha trên mỗi mặt không thể kết hợp với trước đây luôn được ưu tiên. Cách duy nhất để đạt được hiệu quả mà tôi muốn là bằng cách viết mã cập nhật giá trị alpha mỗi pixel của bề mặt nguồn trước blit.

4

Có thể. documentation of the Surface class giải thích cách thực hiện. Nó nắm để chỉ có hai trường hợp: Hoặc bạn thiết lập một lá cờ trong quá trình tạo đối tượng bề mặt:

s = pygame.Surface((16, 16), flags=pygame.SRCALPHA) 

Hoặc bạn đưa ra một kênh alpha vào bề mặt mà không có tiểu sử nào:

s = pygame.image.load('spam.png') 
s.convert_alpha() 

Tài liệu của mô-đun pygame.image nói rằng việc áp dụng convert_alpha là cần thiết cho PNG có độ trong suốt.

Nếu bạn muốn, bạn có thể sửa đổi giá trị alpha của mỗi pixel bằng các mô-đun vẽ và biểu đồ lướt sóng. Khi chỉ định một màu, sử dụng sau đó một bộ gồm bốn số nguyên: (đỏ, lục, lam, alpha). Tham số alpha dao động từ 0 (hoàn toàn trong suốt) đến 255 (hoàn toàn mờ đục).

import pygame 
pygame.init() 
screen = pygame.display.set_mode((320, 200)) 
screen.fill((200, 100, 200)) 
s = pygame.Surface((64, 64), flags=pygame.SRCALPHA) 
for i in range(64): 
    pygame.draw.line(s, (0, 0, 0, i*4), (0, i), (64, i)) 

screen.blit(s, (50, 30)) 
pygame.display.flip() 
+0

Ví dụ +1 luôn được chào đón. đặc biệt là khi nó hoạt động, và cho thấy những gì cần thiết: D – admalledd

+5

Vâng, điều đó giải thích cách hiển thị các bề mặt với mỗi pixel alpha (ví dụ: từ tệp PNG). Tôi đã biết điều đó rồi. Nhưng tôi tìm cách hiển thị các bề mặt đó với độ mờ có thể điều khiển mã. ví dụ. để làm cho các sprites này chuyển từ hoàn toàn trong suốt sang độ trong suốt của mỗi pixel. Một cái gì đó giống như Surface.set_alpha() nhưng không tắt tính minh bạch trên mỗi pixel đã xuất hiện trên bề mặt. Pha trộn độ trong suốt của mỗi pixel với giá trị minh bạch tổng thể. –

1

Nếu hình ảnh đầu vào của bạn bật alpha mỗi pixel, nhưng chỉ sử dụng một bit cho độ trong suốt (ví dụ: .png sprites với nền hoặc văn bản trong suốt), bạn có thể chuyển nền trong suốt sang nền colorkey-alpha khá dễ dàng, và sau đó sử dụng set_alpha() để pha trộn toàn bộ kết cấu vào bất cứ thứ gì.

Đây là một chức năng nhanh chóng và dơ bẩn helper tôi sử dụng cho fading và hiệu ứng văn bản và những thứ khác:

def convert_to_colorkey_alpha(surf, colorkey=pygame.color.Color("magenta")): 
    newsurf = surface.Surface(surf.get_size()) 
    newsurf.fill(colorkey) 
    newsurf.blit(surf, (0, 0)) 
    newsurf.set_colorkey(colorkey) 
    return newsurf 

Một vài thủ thuật khác có khả năng giải quyết vấn đề này có thể là:

  • Làm per- chỉnh sửa pixel để sửa đổi kênh alpha trước khi nhòe
  • Làm mờ bề mặt màu trắng hoặc đen trong suốt với special_flags = BLEND_RGBA_MULT hoặc BLEND_RGBA_SUB lên bề mặt nguồn của bạn.
5

Các Pygame documentation nói rằng bạn không thể kết hợp alpha bề mặt với alpha mỗi pixel, nhưng nếu bạn đang sử dụng Pygame 1.8.1 hoặc mới hơn, bạn có thể làm việc này bằng cách sử dụng tham số special_flags-.blit().

Đây là cách tôi đã làm nó:

# Load an image with per-pixel alpha 
s = pygame.image.load('spam.png') 
s.convert_alpha() 

# Simulate s.set_alpha(alpha) 
alpha_img = pygame.Surface(s.get_rect().size, pygame.SRCALPHA) 
alpha_img.fill((255, 255, 255, alpha)) 
s.blit(alpha_img, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) 

Cách làm việc này là để tạo ra một bề mặt thứ hai kích thước giống như người đầu tiên, và blit nó trên để là người đầu tiên sử dụng RGBA multiplication. Bằng cách có các thành phần R, G và B của hình ảnh thứ hai bằng 255, phép nhân sẽ không ảnh hưởng đến màu của hình ảnh, nhưng nó sẽ mở rộng kênh alpha theo hệ số alpha đã cho.

Lưu ý rằng phương pháp trên khác với cách gọi set_alpha() trong đó set_alpha() có thể được đảo ngược bằng cách gọi set_alpha(255). Nếu bạn sử dụng phương pháp trên, nó sẽ dẫn đến các điểm ảnh pixel của mỗi điểm ảnh bị thay đổi, vì vậy quá trình này không thể được đảo ngược một cách thẳng thắn.

+0

'self' phải là' s'? – Jason

+0

@ Jason: cố định, cảm ơn! – talljosh

Các vấn đề liên quan