【问题标题】:PyGame Text Under The Button按钮下的 PyGame 文本
【发布时间】:2020-03-11 05:49:27
【问题描述】:

我的代码有问题,尤其是 pygame 和按钮

最初,我是手动添加按钮,但我决定使用类来代替。 但是,文本显示在我的按钮下方,而不是在按钮上方。

如何让文本显示在按钮顶部?

这是我的代码:

import pygame as P
import sys

P.init()

class MENU():
    def __init__(self, BUTTON_COUNT, WINDOW, RESOLUTION, BUTTON_WIDTH, BUTTON_HEIGHT, BUTTON_PADDING_X, BUTTON_PADDING_Y):
        self.WINDOW = WINDOW
        self.BUTTON_COUNT = BUTTON_COUNT
        self.RESOLUTION = RESOLUTION
        self.BUTTON_WIDTH = BUTTON_WIDTH
        self.BUTTON_HEIGHT = BUTTON_HEIGHT
        self.BUTTON_PADDING_X = BUTTON_WIDTH + BUTTON_PADDING_X
        self.BUTTON_PADDING_Y = BUTTON_HEIGHT + BUTTON_PADDING_Y

        self.SETTINGS_ON = True
        self.ONCE = False
        self.FPS = P.time.Clock()

        while self.SETTINGS_ON:
            self.FPS.tick(30)
            self.WINDOW.fill((0, 0, 0))

            self.CENTER_X = RESOLUTION[0]//2
            self.CENTER_Y = RESOLUTION[1]//2

            self.TITLE_FONT = P.font.SysFont("calibri", 75)
            self.MESSAGE_FONT = P.font.SysFont("calibri", 20)
            self.BUTTON_FONT = P.font.SysFont("calibri", 25)

            if self.ONCE == False:
                self.CREATE_BUTTONS((127, 127, 127), (191, 191, 191), ("BUTTON 1", "BUTTON 2", "BUTTON 3"))
                self.ONCE = True
            if self.ONCE == True:
                self.VIEW_BUTTONS()


            event = P.event.wait()
            if event.type == P.KEYDOWN and event.key == P.K_RETURN:
                self.SETTINGS_ON = False

            if event.type == P.MOUSEMOTION:
                for i in range(0, self.BUTTON_COUNT):
                    if vars(self)["BTN"+str(i+1)+"_RECT"].collidepoint(event.pos):
                        vars(self)["BTN"+str(i+1)+"_CX"] = vars(self)["BTN"+str(i+1)+"_C1"]
                    else:
                        vars(self)["BTN"+str(i+1)+"_CX"] = vars(self)["BTN"+str(i+1)+"_C2"]

            if event.type == P.MOUSEBUTTONDOWN:
                for i in range(0, self.BUTTON_COUNT):
                    if vars(self)["BTN"+str(i+1)+"_RECT"].collidepoint(event.pos):
                        print("BUTTON CLICK")

            P.display.update()

    def CENTER_IT(self, text):
        self.CENTERED = (self.CENTER_X-text.get_width()//2, self.CENTER_Y-text.get_height()//2)

    def CREATE_BUTTONS(self, COLOR1, COLOR2, TEXTS):
        for i in range(0, self.BUTTON_COUNT):
            vars(self)["BTN"+str(i+1)+"_CX"] = COLOR1
            vars(self)["BTN"+str(i+1)+"_C1"] = COLOR1
            vars(self)["BTN"+str(i+1)+"_C2"] = COLOR2
            vars(self)["BTN"+str(i+1)+"_RECT"] = P.Rect(self.CENTER_X-self.BUTTON_WIDTH//2, self.CENTER_Y-self.BUTTON_HEIGHT//2-self.BUTTON_PADDING_Y*(i-1), self.BUTTON_WIDTH, self.BUTTON_HEIGHT)
            vars(self)["BTN"+str(i+1)+"_TEXT"] = self.BUTTON_FONT.render(TEXTS[i], True, (255, 255, 255))
    def VIEW_BUTTONS(self):
        for i in range(0, self.BUTTON_COUNT):
            P.draw.rect(self.WINDOW, vars(self)["BTN"+str(i+1)+"_CX"], vars(self)["BTN"+str(i+1)+"_RECT"])
            self.CENTER_IT(vars(self)["BTN"+str(i+1)+"_TEXT"])
            self.WINDOW.blit(vars(self)["BTN"+str(i+1)+"_TEXT"], (self.CENTERED[0], self.CENTERED[1]+self.BUTTON_PADDING_Y*(i-1)))


class MainWindow():
    def __init__(self):
        self.RESOLUTION = (1024, 768)
        self.WINDOW = P.display.set_mode(self.RESOLUTION)
        self.Variables()
        self.Main()

    def Variables(self):
        self.GAMEMODE = -1
        self.ONCE = False
        self.FPS = P.time.Clock()

    def Main(self):
        while True:
            self.FPS.tick(30)
            if self.GAMEMODE == -1:
                if self.ONCE == False:
                    SETTINGS = MENU(3, self.WINDOW, self.RESOLUTION, 168, 64, 10, 10)
                    self.GAMEMODE = 2

            if self.GAMEMODE != -1:
                self.ONCE = False

            P.display.update()

            event = P.event.wait()

if __name__ == '__main__':
    MainWindow()

P.quit()
exit()

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    因为这是你的全部代码,为了方便我们两个部分,我将只演示如何创建一个带有文本的按钮

    您可以使用freetype module

    import pygame
    import pygame.freetype # you have to do this import explicitly
    

    你创建一个字体对象

    my_font = pygame.freetypeFont(name='Arial', size=24) 
    

    然后您可以渲染它以创建文本表面以及具有相同大小的矩形

    txt_surface, txt_rect = my_font.render(text='Press this Button', 
                                           fgcolor=pg.Color('Black'))
    

    如果您有一个具有图像和 rect 属性的 Button 对象(它确实应该),那么您可以使用 txt_rect 对齐中心,然后在按钮的图像上进行 blit 处理

    txt_rect.center = my_button.rect.center
    my_button.image.blit(txt_surface, txt_rect)
    

    这样,带有“Press this Button”的文本表面就会被绘制到按钮的图像上。

    【讨论】:

    • 但这并不能真正帮助用户。或许你应该考虑在他的代码中定位错误。
    【解决方案2】:

    问题在于函数MENU.CENTER_IT()。它使屏幕上的按钮文本相对于文本图像高度居中,在按钮位置上。

    我修改了这个函数以将按钮矩形作为参数,并让它计算相对于该矩形的居中位置:

    def CENTER_IT(self, butt_rect, text):
        #self.CENTERED = (self.CENTER_X-text.get_width()//2, self.CENTER_Y-text.get_height()//2)
        # Centre text over the top of button rectangle
        text_x = butt_rect.x + ( ( butt_rect.width  - text.get_width() )  // 2 )
        text_y = butt_rect.y + ( ( butt_rect.height - text.get_height() ) // 2 )
        self.CENTERED = ( text_x, text_y )
    

    那么MENU.VIEW_BUTTONS()中的调用代码需要将按钮矩形传入修改后的居中函数:

    def VIEW_BUTTONS(self):
        for i in range(0, self.BUTTON_COUNT):
            P.draw.rect(self.WINDOW, vars(self)["BTN"+str(i+1)+"_CX"], vars(self)["BTN"+str(i+1)+"_RECT"])
            self.CENTER_IT(vars(self)["BTN"+str(i+1)+"_RECT"], vars(self)["BTN"+str(i+1)+"_TEXT"])
            self.WINDOW.blit(vars(self)["BTN"+str(i+1)+"_TEXT"], ( self.CENTERED[0], self.CENTERED[1] ) )
    

    这解决了问题。

    使用 python vars 功能在运行时创建新变量会使代码更难阅读和调试。这些值最好存储在简单的数据结构中,如列表或“按钮”类。

    您的代码未处理 pygame.QUIT 事件。

    【讨论】:

      【解决方案3】:

      我已尝试运行您的代码,据我了解,您在画布上绘制文本和按钮的方式似乎存在问题。

      图像在更改此行时反映了画布 self.WINDOW.blit(vars(self)["BTN"+str(i+1)+"_TEXT"], (self.CENTERED[0], self.CENTERED[1]+self.BUTTON_PADDING_Y*(i-1)+150))

      所以这告诉我按钮 1,2 是在文本之后创建的,因此被放置在文本的顶部。您应该调试您的代码并了解如何应用所有内容。然后,您可以轻松找到错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-24
        • 2020-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多