2017-09-04 125 views
1

我想用pyglet做一個簡單的應用程序。到目前爲止,我的主要問題是,我似乎無法用alpha處理圖像 - 所有透明像素都轉換成黑色像素。我不確定問題是否與加載圖像或blitting有關。以下是我如何渲染圖像的基本概述:pyglet - 加載/ blitting圖像與阿爾法

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

任何幫助表示讚賞。提前致謝。

回答

2

你最有可能只需要啓用GL ALPHA混合。

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

但首先,您的代碼無法運行。 大部分原因是因爲您沒有聲明window.event函數來處理通常呈現內容的on_draw

其次,你永遠不清除窗口(這將導致一個爛攤子)。

這是你的代碼的一小部分工作示例:

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

現在,這產生這樣的:

enter image description here

下面是你如何使用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() 

這產生如下結果:

enter image description here

然而,這個代碼將很快成爲凌亂。
所以你可以做兩件事。你可以先將你的圖片放入精靈對象中。其次,讓這個更加面向對象。

首先,我們將使用精靈。

self.fancy_background = pyglet.sprite.Sprite(pyglet.image.load('bg.png')) 
self.fancy_background.draw() # not blit! 

Sprites會自動使用透明度,這會讓您的生活(和代碼)變得更容易。

其次,我們會把這些到一個批處理。
批次到一堆製作的精靈了很多,所以你可以調用批處理.draw(),並在該批次所有精靈得到斯塔渲染。

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!! 

最後也是最重要的。
我們將把它放到一個類中,以便我們稍後可以做很酷的東西。

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。

此代碼將使您稍後創建自定義功能和自定義「的球員對象」的實例。你也可以更容易地實現碰撞檢測,代碼看起來更加結構化(我投入了一些額外的功能,如鍵盤和鼠標事件)。

請注意,如上圖所示,精靈的位置將默認爲x=0, y=0。您可以使用x=100在變量/句柄或創建精靈時設置位置。

+0

正如我所說,我把我使用的代碼非常簡化的版本。我知道如何在python中創建應用程序,多年來一直這樣做。你沒有必要把所有額外的信息,但謝謝你無論如何做。明確的upvote。 – nousername

+1

@nousername錯過了它是一個簡化版本。但即使如此,如果將它最小化爲至少能夠運行的版本,它將會很整潔。最後,其他人可能會在這裏結束(很常見的話題),所以我認爲最好留下一個徹底的答案。爲您的項目喝彩並祝您好運:D – Torxed