#python #python-3.x #class #pygame
#python #python-3.x #класс #pygame
Вопрос:
Я относительно новичок в программировании своих собственных классов на Python. Я работаю над программой, в которой я уже определил 3 класса с 4/5 методами, каждый из которых отлично работает. Но я сталкиваюсь с проблемой с новым в течение часа, и я не могу понять, что я делаю неправильно. На самом деле, метод не работает, даже если не появляется сообщение об ошибке, но если я скопирую и вставлю код метода в мой цикл pygame (где он вызывается), он работает отлично. Вот код моего класса (здесь речь идет о методе .click(self))):
class button:
def __init__(self, window, xpos, ypos, width, height, color = white, text = '', dest = None):
self.xpos = xpos * r
self.ypos = ypos * r
self.width = width * r
self.height = height * r
self.color = color
self.colorBuffer = [color[i] for i in range(3)]
self.window = window
self.hovered = False
self.clicked = False
self.text = text
self.dest = dest
#self.R = color[0]
#self.G = color[1]
#self.B = color[2]
def click(self):
self.clicked = True
if self.dest == None:
pass
else:
currentMenu = self.dest
self.dest.disp()
self.clicked = False
Вот код, в котором вызывается метод (он вызывается, когда программа проверяет, работает ли event.type == MOUSEBUTTONDOWN):
loop = False
if loop == False:
currentMenu = mainMenu
loop = True
boxisinputting = False
boxinputting = None
userisinputting = False
while loop == True:
pygame.display.flip()
userisinputting = False
mousex, mousey = pygame.mouse.get_pos()
currentMenu.disp()
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if pygame.key.name(event.key) == 'return':
boxinputting.inputting = False
boxisinputting = False
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
for but in currentMenu.buttonList:
if but.hovered == True:
but.click()
if boxisinputting == False:
for box in currentMenu.inputBoxList:
if box.hovered == True:
box.inputting = True
boxisinputting = True
boxinputting = box
if userisinputting == True:
boxinputting.render()
pygame.time.delay(100)
Что происходит, когда я запускаю этот код:
Следующее меню отображается нормально, но его кнопки не реагируют (у меня есть методы, которые подсвечивают его вверх или вниз независимо от того, нажимает ли мышь на кнопку); вместо этого, когда я перемещаю указатель на предыдущее меню, появляются кнопки предыдущего меню, где они были.
Однако, когда я копирую и вставляю инструкции, я хочу, чтобы мой метод .нажмите (self), чтобы сделать здесь:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
for but in currentMenu.buttonList:
if but.hovered == True:
but.clicked = True
if but.dest == None:
pass
else:
currentMenu = None
currentMenu = but.dest
but.dest.disp()
but.clicked = False
… ну, это работает отлично: кнопки активны и отвечают, а предыдущие не появляются из ниоткуда (что я и готов сделать).
Мне это сойдет с рук, потому что это просто потеряет 5 или 6 строк в моем цикле. Но мне интересно узнать, почему я не могу заставить метод работать, чтобы избежать будущих проблем, подобных этой.
Спасибо, что прочитали мой пост!
Уильям
Комментарии:
1. Хорошо, так что именно пошло не так ? Кроме того, вместо того, чтобы пытаться сократить
click
метод, в котором у вас возникла проблема, можете ли вы попытаться вырезать все остальное , что не связано с проблемой? Оставьте только то, что необходимо, чтобы другие люди могли скопировать и вставить код и воспроизвести проблему. Пожалуйста, смотрите sscce.org за подробностями.2. Если вы замените
break
button.click()
свой на, то ваш код с вызовом функции будет эквивалентен встроенному коду. В противном случае вы пытаетесь вызватьbutton.click()
в концеfor
цикла. И в вашемfor
цикле также есть потенциальная проблема, поскольку вы создаете локальную переменную с именемbutton
, совпадающим с именем вашего класса. Это помогает?3. @Karl Knetchel Спасибо. Я обновил свой пост, чтобы сделать его, надеюсь, более читаемым и перейти прямо к делу.
4. @Random Davis Ну, вы точно определили мою проблему: два кода, которые я считаю эквивалентными, не выполняются одинаково. И я исправил неправильное написание, на которое вы указываете, заменив «для кнопки в currentMenu.ButtonList» на «для, но в currentMenu.ButtonList». Он по-прежнему не решает мою проблему.
Ответ №1:
Трудно сказать, потому что включенный код не показывает создание экземпляра a button
, но, вероятно, вам нужно убедиться, что он ссылается на глобальную область:
def click(self):
global currentMenu, gamesMenu
currentMenu = gamesMenu
print('click')
Ваш класс button был бы лучше, если бы он просто оставался только кнопкой. Итак, это касается местоположения и метки, цветов, независимо от того, нажата ли она, не нажата, наведена и т. Д. Но то, что это не так, также важно. Кнопка — это не меню, она не должна знать о меню и не должна обрабатывать меню (или очищать буфер отображения!).
Объекты создают лучший дизайн и более чистый код, когда они кратко описывают, что они делают.
Комментарии:
1. Спасибо. Я не знал о «глобальном» в Python, но я определил проблему следующим образом: он изменяет currentMenu только локально в методе, но currentMenu принимает его предыдущее значение, как только программа завершит выполнение метода. Итак, это решает мою проблему. Кроме того, что касается моего класса button, его цель — указывать на меню при нажатии и выделять при наведении курсора мыши: вместо написания функций и определения кнопки со списком я счел более практичным определить класс со своими собственными методами. Но не стесняйтесь давать мне советы по улучшению эргономики моей программы.