本文介绍了在pygame的透明表面渲染反锯齿文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



例如:



Line1\\\
Line 2





  Line1 
Line2

无论如何,我的问题是,我不能返回一个正确的透明表面的调用函数。我试过使用一个颜色键,但它不适用于反锯齿文本。有什么办法可以做到这一点?感谢您的回答。



我的代码:(目前在文字周围留下一个丑陋的紫色阴影)

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

messages.split '\\\
'):
surf = FONT.render(message,True,(0,0,0))
surfaces.append(surf)
height + = surf.get_height( )+ 5
如果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))
$ b $ top = 0
表面:
result.blit(surface,(max_width / surface.get_width()/ 2,top))
top + = surface.get_height()+ 5

返回结果

解决方案

发表第二个答案,因为这更复杂,人们可能想看到两者。






  • 1 2 减少/增加字体大小

  • 空格切换BG



文本包装。编辑 parse_text()来创建你想要的文本列表。

 从pygame import import pygame 
从pygame.locals导入Surface
导入*
#Todo:从TextLine()中删除字体对象到TextWall()。然后与任何一行共享一个字体列表。

多行文本类的示例,带有alpha透明度。
lorem =Lorem ipsum dolor sit amet,consectetur adipiscing elit。Sed aliquet
tellus eros,eu faucibus dui。Phasellus eleifend,massa id ornare sodales,est urna
congue tellus,vitae varius metus nunc non enim。Mauris elementum,arcuvitae tempor euismod,justo turpis malesuada est,sed dictum nunc nulla nec在这种情况下,我们可以把它们看成是一种可能性,也就是说,它们可以被看成是一种可能性,我们可以在这里找到一些有趣的东西,这些东西可以用来表达我们的想法,
est lectus varius erat,sit amet ultrices tortor nisi id justo。Aliquam elementum vestibulum dui ut auctor。Mauris大商店简介augus tempus sagittis。 Morbi一个nibh lectus,sed porta nibh。 Donec et est ac dui sodales aliquet tristique et arcu。 Nullam enim felis,posuere vel rutrum eu,euismod a purus。 Morbi porta cursus libero,id rutrum elit lacinia vitae。

在实际数据中,可以使用egestas et。克拉斯在egestas elit。 Morbi
quis neque ligula。 Sed tempor,sem在fringilla rhoncus,diam quam mollis nisi,vitae semper
mi massa坐amet tellus。 Vivamus认为商品ornare。 Morbi et mi non sem malesuada rutrum。 Etiam est purus,interdum ut placerat sit amet,tempus eget eros。 Duis eget augue quis diam facilisis blandit。 Ut vulputate adipiscing eleifend。
$ b $ class TextLine(object):
#管理绘图和缓存一行文本
#你可以设置字体大小,.color_fg等属性,自动*开关脏bool。
def __init __(self,font = None,size = 16,text =hi world):
self.font_name = font
self.font_size = size
self.color_fg =颜色(白色)
self.color_bg =颜色(gray20)

self._aa = True
self._text = text
self.font = pygame.font.Font(font,size)
self.screen = pygame.display.get_surface()

self.dirty = True
self .image = None
self._render()

def _render(self):
#渲染缓存
no AA =自动透明。用AA你也需要设置颜色键
self.dirty = False
self.image = self.font.render(self._text,self.aa,self.color_fg)
self.rect = self.image.get_rect()

def draw(self):
#调用do draw,总是喜欢使用缓存
self.dirty或者(self.image是None):self._render()
self.screen.blit(self.image,self.rect)

@property
def text(self ):
return self._text

@ text.setter
def text(self,text):
self.dirty = True
self._text =文本

@property
def aa(self):return self._aa

@ aa.setter
def aa(self,aa):
self.dirty = True
self._aa = aa
$ b $ class TextWall(object):
#管理多行文本/段落
def __init __(self,font = None,size = 16):
self.font = font
self.font_size = size
self.offset = Rect(20,20,1,1)#整墙的偏移量

self.screen = pygame.display.get_surface()
self.dirty = True
self.text_lines = []
self._text_paragraph =Empty \\\
Text
self._render()
$ b $ def _render self):
#render list
self.dirty = False
self.text_lines = [TextLine(self.font,self.font_size,line)in self._text_paragraph]

#偏移整段
self.text_lines [0] .rect.top = self.offset.top

#偏移每一行的高度
prev = Rect(0,0,0,0)
for self.text_lines:
t.rect.top + = prev.bottom
t.rect.left = self.offset.left
prev = t.rect

