2017-09-04 123 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