soft-summer-2021 / summer2021

程序设计实践 (2021夏季学期)
31 stars 6 forks source link

pygame 文字显示异常 #65

Closed hrQAQ closed 2 years ago

hrQAQ commented 2 years ago

想要做一个button在窗口变换大小是在窗口的相对比例不变 将原代码修改为注释部分代码后无法出现文字对象 怀疑是pos_x和pos_y为生命周期引起的?但不知道怎么改

代码如下

import pygame

pygame.init()

# window define
TableSize = [1200, 600]
Window = pygame.display.set_mode(TableSize, pygame.RESIZABLE)

# Color define
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)

# img define
Start_bg = 'Start_bg.png'
Game_bg = 'Game_bg.png'

# font define
font_addr = pygame.font.get_default_font()
font_1 = pygame.font.Font(font_addr, 36)

def GetSize():
    infoobject = pygame.display.Info()
    TableSize = (infoobject.current_w, infoobject.current_h)
    return TableSize

# botton class
# x, y indicate the pos of botton(propotion)
class Button(object):
    def __init__(self, text, color, font, x=None, y=None):
        self.surface = font.render(text, True, color)
        self.WIDTH = self.surface.get_width()
        self.HEIGHT = self.surface.get_height()
        self.x = x
        self.y = y

    def display(self):
        # pos_x = int(TableSize[0] * self.x - self.WIDTH / 2)
        # pos_y = int(TableSize[0] * self.y - self.HEIGHT / 2)
        # Window.blit(self.surface, pos_x, pos_y)
        Window.blit(self.surface, (self.x, self.y))  # 原代码

    def check_click(self, position):
        Sign = False
        x_match = position[0] > self.x and position[0] < self.x + self.WIDTH
        y_match = position[1] > self.y and position[1] < self.y + self.HEIGHT
        if x_match and y_match:
            Sign = True
        else:
            Sign = False
        return Sign

class Screen():
    def __init__(self, img):
        self.surface = pygame.image.load(img)

    # window -->the bg screen
    def display(self):
        Window = pygame.display.set_mode(GetSize(), pygame.RESIZABLE)
        Window.blit(pygame.transform.scale(self.surface, GetSize()), (0, 0))
        return self.surface

# Start page
start_screen = Screen(Start_bg)
play_button = Button('Play', WHITE, font_1, 0.667, 0.583)
exit_button = Button('Exit', WHITE, font_1, 0.667, 0.667)
play_button.display()
exit_button.display()

while True:

    if play_button.check_click(pygame.mouse.get_pos()):
        play_button = Button('Play', RED, font_1, 0.667, 0.583)
    else:
        play_button = Button('Play', WHITE, font_1, 0.667, 0.583)

    if exit_button.check_click(pygame.mouse.get_pos()):
        exit_button = Button('Exit', RED, font_1, 0.667, 0.667)
    else:
        exit_button = Button('Exit', WHITE, font_1, 0.667, 0.667)

    bgimg = start_screen.display()
    play_button.display()
    exit_button.display()
    pygame.display.update()

    if pygame.mouse.get_pressed()[0]:
        if play_button.check_click(pygame.mouse.get_pos()):
            break
        if exit_button.check_click(pygame.mouse.get_pos()):
            pygame.quit()
            raise SystemExit

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            raise SystemExit
        elif event.type == pygame.VIDEORESIZE:
            TableSize = event.size[0], event.size[1]
            screen = pygame.display.set_mode(TableSize, pygame.RESIZABLE)
            screen.blit(pygame.transform.scale(bgimg, TableSize), (0, 0))
hzy1721 commented 2 years ago
SCREEN_SIZE = (1200, 600)
screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)

class Button:
    def display(self):
        global screen
        pos_x = int(SCREEN_SIZE[0] * self.x - self.WIDTH / 2)
        pos_y = int(SCREEN_SIZE[1] * self.y - self.HEIGHT / 2)
        screen.blit(self.surface, (pos_x, pos_y))

我改成这样可以正常显示 (背景图随便找了张)。

截屏2021-08-27 下午3 50 58
hrQAQ commented 2 years ago

it works for me!!! 错误原因是修改版(注释中)的第二行TableSize的list仍然用的[0],导致文字坐标超出了Window显示范围 (btw外部的screen应该是全局对象吧,大概不需要Global关键字就可以改变screen?)

hzy1721 commented 2 years ago

是的,不写 global 也行。