Creating UI to load multiple games [Solved]

I’m trying to create a user interface that can load multiple games. Can someone kindly explain how to do this in Panda3D? I’m new to Panda and is confused on how I can accomplish this. Should I remove everything from render and delete every task when I load up the second game?Any help would be greatly appreciated.

I’m also pretty new to Panda3D. But if you’re parenting all your UI objects to render2d, you could just replace everything in the render and it should stay normally. You can also use NodePath.copyTo(NodePath) to copy everything from 1 nodepath to an another.

Thanks for the reply, that was helpful. Sorry, maybe I didn’t explain this, but the main goal is to make it possible to switch from one game to another with minimum interruption (the game is still displayed on the same window). I tried to accomplish this by doing cleanups (removing tasks, nodepaths, and keyhandlings) and then instantiating a new DirectObject every time the game is switched. So, is this the right approach? Or is there any other way to reset to original state (the blank grey screen)

Here’s a snippet of my code:

import PictureMatch
import AccuracyTest_2

from direct.gui.DirectGui import *
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import TextNode, Vec3, Vec4

class Interface(DirectObject):

    def genLabelText(self, text, i):
        return OnscreenText(text = text, pos = (-0.2, .95-.05*i), fg=(1,1,1,1),
                            align = TextNode.ALeft, scale = .05, mayChange = 1)


    def __init__(self):
        self.genLabelText("Press a to go back to interface ",0)
        self.genLabelText("Press s to play Accuracy Test",1)
        self.genLabelText("Press d to play Picture Match",2)
        self.accept("a",self.cleanup)
        self.accept("s",self.launchAccTest)
        self.accept("d",self.launchPictMatch)
        
    def launchPictMatch(self):
        self.i = PictureMatch.World()
        
    def launchAccTest(self):
        self.i = AccuracyTest_2.World()
        
    def cleanup(self):
        for x in taskMgr.getTasks():
            if (x.getName() != 'ivalLoop' and
                x.getName() != 'collisionLoop' and
                x.getName() != 'igLoop' and
                x.getName() != 'audioLoop' and
                x.getName() != 'resetPrevTransform' and
                x.getName() != 'dataLoop' and
                x.getName() != 'clientDisconnectTask'):
                taskMgr.remove(x)
        for x in render.getChildren():
            if (x != camera): 
                x.detachNode()
        render2d.getChildren().detach()
        aspect2d.getChildren().detach()

        self.i = Interface()
        #TODO:Remove key bindings

        
i = Interface()
run()

If you want to switch during runtime, it’s pretty easy. Make sure all your UI components are parented to render/aspect2d and then make sure your game is on render. If you just change the render node, the render2d node will just stay the same.

Also, yes, that code looks pretty decent.

I see, I didn’t notice it’s that simple, thanks! Now the code ran fine, but every time the game gets reloaded, it lags a bit more and a bit more till it’s too laggy to run. I don’t know why this happens. Is it because there are too many instances that takes up memory?(the way I reload the game in the code above) Perhaps there’s a more efficient way to load the game instead of instantiating the DirectObject maybe?

And also, when someone is messing up with base or base.win, it’s only showing the background instead of the render. And there’s also some conflicts with the fonts that I don’t know how to fix… I tried copying the base and base.win using the built in copy class and replacing them every time i go back to the interface, but it didn’t work… Any suggestions?

About the first problem, if you switch game, what do you do with the old NodePath? Do you just hide it? It might be better to destroy it. Also, try to look at PStats, it should you directly tell what’s wrong (there is a guide in the manual).

Thanks a lot wvd! I found the bug, I didn’t know that keyboard hooks are actually stacked and not replaced.

The only problem left is with the base.win and fonts. The problematic ones call the method base.win.setClearColor. I tried reverting to the original base by calling base.win.setClearColorActive(False), but no success…

As for the fonts, here’s the error message:

File “C:\Program Files\Panda3D-1.6.2\direct\showbase\Loader.py”, line 442, in loadFont
font.setPixelsPerUnit(pixelsPerUnit)
AssertionError: get_num_pages() == 0 at line 75 of c:\p\p3d\panda3d-1.6.2\panda\src\text\dynamicTextFont.I

I really have no clue…

setClearColor() sets the color, setClearColorActive() toggles the flag to clear the framebuffer before drawing a frame.
You must want to setClearColor(Vec4(.41,.41,.41,1)), or you could get the default value from config variable background-color.

As of the font num pages>0 error, call font.clear() before setting the PPU.

Thanks a lot ynjh_jo! By the way, I’m from Indonesia too, and I’ve been to Malang, the apples there are great!

I finally found the bugs. I unintentionally removed aspect2d from render2d while cleaning up. And for the font, I have to import the FontPool and call the method releaseAllFonts every cleanup session to reset the num_pages

:smiley: