我正在努力重写一段工作代码 - 我以更面向对象的方式编写,并且不知道如何将字体(显示位置)附加到3个移动的部分。换句话说,当我移动那些rects时,我希望将数字与其位置相关联。 强烈建议任何改进此代码的建议。
import sys
import pygame as pg
WIDTH = 800
HEIGHT = 600
WHITE = (255, 255, 255)
SCREEN = pg.display.set_mode((WIDTH, HEIGHT))
clock = pg.time.Clock()
pg.font.init()
class Rectangle(pg.sprite.Sprite):
def __init__(self, color, width, height, x , y):
super().__init__()
self.width = width
self.height = height
self.color = color
self.image = pg.Surface((width, 3*140 + height),pg.SRCALPHA)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
for z in range(0, 3 * 140, 140):
pg.draw.rect(self.image, color, (0, z, self.width, self.height))
def draw(self, screen):
screen.blit(self.image, self.rect)
return int(self.rect.y)
def update(self):
self.rect.y += event.rel[1]
def rect_y(self):
return self.rect.y
class Font(Rectangle):
def __init__(self, color, width, height, x , y):
super().__init__( color, width, height, x , y)
self.font_a = pg.font.Font(None, 20)
self.text = self.font_a.render(str(abs(int(object1.rect_y()))), True, (0,0,0))
self.text_rect = self.text.get_rect()
self.text_rect.y = Rectangle.rect_y(self)
object1 = Rectangle((50,100,100), 30, 100, 110 , 120)
selected1 = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEBUTTONDOWN:
if object1.rect.collidepoint(event.pos):
selected1 = True
elif event.type == pg.MOUSEBUTTONUP:
selected1 = False
elif event.type == pg.MOUSEMOTION:
if selected1:
object1.update()
SCREEN.fill(WHITE)
font1 = Font((50,100,100), 30, 100, 110 , 120)
SCREEN.blit(font1.text, font1.rect)
object1.draw(SCREEN)
pg.display.update()
clock.tick(60)
if __name__ == '__main__':
pg.init()
pg.quit()
sys.exit()
答案 0 :(得分:1)
我将Font
个对象(我将该类重命名为Label
)作为属性添加到Rectangle
个实例中。如果您需要多个标签,可以将它们放入列表中。我提供了Rectangle
handle_event
方法,我将MOUSEMOTION
事件传递给我以更新其self.rect
,然后矩形将事件传递给其标签,以便他们可以更新他们的立场。
要存储精灵实例,您可以使用pygame.sprite.Group
(示例中为all_sprites
),它允许您通过调用all_sprites.update()
和all_sprites.draw(SCREEN)
来更新所有包含的精灵。 all_sprites.update()
在这种情况下实际上没用,因为精灵没有update
方法(我只是想告诉你应该如何在主循环中调用它)。
import pygame as pg
pg.init()
WHITE = (255, 255, 255)
SCREEN = pg.display.set_mode((800, 600))
FONT_A = pg.font.Font(None, 20)
clock = pg.time.Clock()
class Rectangle(pg.sprite.Sprite):
def __init__(self, color, width, height, x, y, all_sprites):
super().__init__()
self.color = color
self.image = pg.Surface((width, 3*140 + height), pg.SRCALPHA)
self.rect = self.image.get_rect(topleft=(x, y))
# If you need multiple labels, you can put them into a list.
# You could also create and add them in the for loop below.
self.labels = [Label(self.rect.right+3, self.rect.top, (0,0,0)),
Label(self.rect.right+3, self.rect.top+140, (0,0,0))]
all_sprites.add(self.labels)
for z in range(0, 3*140, 140):
pg.draw.rect(self.image, color, (0, z, width, height))
def handle_event(self, event):
self.rect.y += event.rel[1]
# Pass the event to the labels, so that they can handle it themselves.
for label in self.labels:
label.handle_event(event)
class Label(pg.sprite.Sprite):
def __init__(self, x, y, color):
super().__init__()
self.color = color
self.image = FONT_A.render(str(abs(y)), True, self.color)
self.rect = self.image.get_rect(topleft=(x, y))
def handle_event(self, event):
self.rect.y += event.rel[1]
self.image = FONT_A.render(str(abs(self.rect.y)), True, self.color)
def main():
# Create a sprite group which will contain all sprite instances.
# To update and draw the sprites you can just call its .update and .draw
# methods.
all_sprites = pg.sprite.Group()
# Pass the group to the Rectangle, because we need to add the labels.
object1 = Rectangle((50,100,100), 30, 100, 110, 120, all_sprites)
all_sprites.add(object1)
selected1 = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEBUTTONDOWN:
if object1.rect.collidepoint(event.pos):
selected1 = True
elif event.type == pg.MOUSEBUTTONUP:
selected1 = False
elif event.type == pg.MOUSEMOTION:
if selected1:
# Pass the event to the object's handle_event method,
# where it uses it to update its rect and labels.
object1.handle_event(event)
all_sprites.update()
SCREEN.fill(WHITE)
all_sprites.draw(SCREEN)
pg.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
pg.quit()
附录:如果所有标签都显示相同的值(在这种情况下是rects的顶部位置),则可以将此值传递给标签实例并将其添加为属性。然后在handle_event
方法中更新它并使用它来渲染字体表面。
class Rectangle(pg.sprite.Sprite):
def __init__(self, color, width, height, x, y, all_sprites):
super().__init__()
self.color = color
self.image = pg.Surface((width, 3*140 + height), pg.SRCALPHA)
self.rect = self.image.get_rect(topleft=(x, y))
# Pass another argument (the `value`) to the labels.
self.labels = [Label(self.rect.right+3, self.rect.top, self.rect.top, (0,0,0)),
Label(self.rect.right+3, self.rect.top+140, self.rect.top, (0,0,0))]
all_sprites.add(self.labels)
for z in range(0, 3*140, 140):
pg.draw.rect(self.image, color, (0, z, width, height))
def handle_event(self, event):
self.rect.y += event.rel[1]
for label in self.labels:
label.handle_event(event)
class Label(pg.sprite.Sprite):
def __init__(self, x, y, value, color):
super().__init__()
self.value = value
self.color = color
self.image = FONT_A.render(str(abs(self.value)), True, self.color)
self.rect = self.image.get_rect(topleft=(x, y))
def handle_event(self, event):
# Update the self.value as well and use it to render the new font surface.
self.value += event.rel[1]
self.rect.y += event.rel[1]
self.image = FONT_A.render(str(abs(self.value)), True, self.color)