Destroying 2d screens

I’m putting some 2d screens (frames actually) together for my game. Std stuff like options, credits, etc.

The title screen has buttons to the others (including 1 button which starts the actual 3d game.)

My questions is what’s the proper way to destroy the 2d screens when moving from 1 to the other. Or should I just be hiding them).

I can get around the 2d ones with no issues, but when calling my 3d game, I need to destroy the 2d frames. Should i be checking if they exist and then just use .destroy()? how do i check if they exist (they wouldn’t unless the user had clicked the button that created them)

Is there an example of this I could look at?

If you’re talking about DirectFrame, the correct way to remove them is to call .destroy().

As to knowing whether they exist or not, that sounds like something you have to handle in your program’s design. If you created them, they exist. If you have already destroyed them, they don’t exist.

David

Here’s my code and what I’m seeing:

class MyGame(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)
		self.GAME_FONT = loader.loadFont(GAME_STORY + "/art/gui/" + "gnatfont.ttf")
		self.screenTitle()

	def screenTitle(self):
		logFile("show title screen")		    
		self.scrTitle = DirectFrame(image=GAME_STORY + "/art/gui/game_title.jpg", frameSize=(-1.33,1.33,-1.0,1.0), image_scale=(1.34, 0, 1))
		self.cmdChar = self.myGUIButton("Battle!", self.playBattle, (-.6,0,-.9), self.scrTitle)
		self.cmdChar = self.myGUIButton("Options", self.screenOptions, (-.2,0,-.9), self.scrTitle)
		self.cmdChar = self.myGUIButton("Credits", self.screenCredits, (.2,0,-.9), self.scrTitle)
		self.cmdChar = self.myGUIButton("Quit Game", self.quitGame, (.6,0,-.9), self.scrTitle)

	def screenOptions(self):
		self.scrOptions = DirectFrame(image=GAME_STORY + "/art/gui/game_options.jpg", frameSize=(-1.33,1.33,-1.0,1.0), image_scale=(1.34, 0, 1))		
		self.cmdMenu = self.myGUIButton("Main Menu", self.screenTitle, (-1,0,-.9), self.scrOptions)

	def screenCredits(self):
		self.scrCredits = DirectFrame(image=GAME_STORY + "/art/gui/game_credits.jpg", frameSize=(-1.33,1.33,-1.0,1.0), image_scale=(1.34, 0, 1))
		self.cmdMenu = self.myGUIButton("Main Menu", self.screenTitle, (-1,0,-.9), self.scrCredits)

	def myGUIButton(self, text, command, pos, parent):
	    	return DirectButton(text=text, command=command, pos=pos, parent=parent,
			frameSize=(-.2,.2,-.07,.07), relief=DGG.RAISED, borderWidth = (0.03, 0.03), text_font=self.GAME_FONT,
			text_scale=.04, text0_fg=(0,0,1,1), text1_fg=(1,0,0,1), text2_fg=(1,1,0,1), text3_fg=(0,1,1,1))

	def playBattle(self):
		self.scrTitle.destroy()
		self.gameControls()
		base.disableMouse() 
		base.camera.setPos((133, -132, 67))
		self.mouseX = 0
		self.mouseY = 0 
		self.mouseDrag = False
		self.camTarget = Vec3() 
		self.camDist = 200
		self.camTrack = False
		etc... rest of 3d game code

when the game starts up the fram, scrTitle is shown. If I click the “Battle” button to play, it goes to playBattle and everything works fine.

If I click any other button 1st (say “Credits”) and then use the “Main Menu” button on Credits to go back to scrTitle and then launch the game with “Battle” - the title screen never goes away . I can tell the gaem code has started because some ot the game ui pops up on top of the title jpg, but I can’t see the 3d scene.

I tried adding a scrOptions.destroy(), but then I need to know if it exists. I added a flag to set if the user ever clicks the Options button and then check it to see if I should destroy. Still the same result.

You can use hasattr(self, ‘scrOptions’) to check to see if there exists a self.scrOptions. Or, even better, set self.scrOptions to None in your constructor, and after you call destroy; then you can just check self.scrOptions.

David

changed the playBattle code to this (added hasattr check)

	def playBattle(self):
		if hasattr(self, 'scrOptions'):
			self.scrOptions.destroy()
		self.scrTitle.destroy()		
		self.gameControls()
		base.disableMouse() 
		base.camera.setPos((133, -132, 67))	# temp code - need to store this in map?
		self.mouseX = 0
		self.mouseY = 0 
		self.mouseDrag = False
		self.camTarget = Vec3() 
		self.camDist = 200
		self.camTrack = False
etc.etc.

Now I don’t get any errors when destroying scrOptions. However, when starting a game (with “Battle” button) , the title screen still stays on the screen as before (and game GUI comes up)

Maybe there’s some object ref problem? I create scrOptions from a button in scrTitle (see code in previous post) . for some reason scrTitle won’t destroy when I create another frame from inside it.

maybe problem is that my “main menu” button in scrOptions basically is just calling screenTitle again. Is there a way I could make the “main menu” button in that frame destroy the frame?

I tried

def screenOptions(self):
		logFile("show options")
		self.scrOptions = DirectFrame(image=GAME_STORY + "/art/gui/game_options.jpg", frameSize=(-1.33,1.33,-1.0,1.0), image_scale=(1.34, 0, 1))		
		self.cmdMenu = self.myGUIButton("Main Menu", self.screenOptions.destroy(), (-1,0,-.9), self.scrOptions)

but get an error.

Maybe you’re calling screenOptions more than once, and each time, you add a new DirectFrame on top of the screen? If that were so, then when you call self.scrOptions.destroy(), it would only destroy the most recent one.

You could make sure that you always destroy a previous scrOptions before you create a new one.

David

Yes, that did it!

I added the hasattr check to the start of each screen function (ensuring there’s always only 1). And I check them all at the start of playbattle and destroy them if they exist.

All running smoothly.

Thanks very much!