首页 > 解决方案 > 如何使我的变量在我单击 pygame 中的按钮时仅增加一个,以及如何使文本更新

问题描述

我正在尝试使用 pygame 为学校制作一个空闲的 Clicker 游戏,我遇到了一些问题,我真的很感谢一些帮助

我的程序需要一些帮助,主要是我有两个问题,一个是当我单击“升级磨刀石按钮”时,当变量磨刀石级别上升时,文本不会,并且由于我这样做的方式,我不能只是 blit一些文本在屏幕上,所以我需要一些帮助,其次,当我按下升级按钮并将其打印在屏幕上时,变量 Whetstone Level 上升不止一个,我希望它上升一个级别点击,所以我想知道我能做些什么来改变它,让它只上升一级

提前致谢

import pygame
pygame.init()
pygame.font.init()
colours = {"White" : (255, 255, 255), "Black" : (0, 0, 0), "Red" : (255, 0, 0), "Blue" : (0, 0, 255), "Green" : (0, 255, 0)}
clickdamage = 1
Whetstone_Level = 0

class Screen():
    def __init__(self, title, width=400, height=600, fill=colours["White"]):
        self.title=title
        self.width=width
        self.height = height
        self.fill = fill
        self.current = False
        
    def makeCurrent(self):
        pygame.display.set_caption(self.title)
        self.current = True
        self.screen = pygame.display.set_mode((self.width, self.height))
         
    def endCurrent(self):
        self.current = False
        
    def checkUpdate(self):
        return self.current
    def screenUpdate(self):
        if(self.current):
            self.screen.fill(self.fill)
            
    def returnTitle(self):
        return self.screen
    
class Button():
        def __init__(self, x, y, sx, sy, bcolour, fbcolour, font, fontsize, fcolour, text):
            self.x = x
            self.y = y
            self.sx = sx
            self.sy = sy
            self.bcolour = bcolour
            self.fbcolour = fbcolour
            self.fcolour = fcolour
            self.fontsize = fontsize
            self.text = text
            self.current = False
            self.buttonf = pygame.font.SysFont(font, fontsize)
        def showButton(self, display):
            if(self.current):
                pygame.draw.rect(display, self.fbcolour, (self.x, self.y, self.sx, self.sy))
            else:
                pygame.draw.rect(display, self.bcolour, (self.x, self.y, self.sx, self.sy))
                
            textsurface = self.buttonf.render(self.text, False, self.fcolour)
            display.blit(textsurface, ((self.x + (self.sx/2) - (self.fontsize/2)*(len(self.text)/2) - 5,(self.y + (self.sy/2) -(self.fontsize/2) - 4))))
        def focusCheck(self, mousepos, mouseclick):
            if(mousepos[0] >= self.x and mousepos[0] <= self.x + self.sx and mousepos[1] >= self.y and mousepos[1] <= self.y + self.sy):
                self.current = True
                return mouseclick[0]
            else:
                self.current = False
                return False
class Enemy(pygame.sprite.Sprite):

    def __init__(self, dx, dy, filename):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(filename).convert()

        self.rect = self.image.get_rect()
        self.rect.x = dx
        self.rect.y = dy
      
   

    def draw(self, screen):
        screen.blit(self.image, self.rect)
    
        

menuScreen = Screen("Menu Screen")
screen2 = Screen("Screen 2")

win = menuScreen.makeCurrent()


done = False
font = pygame.font.Font('freesansbold.ttf', 32)

