Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
415 views
in Technique[技术] by (71.8m points)

python - Render anti-aliased text on transparent surface in pygame

I'm making a function that takes a string a breaks it up into lines and returns a surface with each line rendered below the previous one.

For example:

Line1 Line 2

Renders into:

Line1
Line2

Anyway, my problem is that I cannot return a properly transparent surface to the calling function. I've tried using a color-key, but it does't work with anti-aliased text. Is there a way I can do this? Thanks for your answers.

My code: (Currently leaves an ugly purple shadow around text)

def render_message(messages):
    surfaces = []
    height = 0
    max_width = 0

    for message in messages.split('
'):
        surf = FONT.render(message, True, (0, 0, 0))
        surfaces.append(surf)
        height += surf.get_height() + 5
        if surf.get_width() > max_width:
            max_width = surf.get_width()

    result = pygame.Surface((max_width, height))
    result.fill((255, 0, 255))
    result.set_colorkey((255, 0, 255))

    top = 0
    for surface in surfaces:
        result.blit(surface, (max_width/2-surface.get_width()/2, top))
        top += surface.get_height() + 5

    return result
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Got it working. Main not I found is: no AA = automatic transparent. With AA you need to set the color key too

Here's working example, and it toggles BG to ensure it is transparent.

import pygame
from pygame import Surface
#from pygame.locals import Rect, Color
from pygame.locals import *

class TextWall():
    def __init__(self, font=None, size=300):
        # for simplicity uses one font, one size for now.
        # You also can make font size, .text, etc be properties so they *automatically* toggle dirty bool.
        self.font_name = font
        self.font_size = size
        self.color_fg = Color("white")
        self.color_bg = Color("gray20")
        self.aa = True 
        self.text = "hi world"

        self.dirty = True
        self.font = pygame.font.Font(font, size)
        self.screen = pygame.display.get_surface()


    def _render(self):
        # re-render
        """no AA = automatic transparent. With AA you need to set the color key too"""
        self.dirty = False        
        self.text1 = self.font.render(self.text, self.aa, self.color_fg)            
        self.rect1 = self.text1.get_rect()

    def draw(self):
        # blits use cached surface, until text change makes it dirty
        if self.dirty or self.text1 is None: self._render()
        self.screen.blit(self.text1, self.rect1)

    def text(self, text):
        self.dirty = True
        self.text_message = text # parse

class Game():
    done = False
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode ((640,480))
        self.text = Surface([200,100])

        self.text_wall = TextWall()
        self.toggle_bg = True
    def loop(self):
        while not self.done:
            self.handle_events()
            self.draw()

    def draw(self):
        if self.toggle_bg: bg = Color("darkred")
        else: bg = Color("gray20")

        self.screen.fill(bg)        
        self.text_wall.draw()        
        pygame.display.update()

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT: self.done = True

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE: self.done = True                
                elif event.key == K_SPACE: self.toggle_bg = not self.toggle_bg
                elif event.key == K_a: 
                    self.text_wall.aa = not self.text_wall.aa
                    self.text_wall.dirty = True


if __name__ == "__main__":
    g = Game()
    g.loop()

edit: Improved code, uses alpha channel instead of set_colorkey.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...