gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 04:42:49 25 4
gpt4 key购买 nike

我想将文本 blit 到一个可以移动和重新调整其大小的矩形上。我正在考虑将矩形制作成一个表面,然后将文本 blitting 到表面上,但我不知道该怎么做 :(

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

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)

此外,如果可能的话,任何人都可以帮我解决一下矩形问题,它们似乎能够移出屏幕,如何使屏幕尺寸成为边框并使矩形从边框上弹开?

最佳答案

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

为了 blit 文本表面,我枚举了 self.images,然后将索引乘以字体高度来移动表面。

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)

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

  • 比矩形宽度宽的单词会突出显示。
  • 段落被忽略。
  • 我只是省略了矩形下方的行。
  • 如果您想更改文本,您应该添加一个 getter 和一个 setter 方法或属性,您可以在其中调用 render_text_surfaces 方法来更新表面。

关于python - 将文本添加到可以调整大小的矩形,并在没有插件的情况下在 Pygame 上移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50280553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com