clickdamagelevel = Button(160, 10, 150, 50, colours["Black"], colours["Red"], "arial", 15, colours["White"], str(Whetstone_Level))
clickdamageupgrade = Button(10, 10, 150, 50, colours["Black"], colours["Red"], "arial", 15, colours["White"], "Whetstone")
shopButton = Button(125, 500, 150, 50, colours["Black"], colours["Red"], "arial", 20, colours["White"], "Shop")
DungeonButton = Button(125, 500, 150, 50, colours["Black"], colours["Blue"], "arial", 20, colours["White"], "Dungeon")
hitboxButton = Button(80, 50, 280, 400, colours["White"], colours["Red"], "arial", 20, colours["White"], "")
goblin = Enemy(0 , 20, "images\goblin-resized.png")
goblin2 = Enemy(0 , 20, "images\goblin.jpg")
toggle = False
while not done:
    menuScreen.screenUpdate()
    screen2.screenUpdate()
    mouse_pos = pygame.mouse.get_pos()
    mouse_click = pygame.mouse.get_pressed()
    keys = pygame.key.get_pressed()
    
    if menuScreen.checkUpdate():
        screen2button = shopButton.focusCheck(mouse_pos, mouse_click)
        attack = hitboxButton.focusCheck(mouse_pos, mouse_click)
        hitboxButton.showButton(menuScreen.returnTitle())
        goblin.draw(menuScreen.screen)
        shopButton.showButton(menuScreen.returnTitle())
        if attack:
            print("hitpoints - click damage")
        if screen2button:
            win = screen2.makeCurrent()
            
            menuScreen.endCurrent()
            
    elif screen2.checkUpdate():
        returnm = DungeonButton.focusCheck(mouse_pos, mouse_click)
        DungeonButton.showButton(screen2.returnTitle())
        clickdamageupgrade.showButton(screen2.returnTitle())
        clickdamagelevel.showButton(screen2.returnTitle())
        if clickdamageupgrade.focusCheck(mouse_pos, mouse_click):
            Whetstone_Level += 1
            print(Whetstone_Level)
            clickdamagelevel.showButton(screen2.returnTitle())
        if returnm:
            win = menuScreen.makeCurrent()
            screen2.endCurrent()
    
    for event in pygame.event.get():
        if(event.type == pygame.QUIT):
            done = True
    
    
    pygame.display.update()
    
pygame.quit()

标签: pygame

解决方案


您可以使用 pygame.MOUSEBUTTONDOWN 来注册每次按下鼠标按钮的一次鼠标单击。在您的情况下,您可以使用您的mouse_click按钮变量。将事件循环移到所有 if 语句之前。

    mouse_click = False
    for event in pygame.event.get():
        if(event.type == pygame.QUIT):
            done = True
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_click = True  

    if menuScreen.checkUpdate():
         #...

这也意味着您的foucsCheck成员函数应该返回mouseclick而不是它的下标。

def focusCheck(self, mousepos, mouseclick):
     if(mousepos[0] >= self.x and mousepos[0] <= self.x + self.sx and mousepos[1] >= self.y and mousepos[1] <= self.y + self.sy):
         self.current = True
          return mouseclick #mouseclick[0]

这解决了注册单击的问题。

对于第二个问题,最好只更改文本,但由于您的按钮类不允许这样做,您可以在 Whetstone_Level每次单击时使用更新的变量重新创建按钮。话虽如此,我建议您稍微修改您的课程以促进这一点。

if clickdamageupgrade.focusCheck(mouse_pos, mouse_click):
      clickdamagelevel = Button(160, 10, 150, 50, colours["Black"], colours["Red"], "arial", 15, colours["White"], str(Whetstone_Level))

更新了代码。

import pygame
pygame.init()
pygame.font.init()
colours = {"White" : (255, 255, 255), "Black" : (0, 0, 0), "Red" : (255, 0, 0), "Blue" : (0, 0, 255), "Green" : (0, 255, 0)}
clickdamage = 1
Whetstone_Level = 0

class Screen():
    def __init__(self, title, width=400, height=600, fill=colours["White"]):
        self.title=title
        self.width=width
        self.height = height
        self.fill = fill
        self.current = False

    def makeCurrent(self):
        pygame.display.set_caption(self.title)
        self.current = True
        self.screen = pygame.display.set_mode((self.width, self.height))

    def endCurrent(self):
        self.current = False

    def checkUpdate(self):
        return self.current
    def screenUpdate(self):
        if(self.current):
            self.screen.fill(self.fill)

    def returnTitle(self):
        return self.screen

