如何将文本输出到屏幕,同时还输出面向对象的按钮 - Pygame

时间:2017-11-13 10:37:55

标签: python oop pygame

#Importing Modules
import pygame
import sys
import random

#All pygame stuff under here
pygame.init()

#Font definitions
backFont = pygame.font.SysFont("monospace",40)
titleFont = pygame.font.SysFont("garamond", 100)
buttonFont = pygame.font.SysFont("garamond", 25)
bigFont = pygame.font.SysFont("garamond",100)

#Colour definitions
BackGray = pygame.Color('gray60')
screenGray = pygame.Color('gray80')
buttonGray1 = pygame.Color('gray40')
buttonGray2 = pygame.Color('gray50')
buttonGray3 = pygame.Color('gray30')
textColour = pygame.Color('navy')

#Screen size set
screen = pygame.display.set_mode((800, 600))

#Class for the buttons set here
class Button:
    def __init__(self, x, y, width, height, colour, surface):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.colour = colour
        self.surface = surface

    def isPressed(self):
        mouse_position = pygame.mouse.get_pos()
        mouse_x = mouse_position[0]
        mouse_y = mouse_position[1]
        if mouse_x > self.x:
            if mouse_x < self.x + self.width:
                if mouse_y > self.y:
                    if mouse_y < self.y + self.height:
                        mouse_click = pygame.mouse.get_pressed()
                        left_click = mouse_click[0]
                        if left_click:
                            self.colour = (0,0,0)
                            return True
        self.colour = (230, 230, 230)
        return False

    def drawButton(self):
        pygame.draw.rect(self.surface, self.colour,  (self.x, self.y, self.width, self.height))
        pygame.display.flip()

def FrontPage():
    #Back screen
    screen.fill(screenGray)

    #The background is defined here
    BinaryPage = []
    for i in range(0,15):
        BinaryString = ""
        for j in range(0,33):
            BinaryString += random.choice(["0","1"])
        BinaryPage.append(BinaryString)

    for i in range(0,15):
        screen.blit(backFont.render(BinaryPage[i], 1, BackGray), (0,i * 40))

    #The title is defined and printed here
    Title1 = titleFont.render("The Six", 10, textColour)
    Title2 = titleFont.render("Cipher", 10, textColour)
    Title3 = titleFont.render("Simulator", 10, textColour)
    screen.blit(Title1, (100, 100))
    screen.blit(Title2, (100, 200))
    screen.blit(Title3, (100, 300))

    #Text for the button
    buttonText = buttonFont.render("Continue", 10, textColour)
    screen.blit(buttonText, (115,405))

    #Where the buttons are defined and drawn
    ButtonBig = Button(100, 450, 120, 60, buttonGray1, screen)
    ButtonSmall = Button(105, 455, 110, 50, buttonGray2, screen)
    ButtonBig.drawButton()
    ButtonSmall.drawButton()


    #Pygame While loop
    clock = pygame.time.Clock()
    while True:
        for event in pygame.event.get():
            if ButtonBig.isPressed():
                print("Hello")
                break
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        clock.tick(60)

上面的代码运行一个以随机顺序为0和1的窗口作为背景,我的程序标题位于中间。

然后,底部应该有一个按钮,或者是灰色矩形。但是,当我尝试.blit,或在按钮框架上打印某些东西时,在我将按钮绘制到屏幕上之后,它就不会出现。

有人可以告诉我为什么以及如何解决这个问题? 或者如何将文本输出到按钮上的任何替代方案。

提前致谢

1 个答案:

答案 0 :(得分:1)

我首先要创建一个单独的background曲面,然后将所有背景图形都搞定,这些图形永远不会改变到它上面(以下示例中的数字)。在主循环中,您可以只显示此背景以清除屏幕。

将文字blit到按钮上:

  1. 将文字传递给__init__方法
  2. 创建按钮图像(pygame.Surface)
  3. 渲染文字
  4. 为图像和文本创建rects(将图像rect的中心传递到文本rect以使文本居中)
  5. 将文本表面blit到图像上。
  6. 对于按钮,我使用sprites并将它们放入精灵组,这样您只需拨打sprite_group.draw(screen)即可绘制它们。 Sprite需要imagerect属性才能工作。 Pygame rects有碰撞检测方法,您应该使用它而不是编写自己的方法。在这种情况下,我们可以使用collidepoint方法并将event.pos传递给它。

    import random
    import pygame as pg
    
    
    pg.init()
    
    screen = pg.display.set_mode((800, 600))
    
    FONT = pg.font.SysFont('garamond', 25)
    SCREEN_GRAY = pg.Color('gray80')
    BUTTON_GRAY = pg.Color('gray40')
    TEXT_COLOUR = pg.Color('navy')
    
    
    # Inherit from pg.sprite.Sprite. That will allow you to
    # put the instances into a sprite group.
    class Button(pg.sprite.Sprite):
    
        def __init__(self, text, x, y, width, height, colour):
            super().__init__()
            # Create the image of the button.
            self.image = pg.Surface((width, height))
            self.image.fill(colour)
            # A pygame.Rect will serve as the blit position.
            self.rect = self.image.get_rect()
            # Render the text.
            txt = FONT.render(text, True, TEXT_COLOUR)
            # This txt_rect is used to center the text on the image.
            txt_rect = txt.get_rect(center=self.rect.center)
            self.image.blit(txt, txt_rect)
            # Set the position of the image rect.
            self.rect.topleft = x, y
    
        def is_pressed(self, event):
            if event.type == pg.MOUSEBUTTONDOWN:
                # MOUSE... events have an event.pos attribute (the mouse position)
                # which you can pass to the collidepoint method of the rect.
                if self.rect.collidepoint(event.pos):
                    return True
            return False
    
    
    def main():
        button_big = Button('big button', 100, 250, 120, 60, BUTTON_GRAY)
        button_small = Button('small button', 105, 455, 120, 50, BUTTON_GRAY)
        buttons_group = pg.sprite.Group(button_big, button_small)
    
        background = pg.Surface(screen.get_size())
        background.fill(SCREEN_GRAY)
    
        for i in range(screen.get_height()//40):
            for j in range(screen.get_width()//40):
                n = random.choice(['0', '1'])
                background.blit(FONT.render(n, True, BUTTON_GRAY), (j*40, i*40))
    
        clock = pg.time.Clock()
        while True:
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    return
                if button_big.is_pressed(event):
                    print('big')
                elif button_small.is_pressed(event):
                    print('small')
    
            screen.blit(background, (0, 0))
            # Blit the images of the contained sprites onto the screen.
            buttons_group.draw(screen)
    
            pg.display.flip()
            clock.tick(60)
    
    
    if __name__ == '__main__':
        main()
        pg.quit()