Pyglet:blit_into纹理和alpha

时间:2015-09-12 06:49:28

标签: python pyglet

我现在已经使用pyglet一段时间了,我真的很喜欢它。不过,我有一件事我想做但却无法做到。

我正在开发2D角色扮演游戏,我希望这些角色能够看起来与众不同 - 也就是说,我不喜欢使用完全预先构建的精灵,而是我和I&# #39; d喜欢那里有一系列发型和装备,在游戏中可以看到角色。

所以为了让这个东西起作用,我认为最有效的方法是使用pyglet.image.Texture.create()创建一个纹理,然后使用Texture在该纹理上创建正确的精灵源图像。 blit_into。例如,我可以在纹理上显示裸露的人体图像,然后在其上点亮头发纹理等。

human_base  = pyglet.image.load('x/human_base.png').get_image_data()
hair_style  = pyglet.image.load('x/human_hair1.png').get_image_data()

texture = pyglet.image.Texture.create(width=human_base.width,height=human_base.height)

texture.blit_into(human_base, x=0, y=0, z=0)
texture.blit_into(hair_style, x=0, y=0, z=1)

sprite = pyglet.sprite.Sprite(img=texture, x=0, y=0, batch=my_sprite_batch)

问题是将第二张图像blit到纹理中"覆盖"虽然两个图像都有一个alpha通道,但是当hair_style在它上面是blit之后,下面的图像(human_base)是不可见的。

一读这可能会想知道为什么这样做,而不是创建两个不同的pyglet.sprite.Sprite对象,一个用于human_base,一个用于hair_style,只需将它们移动到一起即可。有一点是绘制顺序:游戏是基于图块和等距的,所以对包含不同图层的多个精灵(或pyglet调用它们的有序组)组成的可见对象进行排序将是一个主要的痛苦。

所以我的问题是,有没有办法在使用pyglet使用blit_into时保留alpha。如果没有办法做到这一点,那么,非常感谢任何有关此方法的替代方法的建议!

2 个答案:

答案 0 :(得分:2)

正确设置混合功能应解决此问题:

pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)

答案 1 :(得分:1)

我遇到了同样的问题,无法找到合适的解决方案。显然将两个RGBA图像/纹理重叠在一起将删除下面的图像。我想出的另一个方法是使用每一件衣服形象'将每个角色作为附加到批次和群组的独立精灵,但这远远不是最佳,并且显着降低了FPS。

我使用PIL获得了自己的解决方案

import pyglet
from PIL import Image
class main(pyglet.window.Window):
    def __init__ (self):
        TILESIZE = 32
        super(main, self).__init__(800, 600, fullscreen = False)
        img1 = Image.open('under.png')
        img2 = Image.open('over.png')
        img1.paste(img2,(0,0),img2.convert('RGBA'))
        img = img1.transpose(Image.FLIP_TOP_BOTTOM)
        raw_image=img.tostring()
        self.image=pyglet.image.ImageData(TILESIZE,TILESIZE,'RGBA',raw_image)

    def run(self):
        while not self.has_exit:
            self.dispatch_events()
            self.clear()
            self.image.blit(0,0)
            self.flip()
x = main()
x.run()

这可能不是最佳解决方案,但如果您在场景加载中进行加载,那么它就不重要了,结果几乎可以做任何你想做的事情(只要你不要#39;把它放在另一个纹理上,嘿)。如果你想从带有PIL的tileset中获得1个tile(或列或行或矩形框),你可以使用crop函数。