【问题标题】:Pyglet: blit_into texture and alphaPyglet:blit_into 纹理和 alpha
【发布时间】:2015-12-08 18:13:10
【问题描述】:

我已经使用 pyglet 有一段时间了,我真的很喜欢它。但是,我有一件想做的事,但到目前为止还没有做。

我正在开发一款 2D 角色扮演游戏,我希望角色能够看起来不同 - 也就是说,我不喜欢使用完全预建的精灵,但我希望有一系列,例如,发型和装备,在游戏中的角色上可见。

所以为了让这个东西正常工作,我认为最明智的方法是使用 pyglet.image.Texture.create() 创建一个纹理,并使用 Texture 在该纹理上对正确的精灵源图像进行 blit。 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)

问题在于,将第二张图像blitting 到纹理中会“覆盖”已经blitted 的纹理。即使两个图像都有一个alpha 通道,下面的图像(human_base)在hair_style 被blit 后不可见它。

阅读本文的人可能想知道为什么要这样做,而不是创建两个不同的 pyglet.sprite.Sprite 对象,一个用于human_base,一个用于hair_style,然后将它们一起移动。一件事是绘制顺序:游戏是基于图块和等距的,因此对由具有不同层的多个精灵(或有序组,pyglet 称之为)组成的可见对象进行排序将是一个很大的痛苦。

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

【问题讨论】:

    标签: python pyglet


    【解决方案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()
    

    这可能不是最佳解决方案,但是如果您在场景加载中进行加载,那么这无关紧要,结果您几乎可以做任何您想做的事情(只要您不在另一个纹理上粘贴它,呵呵)。如果你想用 PIL 从一个瓦片集中只得到 1 个瓦片(或一列、一行或一个矩形框),你可以使用裁剪函数。

    【讨论】:

      【解决方案2】:

      正确设置混合功能应该可以解决这个问题:

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

      【讨论】:

      • 这看起来是更好的解决方案
      猜你喜欢
      • 2019-03-12
      • 1970-01-01
      • 2011-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多