2017-09-04 4 views
1

J'essaye de faire une application simple avec pyglet. Mon problème principal jusqu'ici est que je ne peux pas sembler bliter une image avec alpha - tous les pixels transparents sont convertis en pixels noirs. Je ne suis pas sûr si le problème est avec le chargement de l'image ou le blitting. Voici un aperçu très basique de la façon dont j'essaie de rendre l'image:pyglet - chargement/blitting image avec alpha

import pyglet 
import pyglet.clock 

window = pyglet.window.Window() 

window.config.alpha_size = 8 

#fancy text 
text = pyglet.resource.image("text.png") 

#background image 
bg = pyglet.resource.image("bg.png") 

bg.blit(0, 0) 
text.blit(100, 100) 

pyglet.app.run() 

Toute aide est appréciée. Merci d'avance.

Répondre

2

Vous avez très probablement juste besoin d'activer les mélanges GL ALPHA.

from pyglet.gl import * 
glEnable(GL_BLEND) 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 

Mais tout d'abord, votre code ne peut pas être exécuté. Principalement parce que vous ne déclarez pas une fonction window.event pour gérer le on_draw où vous rendez normalement les choses. Deuxièmement, vous ne videz jamais votre fenêtre (ce qui causera un désordre).

Voici un exemple de travail minimal de votre code:

import pyglet 
import pyglet.clock 

window = pyglet.window.Window() 

window.config.alpha_size = 8 

#fancy text 
text = pyglet.resource.image("text.png") 

#background image 
bg = pyglet.resource.image("bg.png") 

@window.event 
def on_draw(): 
    window.clear() 

    bg.blit(0, 0) 
    text.blit(100, 100) 

pyglet.app.run() 

Maintenant, cela génère ceci:

enter image description here

Et voici un exemple concret de la façon dont vous utilisez la fonction GL_BLEND:

import pyglet 
import pyglet.clock 
from pyglet.gl import * 

window = pyglet.window.Window() 

window.config.alpha_size = 8 

#fancy text 
text = pyglet.resource.image("text.png") 

#background image 
bg = pyglet.resource.image("bg.png") 

@window.event 
def on_draw(): 
    window.clear() 
    glEnable(GL_BLEND) 

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
    bg.blit(0, 0) 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
    text.blit(100, 100) 

pyglet.app.run() 

Ceci donne un résultat comme ceci:

enter image description here

Cependant, ce code deviendra rapidement en désordre.
Donc, il y a deux choses que vous pouvez faire. Vous pouvez d'abord, mettre vos images dans des objets sprites. Deuxièmement, faites-en un peu plus orienté objet.

D'abord, nous allons utiliser des sprites. Sprites utilise automatiquement la transparence, ce qui rend votre vie (et le code) beaucoup plus facile.

Deuxièmement, nous allons les mettre dans un lot.
Les lots sont constitués de BEAUCOUP de sprites, vous pouvez donc appeler le .draw() sur le lot, et tous les sprites de ce lot sont insta-rendus.

self.background = pyglet.graphics.Batch() 
self.fancy_background = pyglet.sprite.Sprite(pyglet.image.load('bg.png'), batch=self.background) 
self.background.draw() # background, not fancy_background! And also not blit!! 

Dernier point et certainement pas des moindres.
Nous allons mettre cela dans une classe afin que nous puissions faire des choses cool plus tard.

import pyglet 
import pyglet.clock 
from pyglet.gl import * 

key = pyglet.window.key 

class main(pyglet.window.Window): 
    def __init__ (self, width=800, height=600, fps=False, *args, **kwargs): 
     super(main, self).__init__(width, height, *args, **kwargs) 
     self.x, self.y = 0, 0 

     self.background = pyglet.graphics.Batch() 
     self.texts = pyglet.graphics.Batch() 

     self.fancy_background = pyglet.sprite.Sprite(pyglet.image.load('bg.png'), batch=self.background) 
     self.fancy_text = pyglet.sprite.Sprite(pyglet.image.load('text.png'), batch=self.texts) 

     self.mouse_x = 0 
     self.mouse_y = 0 
     self.alive = 1 

    def on_draw(self): 
     self.render() 

    def on_close(self): 
     self.alive = 0 

    def on_mouse_motion(self, x, y, dx, dy): 
     self.mouse_x = x 
     self.mouse_y = y 

    def on_mouse_press(self, x, y, button, modifiers): 
     if button == 1: # Left click 
      pass 

    def on_key_press(self, symbol, modifiers): 
     if symbol == key.ESCAPE: # [ESC] 
      self.alive = 0 

    def render(self): 
     self.clear() 

     self.background.draw() 
     self.texts.draw() 

     self.flip() 

    def run(self): 
     while self.alive == 1: 
      self.render() 

      # -----------> This is key <---------- 
      # This is what replaces pyglet.app.run() 
      # but is required for the GUI to not freeze 
      # 
      event = self.dispatch_events() 

if __name__ == '__main__': 
    x = main() 
    x.run() 

enter image description here

BAM.

Ce code vous permettra par exemple de créer des fonctions personnalisées et des "objets joueurs" personnalisés.En outre, vous pouvez faciliter la détection des collisions et le code semble beaucoup plus structuré (j'ai ajouté quelques fonctionnalités bonus telles que les événements clavier et souris).

Notez que la position des sprites sera par défaut x=0, y=0 comme indiqué dans la dernière image. Vous pouvez définir la position avec x=100 soit sur la variable/le handle, soit lors de la création de l'image-objet.

+0

Comme je l'ai dit, j'ai mis une version TRÈS simplifiée du code que j'utilisais. Je sais créer des applications en python depuis des années. Vous n'avez pas eu à mettre toutes les informations supplémentaires, mais merci de le faire quand même. Upvote définitive. – nousername

+1

@nousername Missed que c'était une version simplifiée. Mais même dans ce cas, il serait intéressant de le réduire à une version au moins capable de fonctionner :) Enfin, d'autres pourraient se retrouver ici (un sujet assez courant) alors j'ai pensé qu'il valait mieux laisser une réponse complète. Salutations pour l'upvote et bonne chance pour votre projet: D – Torxed