def parse_text(self,text):
#将原始文本解析为可用
self._text_par agraph = text.split(\\\

self._render()

def draw(self):
#使用缓存表面绘制
如果使用self .dirty:self._render()
用于self.text_lines中的文本:text.draw()
$ b @property
def font_size(self):
return self ._font_size

@ font_size.setter
def font_size(self,size):
self.dirty = True
self._font_size = size

@property
def text(self):
return self._text_paragraph

@ text.setter
def text(self,text_paragraph):
self.dirty = True
self.parse_text(text_paragraph)
$ b $ 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 =真

self.text_wall.parse_text(lorem)

def循环(self):
而不是self.done:
self.handle_events()
self.draw()

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

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

def handle_events(self):
为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_1:self.text_wall。 font_size - = 3
elif event.key == K_2:self.text_wall.font_size + = 3
$ b if if __name__ ==__main__:
g = Game()
g.loop()


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\nLine 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('\n'):
        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
解决方案

Posted a second answer since this is more complex, people might want to see both.

  • 1 , 2 decrease/increase font size
  • space toggle BG

I left text wrapping out. Edit parse_text() to create a list of text you want.

import pygame
from pygame import Surface
from pygame.locals import *
# Todo: remove font object from TextLine() , to TextWall(). Then share a list of font's with any line.

"""Example of multi-line text class, with alpha transparency."""
lorem = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed aliquet
tellus eros, eu faucibus dui. Phasellus eleifend, massa id ornare sodales, est urna
congue tellus, vitae varius metus nunc non enim. Mauris elementum, arcu vitae tempor euismod, justo turpis malesuada est, sed dictum nunc nulla nec mauris. Cras felis eros, elementum vitae sollicitudin in, elementum et augue. Proin eget nunc at dui congue pretium. Donec ut ipsum ut lacus mollis tristique. In pretium varius dui eu dictum.

Proin pulvinar metus nec mi semper semper. Pellentesque habitant morbi tristique
senectus et netus et malesuada fames ac turpis egestas. Proin in diam odio. Vestibulum
at neque sed ante sodales eleifend quis id dui. Mauris sollicitudin, metus a semper consectetur,
est lectus varius erat, sit amet ultrices tortor nisi id justo. Aliquam elementum vestibulum dui ut auctor. Mauris commodo sapien vitae augue tempus sagittis. Morbi a nibh lectus, sed porta nibh. Donec et est ac dui sodales aliquet tristique et arcu. Nullam enim felis, posuere vel rutrum eu, euismod a purus. Morbi porta cursus libero, id rutrum elit lacinia vitae.

In condimentum ultrices ipsum, ut convallis odio egestas et. Cras at egestas elit. Morbi
quis neque ligula. Sed tempor, sem at fringilla rhoncus, diam quam mollis nisi, vitae semper
mi massa sit amet tellus. Vivamus congue commodo ornare. Morbi et mi non sem malesuada rutrum. Etiam est purus, interdum ut placerat sit amet, tempus eget eros. Duis eget augue quis diam facilisis blandit. Ut vulputate adipiscing eleifend. """

class TextLine(object):
    # Manages drawing and caching a single line of text
    # You can make font size, .color_fg etc be properties so they *automatically* toggle dirty bool.
    def __init__(self, font=None, size=16, text="hi world"):
        self.font_name = font
        self.font_size = size
        self.color_fg = Color("white")
        self.color_bg = Color("gray20")

        self._aa = True
        self._text = text
        self.font = pygame.font.Font(font, size)
        self.screen = pygame.display.get_surface()

        self.dirty = True
        self.image = None
        self._render()

    def _render(self):
        # render for cache
        """no AA = automatic transparent. With AA you need to set the color key too"""
        self.dirty = False
        self.image = self.font.render(self._text, self.aa, self.color_fg)
        self.rect = self.image.get_rect()

    def draw(self):
        # Call this do draw, always prefers to use cache
        if self.dirty or (self.image is None): self._render()
        self.screen.blit(self.image, self.rect)

    @property
    def text(self):
        return self._text

    @text.setter
    def text(self, text):
        self.dirty = True
        self._text = text

    @property
    def aa(self): return self._aa

    @aa.setter
    def aa(self, aa):
        self.dirty = True
        self._aa = aa

class TextWall(object):
    # Manages multiple lines of text / paragraphs.
    def __init__(self, font=None, size=16):
        self.font = font
        self.font_size = size
        self.offset = Rect(20,20,1,1) # offset of whole wall

        self.screen = pygame.display.get_surface()
        self.dirty = True
        self.text_lines = []
        self._text_paragraph = "Empty\nText"
        self._render()

    def _render(self):
        # render list
        self.dirty = False
        self.text_lines = [ TextLine(self.font, self.font_size, line) for line in self._text_paragraph ]

        # offset whole paragraph
        self.text_lines[0].rect.top = self.offset.top

        # offset the height of each line
        prev = Rect(0,0,0,0)
        for t in self.text_lines:
            t.rect.top += prev.bottom
            t.rect.left = self.offset.left
            prev = t.rect

    def parse_text(self, text):
        # parse raw text to something usable
        self._text_paragraph = text.split("\n")
        self._render()

    def draw(self):
        # draw with cached surfaces
        if self.dirty: self._render()
        for text in self.text_lines: text.draw()

    @property
    def font_size(self):
        return self._font_size

    @font_size.setter
    def font_size(self, size):
        self.dirty = True
        self._font_size = size

    @property
    def text(self):
        return self._text_paragraph

    @text.setter
    def text(self, text_paragraph):
        self.dirty = True
        self.parse_text(text_paragraph)

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

        self.text_wall.parse_text(lorem)

    def loop(self):
        while not self.done:
            self.handle_events()
            self.draw()

    def draw(self):
        if self.toggle_bg: bg = Color("gray60")
        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_1: self.text_wall.font_size -= 3
                elif event.key == K_2: self.text_wall.font_size += 3

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

这篇关于在pygame的透明表面渲染反锯齿文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 22:31