2011-09-12 3 views
1

J'essaie d'écrire un jeu 2D en utilisant python/pygame qui bloque plusieurs couches les unes sur les autres à chaque rafraîchissement de l'écran. Ma configuration de base est (de bas en haut):Comment effacer une couche alpha de pygame efficacement?

  • Contexte: surface (non transparente), défile à une vitesse différente de celle de repos
  • second plan: SRCALPHA surface transparente (statique)
  • Lecteur/sprites/ennemis: groupe sprite
  • forground: SRCALPHA surface transparente (statique)

en ce moment, je suis blitting ces quatre couches superposées au-dessus d'une autre chaque écran. L'arrière-plan défile à un rythme différent des trois autres couches, ce qui explique pourquoi je l'ai séparé de mi-champ. Comme j'ai le jeu structuré maintenant, il fonctionne sur mon ordinateur portable assez modeste à 60fps.

-BUT- J'ai des problèmes avec le groupe de sprites, que je bluffe directement à l'écran. Avoir à ajuster le rect pour chaque sprite en fonction de ma fenêtre d'affichage actuelle semble être une façon moche de programmer les choses, et j'aimerais une solution plus élégante. J'aimerais ajouter les sprites à une autre surface transparente que je pourrais gérer, mais c'est là que réside mon problème: je n'arrive pas à trouver un moyen d'effacer un calque transparent qui ne fait pas la moitié de mes performances. Certaines des configurations que j'ai essayé:

  • J'ai essayé de remplir la couche avec une surface blanche avec mode de fusion rgba_sub (surf.fill ((255.255.255.255), région, BLEND_RGBA_SUB)) - c'est super, super lent
  • J'ai essayé surface.copy() d'une surface vierge - cela est plus rapide, mais encore réduit de moitié mon ips
  • J'ai essayé de combiner les sprites avec la couche de second plan et à l'aide pygame.sprite.LayeredUpdates à mettre à jour les sprites. Cela n'a aucun effet sur les performances, mais ne fonctionne pas lorsque le milieu est transparent. Je reçois des traces de sprites sur la couche de fond.

La meilleure solution que j'ai trouvée jusqu'ici est ma configuration actuelle de sprites de dessin directement à l'écran. Ça a l'air génial, ça tourne vite, mais c'est difficile à gérer, car je dois m'assurer que le rectangle de chaque sprite est ajusté en fonction de la fenêtre à chaque image. Cela rend également la détection des collisions difficile. Y at-il un autre moyen rapide d'effacer une surface transparente de pygame?

Rapide comme dans, peut être fait 60+ fois par seconde? Alternativement, y a-t-il une configuration pour mes couches qui accomplirait toujours le même effet? Le Surface.fill() effacera toutes les valeurs R, G, B et A.

Répondre

1

J'ai trouvé un moyen rapide de compensation une sprites que la couche transparente en appliquant la solution de Pierre sélective à la couche:

for s in self.level.sprites: 
    spritelayer.fill((0), s.rect) 

Cela semble fonctionner très bien (tout effacer chaque image) et fonctionne toujours à 60fps .

1

>>> img = pygame.image.load("hasalpha.png") 
>>> print img.get_at((300, 300)) 
(238, 240, 239, 255) 
>>> surface.fill(0) 
>>> print img.get_at((300, 300)) 
(0, 0, 0, 0) 

Il semble que cela fera ce que vous décrivez. Si vous essayez de faire quelque chose de plus spécifique avec les valeurs alpha, les fonctions pygame.surfarray.pixel peuvent vous donner directement des valeurs modifiables. Ce sera rapide, mais nécessite numpy comme une dépendance.

+0

Cela semble fonctionner plus vite que surf.fill ((255,255,255,255), zone, BLEND_RGBA_SUB), mais me donne toujours des performances réduites de moitié lorsque je l'exécute sur l'ensemble du calque. – drinkdecaf

+0

Aha! Mais quand je l'applique seulement sur les sprites, il fonctionne RAPIDEMENT: D Merci monsieur! – drinkdecaf

Questions connexes