Python 如何在字体上绘制轮廓(Pygame)

Python 如何在字体上绘制轮廓(Pygame),python,fonts,pygame,outline,Python,Fonts,Pygame,Outline,我能在字体上画轮廓吗?我想使用黑色字体,但背景必须是黑色的,所以很难看到字体。我假设myfont.render不支持在字体上绘制轮廓。还有其他方法吗?Pygame不支持开箱即用,但一种方法是以大纲颜色渲染文本,并将其多次移动到结果表面,然后以所需颜色渲染文本 使用这种技术;其代码的精简版本如下所示: import pygame _circle_cache = {} def _circlepoints(r): r = int(round(r)) if r in _circle_c

我能在字体上画轮廓吗?我想使用黑色字体,但背景必须是黑色的,所以很难看到字体。我假设myfont.render不支持在字体上绘制轮廓。还有其他方法吗?

Pygame不支持开箱即用,但一种方法是以大纲颜色渲染文本,并将其多次移动到结果表面,然后以所需颜色渲染文本

使用这种技术;其代码的精简版本如下所示:

import pygame

_circle_cache = {}
def _circlepoints(r):
    r = int(round(r))
    if r in _circle_cache:
        return _circle_cache[r]
    x, y, e = r, 0, 1 - r
    _circle_cache[r] = points = []
    while x >= y:
        points.append((x, y))
        y += 1
        if e < 0:
            e += 2 * y - 1
        else:
            x -= 1
            e += 2 * (y - x) - 1
    points += [(y, x) for x, y in points if x > y]
    points += [(-x, y) for x, y in points if x]
    points += [(x, -y) for x, y in points if y]
    points.sort()
    return points

def render(text, font, gfcolor=pygame.Color('dodgerblue'), ocolor=(255, 255, 255), opx=2):
    textsurface = font.render(text, True, gfcolor).convert_alpha()
    w = textsurface.get_width() + 2 * opx
    h = font.get_height()

    osurf = pygame.Surface((w, h + 2 * opx)).convert_alpha()
    osurf.fill((0, 0, 0, 0))

    surf = osurf.copy()

    osurf.blit(font.render(text, True, ocolor).convert_alpha(), (0, 0))

    for dx, dy in _circlepoints(opx):
        surf.blit(osurf, (dx + opx, dy + opx))

    surf.blit(textsurface, (opx, opx))
    return surf

def main():
    pygame.init()

    font = pygame.font.SysFont(None, 64)

    screen = pygame.display.set_mode((350, 100))
    clock = pygame.time.Clock()

    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
        screen.fill((30, 30, 30))

        screen.blit(render('Hello World', font), (20, 20))

        pygame.display.update()
        clock.tick(60)

if __name__ == '__main__':
    main()
导入pygame
_圈_缓存={}
def_回路点(r):
r=int(圆形(r))
如果r在循环缓存中:
返回循环缓存[r]
x、 y,e=r,0,1-r
_圆形缓存[r]=点=[]
当x>=y时:
点。附加((x,y))
y+=1
如果e<0:
e+=2*y-1
其他:
x-=1
e+=2*(y-x)-1
点数+=[(y,x)表示x,如果x>y,则表示点中的y]
点+=[(-x,y)表示x,y表示x时的点]
点+=[(x,-y)表示x,y表示点,如果是y]
points.sort()
返回点
def render(文本、字体、gfcolor=pygame.Color('dodgerblue')、ocolor=(255、255、255)、opx=2):
textsurface=font.render(text,True,gfcolor).convert_alpha()
w=textsurface.get_width()+2*opx
h=font.get_height()
osurf=pygame.Surface((w,h+2*opx)).convert_alpha()
osurf.填充((0,0,0,0))
surf=osurf.copy()
blit(font.render(text,True,ocolor).convert_alpha(),(0,0))
对于dx,dy in_圆点(opx):
冲浪板(osurf,(dx+opx,dy+opx))
冲浪板(textsurface,(opx,opx))
回浪
def main():
pygame.init()
font=pygame.font.SysFont(无,64)
screen=pygame.display.set_模式((350100))
clock=pygame.time.clock()
尽管如此:
events=pygame.event.get()
对于事件中的e:
如果e.type==pygame.QUIT:
回来
屏幕填充((30,30,30))
blit(呈现('helloworld',字体),(20,20))
pygame.display.update()
时钟滴答(60)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

Pygame不支持开箱即用,但一种方法是以大纲颜色渲染文本,并将其多次移动到结果曲面,然后以所需颜色渲染文本

使用这种技术;其代码的精简版本如下所示:

import pygame

_circle_cache = {}
def _circlepoints(r):
    r = int(round(r))
    if r in _circle_cache:
        return _circle_cache[r]
    x, y, e = r, 0, 1 - r
    _circle_cache[r] = points = []
    while x >= y:
        points.append((x, y))
        y += 1
        if e < 0:
            e += 2 * y - 1
        else:
            x -= 1
            e += 2 * (y - x) - 1
    points += [(y, x) for x, y in points if x > y]
    points += [(-x, y) for x, y in points if x]
    points += [(x, -y) for x, y in points if y]
    points.sort()
    return points

