将文本添加到可以调整大小的矩形,并在没有插件的情况下在Pygame上移动

时间:2018-05-10 19:52:46

标签: python python-3.x pygame

我想将文本blit到一个可以移动并重新调整其大小的矩形上。 我正在考虑让矩形成为表面,只是在表面上涂抹文字,但我不知道如何这样做:(

可以移动并且可以调整大小的矩形是:

import pygame as pg

pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
rect1 = pg.Rect(100, 100, 161, 100)
rect2 = pg.Rect(300, 200, 161, 100)
selected_rect = None

done = False
while not done:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            done = True
        elif event.type == pg.MOUSEBUTTONDOWN:
            for rect in (rect1, rect2):
                if rect.collidepoint(event.pos):
                    selected_rect = rect  # Select the colliding rect.
        elif event.type == pg.MOUSEBUTTONUP:
            selected_rect = None  # De-select the rect.
        elif event.type == pg.MOUSEMOTION:
            if selected_rect is not None:  # If a rect is selected.
                if event.buttons[0]:  # Left mouse button is down.
                    # Move the rect.
                    selected_rect.x += event.rel[0]
                    selected_rect.y += event.rel[1]
                else:  # Right or middle mouse button.
                    # Scale the rect.
                    selected_rect.w += event.rel[0]
                    selected_rect.h += event.rel[1]
                    selected_rect.w = max(selected_rect.w, 10)
                    selected_rect.h = max(selected_rect.h, 10)

    screen.fill((30, 30, 30))
    pg.draw.rect(screen, (0, 100, 250), rect1)
    pg.draw.rect(screen, (0, 200, 120), rect2)
    pg.display.flip()
    clock.tick(30)

另外,如果有可能,任何人都可以帮我解决一下矩形,他们似乎能够离开屏幕,怎样才能使屏幕大小成为边框并使矩形从它反弹?

2 个答案:

答案 0 :(得分:2)

这是一个基本的解决方案。我首先将文本分成单独的单词。然后,为了创建行,我将一个词一个接一个地添加到中间列表(line)并使用pygame.font.Font.size方法来获取我添加到{{1}的单词的大小变量。当line_width超出矩形宽度时,我会使用行列表中的字词来呈现文本表面并将其附加到line_width列表。

要对文本曲面进行blit,我枚举self.images,然后将索引乘以字体的高度以移动曲面。

self.images

还有一些事情需要改进,但我把它留给你。例如:

  • 宽于矩形宽度的单词伸出。
  • 段落被忽略。
  • 我只是省略了矩形下方的行。
  • 如果要更改文本,则应添加getter和setter方法或属性,在其中调用import pygame as pg class TextBox: def __init__(self, text, pos, font, bg_color, text_color=(255, 255, 255)): self.font = font self.font_height = font.get_linesize() self.text = text.split() # Single words. self.rect = pg.Rect(pos, (200, 200)) self.bg_color = bg_color self.text_color = text_color self.render_text_surfaces() def render_text_surfaces(self): """Create a new text images list when the rect gets scaled.""" self.images = [] # The text surfaces. line_width = 0 line = [] space_width = self.font.size(' ')[0] # Put the words one after the other into a list if they still # fit on the same line, otherwise render the line and append # the resulting surface to the self.images list. for word in self.text: line_width += self.font.size(word)[0] + space_width # Render a line if the line width is greater than the rect width. if line_width > self.rect.w: surf = self.font.render(' '.join(line), True, self.text_color) self.images.append(surf) line = [] line_width = self.font.size(word)[0] + space_width line.append(word) # Need to render the last line as well. surf = self.font.render(' '.join(line), True, self.text_color) self.images.append(surf) def draw(self, screen): """Draw the rect and the separate text images.""" pg.draw.rect(screen, self.bg_color, self.rect) for y, surf in enumerate(self.images): # Don't blit below the rect area. if y * self.font_height + self.font_height > self.rect.h: break screen.blit(surf, (self.rect.x, self.rect.y+y*self.font_height)) def scale(self, rel): self.rect.w += rel[0] self.rect.h += rel[1] self.rect.w = max(self.rect.w, 30) # 30 px is the minimum width. self.rect.h = max(self.rect.h, 30) self.render_text_surfaces() def move(self, rel): self.rect.move_ip(rel) self.rect.clamp_ip(screen.get_rect()) text = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.""" pg.init() screen = pg.display.set_mode((800, 600)) clock = pg.time.Clock() FONT = pg.font.Font(None, 34) selected_box = None textbox = TextBox(text, (50, 50), FONT, (20, 50, 120)) textbox2 = TextBox(text, (350, 100), pg.font.Font(None, 22), (20, 80, 60)) done = False while not done: for event in pg.event.get(): if event.type == pg.QUIT: done = True elif event.type == pg.MOUSEBUTTONDOWN: for box in (textbox, textbox2): if box.rect.collidepoint(event.pos): selected_box = box # Select the colliding box. elif event.type == pg.MOUSEBUTTONUP: selected_box = None # De-select the box. elif event.type == pg.MOUSEMOTION: if selected_box is not None: # If a box is selected. if event.buttons[0]: # Left mouse button is down. selected_box.move(event.rel) else: selected_box.scale(event.rel) screen.fill((30, 30, 30)) textbox.draw(screen) textbox2.draw(screen) pg.display.flip() clock.tick(60) 方法来更新曲面。

答案 1 :(得分:-1)

我可以推荐pygame-text,它简化了在表面上绘制文字的效果。

给出一个表面:

surface = pg.Surface((200, 100))

您可以轻松添加文字:

import ptext  # Grab the module from Github

ptext.draw("hello world", (20, 100), surf=surface)
screen.get_surface().blit(surface, (10, 10))

以上链接的更多信息。