所以我正在用python编写一个隐形游戏的代码,我正在使用pygame模块,但这个问题甚至可能与它无关。我在菜单上有一些阶段,我正在采用一种OOP方法(我是OOP的新手,所以请不要讨厌我的代码!),其中会为有播放和退出按钮的菜单生成按钮。然后,将Easy,Medium,Hard和Veteran按钮加载到旧按钮的顶部(以前的按钮失去功能),然后将级别的1、2、3和4按钮再次加载到先前的按钮之上,感。但是,按照我编写代码的方式,我需要一个可变的阶段,其中阶段1是播放和退出,阶段2是难度,阶段3是要传递的方法和类所需的级别编号。不知道如何在不使用全局范围声明变量的情况下做到这一点,这违反了我认为的OOP的目的。那我该怎么办?因为否则代码将只接受输入并通过所有按钮到达末尾。 这是我的代码,至少我需要文本文件才能提供图像。
#Stealth Assassin
import pygame #Imports the pygame module inclulding many in built functions that aids in game design
import time #Imports the time module for which I can implement delays into my program
pygame.init() #Runs pygame
clock = pygame.time.Clock() #Intialises the variable to control the game clock (FPS)
gameDisplay = pygame.display.set_mode((1920,1080),pygame.FULLSCREEN) #Variable which will set the resolution of the game window and put the window into fullscreen mode
pygame.display.set_caption("Stealth Assassin") #Sets the title of the pygame window for the game
class DisplayImage: #This class contains methods required to load images into the game
def __init__(self, filename, xpos, ypos): #Method used to allow the class to intialise attributes
self.filename = filename #Defines filename as the filename attribute passed through
self.xpos = xpos #Defines the x axis positioning of the image as the attribute passed through
self.ypos = ypos #Defines the y axis positioning of the image as the attribute passed through
def LoadImage(self): #This method will load images into the game displaying them
image = pygame.image.load(self.filename+".png") #Image is loaded into the program
gameDisplay.blit(image, (self.xpos,self.ypos)) #Image is displayed to coordinates which were attributes that were defined prior
stage = 1 #Sets the menu as stage 1 which is the play and quit buttons
class Button: #This class contains methods for buttons including display and functionality
def __init__(self, buttonname, buttonx, buttony, buttonwidth, buttonheight, textfile, textx, texty, stage): #Methods used to allow classes to intialise attributes
self.buttonname = buttonname #Defines the name of the button as the attribute passed through
self.buttonx = buttonx #Defines the x axis positioning of the button as the attribute passed through
self.buttony = buttony #Defines the y axis positioning of the button as the attribute passed through
self.buttonwidth = buttonwidth #Defines the width of the button as the attribute passed through
self.buttonheight = buttonheight #Defines the height of the button as the attribute passed through
self.textfile = textfile #Sets the name of the textfile to be called
self.textx = textx #Defines the x axis positioning of the text as the attribute passed through
self.texty = texty #Defines the y axis positioning of the text as the attribute passed through
self.stage = stage #Sets the stage of the menu which has 3 states of play/quit, difficulty and level choice
def createbutton(self): #Method which creates a button for the menu
buttonname = pygame.draw.rect(gameDisplay, (0,0,0), [self.buttonx, self.buttony, self.buttonwidth, self.buttonheight]) #Draws a rectangular button which is black and given the size and coordinates which were attributes
text = pygame.image.load(self.textfile+".png") #Loads the text file into the program
gameDisplay.blit(text, (self.textx,self.texty)) #Displays the text given coordinates
def quitbutton(self): #Method which quits the program if the quit button is clicked
if self.buttonx+self.buttonwidth > mouse[0] > self.buttonx and self.buttony+self.buttonheight > mouse[1] > self.buttony and pressed[0] == 1: #If the button is clicked (regarding its dimensions)
pygame.quit() #Exits pygame
quit() #Quits program
def buttonaction(self): #Method which takes action for the particular button
if self.buttonx+self.buttonwidth > mouse[0] > self.buttonx and self.buttony+self.buttonheight > mouse[1] > self.buttony and pressed[0] == 1: #If the button is clicked (regarding its dimensions)
if self.stage == 1: #If the play/quit buttons are active
EasyButton.createbutton() #Creates and displays the easy button through the button class and its method
MediumButton.createbutton() #Creates and displays the medium button through the button class and its method
HardButton.createbutton() #Creates and displays the hard button through the button class and its method
VeteranButton.createbutton() #Creates and displays the veteran button through the button class and its method
if self.stage == 2: #If the difficulty buttons are active
OneButton.createbutton() #Creates and displays the one button through the button class and its method
TwoButton.createbutton() #Creates and displays the two button through the button class and its method
ThreeButton.createbutton() #Creates and displays the three button through the button class and its method
FourButton.createbutton() #Creates and displays the four button through the button class and its method
if self.buttonname == 'easybutton':
difficulty = 'easy'
if self.buttonname == 'mediumbutton':
difficulty = 'medium'
if self.buttonname == 'hardbutton':
difficulty = 'hard'
if self.buttonname == 'veteranbutton':
difficulty = 'veteran'
print(difficulty)
time.sleep(0.5)
PlayButton = Button('playbutton',133,477,756,223,'PlayText',387,545,1) #Creates play button
QuitButton = Button('quitbutton',133,731,756,223,'QuitText',387,806,None) #Creates quit button
EasyButton = Button('easybutton',127,477,362,223,'EasyText',214,548,2) #Creates easy button
MediumButton = Button('mediumbutton',533,477,362,223,'MediumText',560,548,2) #Creates medium button
HardButton = Button('hardbutton',127,727,362,223,'HardText',214,806,2) #Creates hard button
VeteranButton = Button('veteranbutton',533,727,362,223,'VeteranText',537,806,2) #Creates veteran button
OneButton = Button('onebutton',127,477,362,223,'OneText',287,550,3) #Creates the level 1 button
TwoButton = Button('twobutton',533,477,362,223,'TwoText',693,550,3) #Creates the level 2 button
ThreeButton = Button('threebutton',127,727,362,223,'ThreeText',285,810,3) #Creates the level 3 button
FourButton = Button('fourbutton',533,727,362,223,'FourText',685,810,3) #Creates the level 4 button
PlayButton.createbutton() #Creates the play button through the button class and its method
QuitButton.createbutton() #Creates the play button through the button class and its method
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
mouse = pygame.mouse.get_pos() #Gets the x and y coordinates of the mouse cursor
pressed = pygame.mouse.get_pressed() #Checks if the mouse has been pressed
PlayButton.buttonaction() #Checks if the playbutton needs action
QuitButton.quitbutton() #Checks if the quitbutton needs action
EasyButton.buttonaction() #Checks if the easybutton needs action
MediumButton.buttonaction() #Checks if the mediumbutton needs action
HardButton.buttonaction() #Checks if the hardbutton needs action
VeteranButton.buttonaction() #Checks if the veteranbutton needs action
OneButton.buttonaction() #Checks if the onebutton needs action
TwoButton.buttonaction() #Checks if the twobutton needs action
ThreeButton.buttonaction() #Checks if the threebutton needs action
FourButton.buttonaction() #Checks if the fourbutton needs action
pressed = [0,0,0]
pygame.display.update()
clock.tick(5)
答案 0 :(得分:0)
面向对象设计的原则之一是将对象正在建模/实现的所有方面保留在对象中,而不再需要。这个“按钮”的目的是什么-可以在屏幕上看到,接受用户输入,并向主程序发出状态信号。
因此,就此而言,您的按钮类基本上可以。但是,它包含按钮定义内的内容实际上不是按钮的工作,例如:
def quitbutton(self):
#If the button is clicked (regarding its dimensions)
if self.buttonx+self.buttonwidth > mouse[0] > self.buttonx and self.buttony+self.buttonheight > mouse[1] > self.buttony and pressed[0] == 1:
pygame.quit() #Exits pygame
quit() #Quits program
通用按钮类应该不负责退出程序,只需要单击和取消单击即可。同样,对于在Play + Quit和难度级别按钮集之间切换的代码,这不是按钮的工作。
我认为更好的按钮可以使混乱更简单:
class Button:
def __init__(self, buttonname, buttonx, buttony, buttonwidth, buttonheight, textfile, textx, texty ):
self.buttonname = buttonname # Name of the button
self.buttonx = buttonx # X-axis position
self.buttony = buttony # Y-axis position
self.buttonwidth = buttonwidth # Width of the button
self.buttonheight= buttonheight # Height of the button
self.text_image = pygame.image.load( textfile+".png" ) # Button Label
self.textx = textx # X-axis positioning of the text
self.texty = texty # Y-axis positioning of the text
def drawButton( self, screen ):
""" Paint the button to the screen """
# Black rectangle the size of the button
pygame.draw.rect( screen, (0,0,0), [self.buttonx, self.buttony, self.buttonwidth, self.buttonheight])
# Overlay the button text onto the background
screen.blit( text_image, ( self.textx, self.texty ) )
def mouseIsOver( self, mouse_position ):
""" Returns true if the mouse is within this buttons area """
inside = self.buttonx+self.buttonwidth > mouse_position[0] > self.buttonx and self.buttony+self.buttonheight > mouse_position[1] > self.buttony
return inside
然后在您的主程序中:
PlayButton = Button('playbutton',133,477,756,223,'rock1_64',387,545,1) #Creates play button
QuitButton = Button('quitbutton',133,731,756,223,'rock1_64',387,806,None) #Creates quit button
EasyButton = Button('easybutton',127,477,362,223,'rock1_64',214,548,2) #Creates easy button
MediumButton = Button('mediumbutton',533,477,362,223,'rock1_64',560,548,2)
...
all_buttons = [ PlayButton, QuitButton, EasyButton, MediumButton ]
# Main Loop
while True:
# Handle user-input
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
if event.type == pygame.MOUSEBUTTONUP:
# The mouse button was clicked, was it inside a button?
click_location = pygame.mouse.get_pos()
for b in all_buttons:
if ( b.mouseIsOver( click_location ) ):
print( "Button [%s] pressed" % ( b.buttonname ) )
# Re-paint screen
gameDisplay.fill( BACKGROUND_COLOUR )
for b in all_buttons:
b.drawButton( gameDisplay )
pygame.display.flip()
clock.tick_busy_loop( 60 ) # Limit FPS
pygame.quit()
quit()
否则,Button类可以post
并向PyGame队列发送事件:
(编辑:其中有一个错误,它需要创建要发布的事件,已修复)。
BUTTON_CLICK_EVENT = pygame.USEREVENT + 1
...
class Button ( ... ):
def checkClick( self, mouse_pos ):
""" If the mouse-click is inside our rectangle, post a message to the queue """
if ( self.buttonx+self.buttonwidth > mouse_position[0] > self.buttonx and self.buttony+self.buttonheight > mouse_position[1] > self.buttony ):
pygame.event.post( pygame.event.Event( BUTTON_CLICK_EVENT, { "button_name" : self.buttonname } ) )
...
# Main loop
if event.type == BUTTON_CLICK_EVENT:
print("Clicked "+ event.button_name )
这样做可以将按钮逻辑与程序的其余部分分开,并避免需要全局变量。显然,您需要在按钮组之间进行切换,但这对Button
对象来说不是问题,它应该放在其他地方。也许以ButtonGroup
之类。