def render(text, font, gfcolor=pygame.Color('dodgerblue'), ocolor=(255, 255, 255), opx=2):
    textsurface = font.render(text, True, gfcolor).convert_alpha()
    w = textsurface.get_width() + 2 * opx
    h = font.get_height()

    osurf = pygame.Surface((w, h + 2 * opx)).convert_alpha()
    osurf.fill((0, 0, 0, 0))

    surf = osurf.copy()

    osurf.blit(font.render(text, True, ocolor).convert_alpha(), (0, 0))

    for dx, dy in _circlepoints(opx):
        surf.blit(osurf, (dx + opx, dy + opx))

    surf.blit(textsurface, (opx, opx))
    return surf

def main():
    pygame.init()

    font = pygame.font.SysFont(None, 64)

    screen = pygame.display.set_mode((350, 100))
    clock = pygame.time.Clock()

    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
        screen.fill((30, 30, 30))

        screen.blit(render('Hello World', font), (20, 20))

        pygame.display.update()
        clock.tick(60)

if __name__ == '__main__':
    main()
导入pygame
_圈_缓存={}
def_回路点(r):
r=int(圆形(r))
如果r在循环缓存中:
返回循环缓存[r]
x、 y,e=r,0,1-r
_圆形缓存[r]=点=[]
当x>=y时:
点。附加((x,y))
y+=1
如果e<0:
e+=2*y-1
其他:
x-=1
e+=2*(y-x)-1
点数+=[(y,x)表示x,如果x>y,则表示点中的y]
点+=[(-x,y)表示x,y表示x时的点]
点+=[(x,-y)表示x,y表示点,如果是y]
points.sort()
返回点
def render(文本、字体、gfcolor=pygame.Color('dodgerblue')、ocolor=(255、255、255)、opx=2):
textsurface=font.render(text,True,gfcolor).convert_alpha()
w=textsurface.get_width()+2*opx
h=font.get_height()
osurf=pygame.Surface((w,h+2*opx)).convert_alpha()
osurf.填充((0,0,0,0))
surf=osurf.copy()
blit(font.render(text,True,ocolor).convert_alpha(),(0,0))
对于dx,dy in_圆点(opx):
冲浪板(osurf,(dx+opx,dy+opx))
冲浪板(textsurface,(opx,opx))
回浪
def main():
pygame.init()
font=pygame.font.SysFont(无,64)
screen=pygame.display.set_模式((350100))
clock=pygame.time.clock()
尽管如此:
events=pygame.event.get()
对于事件中的e:
如果e.type==pygame.QUIT:
回来
屏幕填充((30,30,30))
blit(呈现('helloworld',字体),(20,20))
pygame.display.update()
时钟滴答(60)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

如果您是初学者,不需要非常复杂的代码,并且只使用简单的字体,如arial、helvetica、calibri等。。。 您只需在“角落”中以轮廓颜色闪烁文本4次,然后在其上闪烁实际文本:

white = pygame.Color(255,255,255)
black = pygame.Color(0,0,0)

def draw_text(x, y, string, col, size, window):
    font = pygame.font.SysFont("Impact", size )
    text = font.render(string, True, col)
    textbox = text.get_rect()
    textbox.center = (x, y)
    window.blit(text, textbox)

x = 300
y = 300

# TEXT OUTLINE

# top left
draw_text(x + 2, y-2 , "Hello", black, 40, win)
# top right
draw_text(x +2, y-2 , "Hello", black, 40, win)
# btm left
draw_text(x -2, y +2 , "Hello", black, 40, win)
# btm right
draw_text(x-2, y +2 , "Hello", black, 40, win) 

# TEXT FILL

draw_text(x, y, "Hello", white, 40, win)

如果您是一个初学者,不需要非常复杂的代码,并且只使用简单的字体,如arial、helvetica、calibri等。。。 您只需在“角落”中以轮廓颜色闪烁文本4次,然后在其上闪烁实际文本:

white = pygame.Color(255,255,255)
black = pygame.Color(0,0,0)

def draw_text(x, y, string, col, size, window):
    font = pygame.font.SysFont("Impact", size )
    text = font.render(string, True, col)
    textbox = text.get_rect()
    textbox.center = (x, y)
    window.blit(text, textbox)

x = 300
y = 300

# TEXT OUTLINE

# top left
draw_text(x + 2, y-2 , "Hello", black, 40, win)
# top right
draw_text(x +2, y-2 , "Hello", black, 40, win)
# btm left
draw_text(x -2, y +2 , "Hello", black, 40, win)
# btm right
draw_text(x-2, y +2 , "Hello", black, 40, win) 

# TEXT FILL

draw_text(x, y, "Hello", white, 40, win)

我不知道它是如何工作的,因为我是一个初学者,但它工作得非常完美!正如我所想。然而,信的下半部分看起来有点剪。不多,只是一点点。这可能是我的字体的问题,但在我正常渲染时不是这样的。你知道为什么会这样吗?你用哪种字体?嗯,这是我的字体的问题。现在我用的是另一种字体,所以没关系。我不知道这是怎么回事,因为我是个初学者,但它很好用!正如我所想。然而,信的下半部分看起来有点剪。不多,只是一点点。这可能是我的字体的问题,但在我正常渲染时不是这样的。你知道为什么会这样吗?你用哪种字体?嗯,这是我的字体的问题。现在我用的是另一种字体,所以没关系。这或多或少是一种攻击。正如您所说,对于简单字体,它可能可以正常工作,但您仍然可以在各种副本的角落中看到这一点。因此,即使本质上很简单,我也不推荐这种解决方案。这或多或少是一种黑客行为。正如您所说,对于简单字体,它可能可以正常工作,但您仍然可以在各种副本的角落中看到这一点。因此,即使本质上很简单,我也不推荐这种解决方案。