2010-08-27 10 views
6

Ho due immagini:texturing attivo con pygame (possibile ciò che i concetti di esaminare??)

Mask Texture

mi piacerebbe essenzialmente 'tagliare' la sagoma nera dalla mattonelle in modo che io alla fine con qualcosa in queste righe:

Cutout

Tranne trasparente intorno alla forma. È possibile usare pygame? Questo esempio ho dovuto creare in GIMP.

Inoltre, sarebbe troppo pesante per le prestazioni farlo per ogni fotogramma per pochi sprite in un ambiente in tempo reale? (30+ fotogrammi al secondo)

risposta

5

Ho fatto una soluzione, tuttavia non è la migliore né per la velocità né per la bellezza. È possibile utilizzare il doppio attacco con l'impostazione dei tasti di colore per la trasparenza. In questo modo la maschera dovrebbe avere solo due colori: bianco e nero. Nota che non è possibile utilizzare questo per immagini con pixel alpha (RGBA) solo per immagini RGB. Un'altra limitazione è che si raccomanda che la dimensione della trama e l'immagine della maschera sia la stessa (se non si dovessero usare le aree per il blitting).

In parole, passo dopo passo:

  • creare una superficie con la maschera. sfondo dovrebbe essere bianco (255,255,255), le parti dovrebbero essere mascherati nero (0,0,0)
  • creare o caricare la texture in una superficie
  • impostare un colorkey la trasparenza per la maschera per il colore nero
  • blit la maschera sulla trama (o su una copia della trama). a questo punto le parti nere della maschera non sono state applicate alla texture perché abbiamo impostato il colore nero su trasparente con il metodo set_colorkey
  • ora imposta il colore della texture (o della copia della texture) su bianco. ricorda che la nostra attuale superficie della texture ha parti bianche e ruvide.
  • blitare la trama sullo schermo. le parti bianche non saranno blitted causa abbiamo impostarlo trasparente con il colorkey

Esempio di codice:

#!/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() 

vi consiglio di non usare jpg come maschera a causa del suo formato lossy, ho consiglio bmp o png (bmp è meglio). Ricordate che non utilizza alpha modo che i bordi non saranno anti-aliasing quindi non è una bella soluzione nel 2010 :)

Ecco lo screenshot del risultato: masked blitting

Edit: Ciao di nuovo,

Ho effettuato alcuni test con il blitting con BLEND_ADD ed i risultati sono stati promettenti.Ecco il codice:

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() 

E il risultato: result

Con questa soluzione è possibile ottenere per pixel alpha texturing. Si prega di notare che la maschera dovrebbe essere un'immagine con canale alfa in modo che jpg non possa essere usato. Il migliore da usare è png.

immagine Struttura (texture.jpg): texture

immagine Mascherina (mask2.png): mask

5

Se stai usando le immagini con un alpha pre-renderizzati e additivi miscelazione, è possibile ottenere maschere alfa-miscelati:

import pygame 
import sys 

screen = pygame.display.set_mode((800, 600)) 
pygame.init() 

background = pygame.image.load("background.png") 
mask = pygame.image.load("mask.png") 

# Create a surface to hold the masked image 
masked_image = pygame.surface.Surface(background.get_size(), 0, mask) 
# Blit the texture normally 
masked_image.blit(background, (0,0)) 
# Multiply by the pre-rendered, inverted mask 
masked_image.blit(mask, (0,0), None, pygame.BLEND_MULT) 

# masked_image now holds the 'cutout' of your texture blended onto a black 
# background, so we need to blit it as such, i.e., using additive blending. 
screen.fill((0, 0, 0)) 
screen.blit(masked_image, (10, 10), None, pygame.BLEND_ADD) 

pygame.display.flip() 

while True: 
    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() 

Dove background.png e mask.png sono:

background.png + mask.png = result

+0

Ehi, grazie. Ho intenzione di provarci stasera. – agscala