class Button():
        def __init__(self, x, y, sx, sy, bcolour, fbcolour, font, fontsize, fcolour, text):
            self.x = x
            self.y = y
            self.sx = sx
            self.sy = sy
            self.bcolour = bcolour
            self.fbcolour = fbcolour
            self.fcolour = fcolour
            self.fontsize = fontsize
            self.text = text
            self.current = False
            self.buttonf = pygame.font.SysFont(font, fontsize)
        def showButton(self, display):
            if(self.current):
                pygame.draw.rect(display, self.fbcolour, (self.x, self.y, self.sx, self.sy))
            else:
                pygame.draw.rect(display, self.bcolour, (self.x, self.y, self.sx, self.sy))

            textsurface = self.buttonf.render(self.text, False, self.fcolour)
            display.blit(textsurface, ((self.x + (self.sx/2) - (self.fontsize/2)*(len(self.text)/2) - 5,(self.y + (self.sy/2) -(self.fontsize/2) - 4))))
        def focusCheck(self, mousepos, mouseclick):
            if(mousepos[0] >= self.x and mousepos[0] <= self.x + self.sx and mousepos[1] >= self.y and mousepos[1] <= self.y + self.sy):
                self.current = True
                return mouseclick
            else:
                self.current = False
                return False
class Enemy(pygame.sprite.Sprite):

    def __init__(self, dx, dy, filename):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(filename).convert()

        self.rect = self.image.get_rect()
        self.rect.x = dx
        self.rect.y = dy



    def draw(self, screen):
        screen.blit(self.image, self.rect)



menuScreen = Screen("Menu Screen")
screen2 = Screen("Screen 2")

win = menuScreen.makeCurrent()


done = False
font = pygame.font.Font('freesansbold.ttf', 32)

clickdamagelevel = Button(160, 10, 150, 50, colours["Black"], colours["Red"], "arial", 15, colours["White"], str(Whetstone_Level))
clickdamageupgrade = Button(10, 10, 150, 50, colours["Black"], colours["Red"], "arial", 15, colours["White"], "Whetstone")
shopButton = Button(125, 500, 150, 50, colours["Black"], colours["Red"], "arial", 20, colours["White"], "Shop")
DungeonButton = Button(125, 500, 150, 50, colours["Black"], colours["Blue"], "arial", 20, colours["White"], "Dungeon")
hitboxButton = Button(80, 50, 280, 400, colours["White"], colours["Red"], "arial", 20, colours["White"], "")
goblin = Enemy(0 , 20, "images\goblin-resized.png")
goblin2 = Enemy(0 , 20, "images\goblin.jpg")
toggle = False
while not done:
    menuScreen.screenUpdate()
    screen2.screenUpdate()
    mouse_pos = pygame.mouse.get_pos()
    keys = pygame.key.get_pressed()

    mouse_click = False
    for event in pygame.event.get():
        if(event.type == pygame.QUIT):
            done = True
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_click = True

    if menuScreen.checkUpdate():
        screen2button = shopButton.focusCheck(mouse_pos, mouse_click)
        attack = hitboxButton.focusCheck(mouse_pos, mouse_click)
        hitboxButton.showButton(menuScreen.returnTitle())
        goblin.draw(menuScreen.screen)
        shopButton.showButton(menuScreen.returnTitle())
        if attack:
            print("hitpoints - click damage")
        if screen2button:
            win = screen2.makeCurrent()

            menuScreen.endCurrent()

    elif screen2.checkUpdate():
        returnm = DungeonButton.focusCheck(mouse_pos, mouse_click)
        DungeonButton.showButton(screen2.returnTitle())
        clickdamageupgrade.showButton(screen2.returnTitle())
        clickdamagelevel.showButton(screen2.returnTitle())
        if clickdamageupgrade.focusCheck(mouse_pos, mouse_click):
            Whetstone_Level += 1
            clickdamagelevel = Button(160, 10, 150, 50, colours["Black"], colours["Red"], "arial", 15, colours["White"], str(Whetstone_Level))
            print(Whetstone_Level)
            clickdamagelevel.showButton(screen2.returnTitle())
        if returnm:
            win = menuScreen.makeCurrent()
            screen2.endCurrent()

    pygame.display.update()

pygame.quit()

推荐阅读