I have something like this menu shown in pseudo code;
# We get a call to either create or destroy the main menu;
def mainmenu(menustate):
if menustate == True:
showMainMenu()
else:
hideMainMenu()
def showMainMenu():
# Here I have let's say three things
someText = textObject(blah blah blah)
someImage = OnscreenImage(blah blah blah)
someButtn = DirectButton(blah blah blah)
# this function just created these things no problem
def hideMainMenu():
# Here is the problem
textObject.destroy() # Now won't work because,
# I am in a 'local scope' of a function, same for the others
# Trying to access them? How?
but Iâm trying to break up my game in pages and I am just having trouble,
here is my actual repo if you would like to see the actual project; SHENKO.org on Github
I thank you in advance, any suggestions are welcome and appreciated.
Alteratively, I might suggest that you use classes, thus giving you access to the automatic âselfâ reference and through it any instance-variables of that class. Like so:
class Cat:
def __init__(self):
self.mew = None
def setupTextNode(self)
self.mew = TextNode(
# Parameters here
)
def hideTextNode(self):
self.mew.hide()
(The tutorial itself gives a larger example of this approach, I believe.)
I started looking at this option before, so in main.py I would import mainMenu.py
that has this âclassâ called 'mainMenu(). I would initialize the class with âmenuStateâ
variable in order to toggle it on / off. Let me try
Here is an example. I donât think a good solution would be to change attributes at runtime. It is better to create an instance of DirectGUI, configure and hide.
#âFINAL SOLUTIONâ#
in main.py we have something like;
import module as module # SEE: module.py mentioned below
class MyApp(ShowBase):
def __init__(self):
module.mainMenu(mainMenuState, cameraActive) # SEE: module.py below
self.accept('m', self.menuToggle) # This listens to keyboard for 'm' button!
def menuToggle(self):
module.mainMenu(mainMenuState, cameraActive) # Pressing 'm' calls menu
Now in a seperate folder called module containing a empty init.py file
and mainMenu.py I do something like this;
from panda3d.core import AudioSound
from panda3d.core import TextNode
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.OnscreenText import OnscreenText
class mainMenu:
def __init__(self, mainMenuState, cameraActive):
# Just try and destroy a menu if it already exists
try:
self.hideMainMenu()
except:
# Here I create all menu items example
self.textObject = OnscreenText(....) # Create some text like 'loading....'
self.imageObject = OnscreenImage(...) # To create a Logo or something
self.startbttn = DirectButton(...command=self.start) # Click bttn calls self.start()
def hideMainMenu(self):
self.textObject.destroy()
self.imageObject.destroy()
# This one was a bit different
self.startbttn['state'] = DGG.DISABLED
self.startbttn.destroy()
def start(self):
# Let's say you click 'start game' button we destroy the menu and move on...
self.hideMainMenu()
callYourCustomFunctionHere()
Everything seems to be working fine, except for one glitch. Multiple presses of âmâ
seems to require equal amounts of button clicks to counter it. As though the pressing of
the âmâ button queueâs up or stacks the menu. I canât figure this out since the very first
thing I do is try to destroy the menu at the very begining. suggesting that the âtryâ block is not actually succesfully destroying the previous menu. But otherwise works great!
You can find the latest implementation of this in practice on the Shenko.org repo here; SHENKO on Github
Note that in your âtryâ-block, you attempt to destroy elements of the instance that youâve just created (as referenced by âself.â). It wonât touch on any previous instances of the âmainMenuâ class.
Iâd suggest, then, moving the logic that calls âhideMainMenuâ out of âmainMenuâ itself, and into the code that calls for the construction of a âmainMenuâ.
Now, that alone wonât work, I daresay, because it doesnât have access to the previous âmainMenuâ. So, I suggest storing in a variable of your âMyAppâ class a reference to the current âmainMenuâ object, thus allowing you to destroy that object and replace it with the subsequent âmainMenuâ.