Render anti-aliased text on transparent surface in pygame

后端 未结 2 1173
攒了一身酷
攒了一身酷 2020-12-07 04:33

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:

2条回答
  •  心在旅途
    2020-12-07 04:57

    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.

提交回复
热议问题