Есть набросок текста в Pygame - PullRequest
2 голосов
/ 02 апреля 2020

Итак, у меня есть эта функция, в которой он выводит текст на экран:

def text_speech(font : str ,size : int,text : str,color,x,y, bold : bool):
    SCREEN = width, height = 900, 600
    font = pygame.font.Font(font,size)
    font.set_bold(bold)
    text = font.render(text, True, color)
    textRect = text.get_rect()
    textRect.center = (x,y)
    screen.blit(text,textRect)

Если я делаю это:

screen.fill((0,0,0))
text_speed('arialnarrow.ttf', 40, 'Hello', (255,255,255), (width/2), (height/2), False)

Он генерирует мир "Hello" на черном экран с белым текстом. Возможно ли, что если пользователь наводит указатель мыши на это, он создает красный (255,0,0) контур?

Ответы [ 2 ]

2 голосов
/ 02 апреля 2020

Предполагая, что под "контуром" вы подразумеваете обводку, у меня есть простое решение. Просто визуализируйте тот же текст, центрированный вокруг той же позиции, что и текст, который вы уже написали, немного больше и красным. Затем просто проверьте, когда мышь наводит курсор на прямоугольник вашего исходного текста, и, если это так, перетащите контур.

Чтобы сделать это, нам нужно извлечь прямоугольник вашего первого текста. Я изменил вашу функцию так, чтобы она выводила визуализированную поверхность и прямоугольную.

Я также сделал несколько других корректировок:

  • Вам не нужно генерировать font и визуализировать текст каждый раз, это приводит к потере циклов ЦП. Я рекомендую устанавливать каждый из ваших шрифтов как глобальные константы, для каждого размера / шрифта
  • Вы определяете screen в своей функции, но никогда не используете его. Я изменил функцию, чтобы она больше не выполняла рендеринг.
  • Когда вы вызываете text_speech (я предполагаю, что ваше второе использование - опечатка), width и height не относятся к что-нибудь. Я также определил их как глобальные константы, которые я установил в качестве размера вашего дисплея.

Вы не включили никакого кода дисплея, поэтому я написал минимум для работающей концепции.

import pygame

pygame.init()

# Font constants
ARIALNARROW_40 = font = pygame.font.Font('arialnarrow.ttf', 40)
ARIALNARROW_42 = font = pygame.font.Font('arialnarrow.ttf', 42)

# Screen size
WIDTH = 900
HEIGHT = 600

def text_speech(font, text, color, x, y, bold):
    font.set_bold(bold)
    rendered_text = font.render(text, True, color)

    # Directly center the rect upon its creation
    text_rect = rendered_text.get_rect(center=(x,y))
    return text_rect, rendered_text

screen = pygame.display.set_mode((WIDTH, HEIGHT))

inner_rect, inner_text = text_speech(
    ARIALNARROW_40, 'Hello', (255, 255, 255),
    (WIDTH / 2), (HEIGHT / 2), False
)

# For your outline
outline_rect, outline_text = text_speech(
    ARIALNARROW_42, 'Hello', (255, 0, 0),
    (WIDTH / 2), (HEIGHT / 2), False
)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()


    # Paint our screen
    screen.fill((0,0,0))

    if inner_rect.collidepoint(pygame.mouse.get_pos()):
        # Touching our text! Render outline
        screen.blit(outline_text, outline_rect)

    screen.blit(inner_text, inner_rect)


    # Enact our display changes
    pygame.display.update()

Примечание Это действительно добавляет потенциально нежелательное воздействие "бокового увеличения". Однако обойти это означало бы, что вам придется либо возиться с кернингом шрифта (с модулем pygame.freetype), но это может очень быстро запутаться, либо вы можете заранее визуализировать изображение обводки (и стереть его, используя тот же лог c, который я использовал), но для этого вам потребуется каждый раз изменять текст для всех ваших текстовых поверхностей.

2 голосов
/ 02 апреля 2020

Чтобы выполнить sh набросок, вам нужно несколько раз нажать. Визуализируйте текст в цвете контура (красный):

outlineSurf = font.render(text, True, (255, 0, 0))
outlineSize = outlineSurf.get_size()

Создайте поверхность, которая терше, чем поверхность текста. Ширина и высота должны быть увеличены на удвоенную толщину контура:

textSurf = pygame.Surface((outlineSize[0] + outline*2, outlineSize[1] + 2*outline))
textRect = textSurf.get_rect()

Поверните поверхность контура 8 раз на текстовой поверхности, сдвинув ее на толщину контура (по горизонтали, вертикали и диагонали:

offsets = [(ox, oy) 
    for ox in range(-outline, 2*outline, outline)
    for oy in range(-outline, 2*outline, outline)
    if ox != 0 or ox != 0]
for ox, oy in offsets:   
    px, py = textRect.center
    textSurf.blit(outlineSurf, outlineSurf.get_rect(center = (px+ox, py+oy))) 

Визуализация текста с цветом текста и преобразование поверхности в альфа-формат на пиксель (convert_alpha):

innerText = font.render(text, True, color).convert_alpha()

Блит текст в середине textSurf:

textSurf.blit(innerText, innerText.get_rect(center = textRect.center)) 

Blit textSurf на окно:

textRect.center = (x,y)
screen.blit(textSurf, textRect)

См. Пример:

import pygame
import pygame.font

pygame.init()

width, height = 400, 300
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
textRect = pygame.Rect(0, 0, 0, 0)

def text_speech(font : str, size : int, text : str, color, x, y, bold : bool, outline: int):
    global textRect 
    # font = pygame.font.Font(font,size)
    font = pygame.font.SysFont(None, size)
    font.set_bold(True)
    if outline > 0:
        outlineSurf = font.render(text, True, (255, 0, 0))
        outlineSize = outlineSurf.get_size()
        textSurf = pygame.Surface((outlineSize[0] + outline*2, outlineSize[1] + 2*outline))
        textRect = textSurf.get_rect()
        offsets = [(ox, oy) 
            for ox in range(-outline, 2*outline, outline)
            for oy in range(-outline, 2*outline, outline)
            if ox != 0 or ox != 0]
        for ox, oy in offsets:   
            px, py = textRect.center
            textSurf.blit(outlineSurf, outlineSurf.get_rect(center = (px+ox, py+oy))) 
        innerText = font.render(text, True, color).convert_alpha()
        textSurf.blit(innerText, innerText.get_rect(center = textRect.center)) 
    else:
        textSurf = font.render(text, True, color)
        textRect = textSurf.get_rect()    

    textRect.center = (x,y)
    screen.blit(textSurf, textRect)

run = True
while run:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    hover = textRect.collidepoint(pygame.mouse.get_pos())
    outlineSize = 3 if hover else 0 

    screen.fill((0,0,0))
    text_speech('arialnarrow.ttf', 40, 'Hello', (255,255,255), (width/2), (height/2), False, outlineSize)
    pygame.display.flip()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...