Assigning different palette indices to a paletted image

时光总嘲笑我的痴心妄想 提交于 2019-12-23 17:22:17

问题


I'm writing a game with Python and Pygame. For this, the graphics will be in the style of old video game consoles like the NES. Therefore, the graphics consist of a single tileset file with 2-bit (4-colour) images, and I want to be able to assign an arbitrary 4-colour palette to these images when loading them.

What I want to do is use an 8-bit (256-colour) palette mode, with a palette that I have divided into 64 sub-palettes of 4 colours each. Every time I load a 16x16 tile from the 2-bit graphics file, I want to assign one of these virtual 4-colour palettes to it. So, in the raw tile set file, the palette indices are going to be 0-3, because it is a 2-bit indexed file. I want to load tiles from this file into memory, and use a function to reassign the palette indices from 0-3 to whatever palette offset I choose, so that when I blit it to screen, it is coloured in my choice of 4-colour palette -- much like the NES hardware works. This gets a little hairy to explain, so maybe this picture makes it a little clearer:

I have looked around the manuals of Pygame and PIL and found nothing that lets me manipulate paletted files like this. Are there any other libs to look into, or is there a simpler solution I'm not seeing?


回答1:


Although I personally have not done this, in PyGame I believe the call you're searching for is: http://pygame.org/docs/ref/surface.html#Surface.set_palette




回答2:


You can do this with pygame.Surface.set_palette_at(). In your case, you have four colours for sixty-four blocks, so to recolour a specific block, you might use:

for n, newRGBA in enumerate(fourNewColours):  # where fourNewColours are the RGBA tuples you want to plop into the palette.
    GameSurface.set_palette_at(palette_offset + n, newRGBA)  # where palette_offset is the number of the first palette index you want to replace (adding n to increment your way through the new colours).

This is how you might replace individual blocks of four colours. Pushing every palette into the game surface to start with may be more complicated, since pygame seems to approximate blit'd images' palettes instead of replacing the destination surface's indices directly. More complicated because I don't know how you'd go about recolouring pixels with duplicate index RGBA values. (For instance if Palette 14/2 and Palette 40/1 are both (90,91,200,255), for example. I don't know if pygame will assign all pixels with that RGBA value to palette index 57 (from Pal14/2) and none to idx 160 for Pal40/1, or if the two will remain distinct. This could become an issue if you want to recolour images on the fly. It ought to work reliably if you take the slightly longer route and alter the game palette as needed, then blit (or re-blit) surfaces with the relevant new palettes later.

Hope that's useful (even though it's well over two and a half years later)!

If you want to see a longer-form version of this answer, check out this link.



来源:https://stackoverflow.com/questions/9126141/assigning-different-palette-indices-to-a-paletted-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!