Creating an interactive user interface

With very few exceptions, nearly every game features some kind of menu-based user interaction for selecting game modes, browsing servers, setting game, and graphics options, or chatting with other players. Most likely, the games you are going to create with Panda3D will also have such requirements and you will need to create buttons, text input fields, loading bars, or whatever controls suit your needs. To make things easier for you, the Panda3D engine comes with a set of user interface classes that make it very easy to place controls on the screen and make them react to the players' actions.

Getting ready

Go back to Chapter 1 and follow the steps of the recipe Setting up the game structure if you haven't yet and you are set to go on with the following tasks.

How to do it...

Let's create a user interface:

  1. Paste the following source code to Application.py:
    from direct.showbase.ShowBase import ShowBase
    from direct.gui.DirectGui import *
    from direct.interval.IntervalGlobal import *
    from panda3d.core import *
    class Application(ShowBase):
    def __init__(self):
    ShowBase.__init__(self)
    self.nameEnt = DirectEntry(scale = 0.08, pos = Vec3(-0.4, 0, 0.15), width = 10)
    self.nameLbl = DirectLabel(text = "Hi, what's your name?",
    pos = Vec3(0, 0, 0.4),
    scale = 0.1,
    textMayChange = 1,
    frameColor = Vec4(0, 0, 0, 0))
    helloBtn = DirectButton(text = "Say Hello!",
    scale = 0.1,
    command = self.setName,
    pos = Vec3(0, 0, -0.1))
    self.gender = [0]
    genderRdos = [DirectRadioButton(text = "Female",
    variable = self.gender,
    value = [0],
    scale = 0.05,
    pos = Vec3(-0.08, 0, 0.05)),
    DirectRadioButton(text = "Male",
    variable =self.gender,
    value = [1],
    scale = 0.05,
    pos = Vec3(0.16, 0, 0.05))]
    for btn in genderRdos:
    btn.setOthers(genderRdos)
    
  2. Now add the methods for handling clicks on the Say Hello! button and the resulting dialog to the Application class:
    def setName(self):
    self.acceptDlg = YesNoDialog(text = "Are you sure?",
    command = self.acceptName)
    def acceptName(self, clickedYes):
    self.acceptDlg.cleanup()
    if clickedYes:
    self.loadName()
    
  3. Next, it is time to add the code for creating and advancing a progress bar:
    def loadName(self):
    self.waitBar = DirectWaitBar(text = "Loading",
    range = 100,
    value = 0,
    pos = Vec3(0, 0, -0.3))
    inc = Func(self.loadStep)
    show = Func(self.setNameLabel)
    load = Sequence(Wait(1), inc, Wait(2), inc, Wait(1), inc, Wait(3), inc, show)
    load.start()
    def loadStep(self):
    self.waitBar["value"] += 25
    
  4. Lastly, add the code for setting the label text to Application.py:
    def setNameLabel(self):
    title = ""
    if self.gender[0]:
    title = "Mister"
    else:
    title = "Miss"
    self.nameLbl["text"] = "Hello " + title + " " + self.nameEnt.get() + "!"
    
  5. Press F6 to start the program:
How to do it...

How it works...

After importing the packages we need for this recipe—most notably, direct.gui.DirectGui for the user interface functionality—we go on to add a text input field, a label, a set of radio buttons and a button to confirm the name entry. We also use the pos, scale, and text parameters to define the positions, scales, and the texts of the controls and hint the label that its text will change by setting textMayChange to 1. Also note the variable and value parameters used when setting up the radio buttons. The former defines the variable that value will be stored into when the radio button is active. Don't forget to pass data to value using a list! Further, we pass the method to call when being clicked by using the command parameter of our confirmation button. To close step 1 of this sample, we iterate over the radio buttons, informing each button about the other buttons in the radio group so that only one option can be selected at a time.

In the next step, we add the setName() and acceptName() methods, which cause the application to display a confirmation popup after the user clicks the Say Hello! button. If the user clicks Yes, the program proceeds, otherwise the popup is hidden and nothing whatsoever happens.

We then proceed to step 3, where we add a progress bar to our user interface. The range parameter sets the maximum value for the progress bar, whereas value defines the initial progress shown after the control is added to the screen. We want to slow things down for this sample to see the progress bar in action. Therefore, we call loadStep() in a Sequence that waits a short moment between each step. This also allows us to see how we are able to update the progress bar's current value.

In the last method we add to the Application class, setNameLabel(), which is called last by the sequence that controls our progress bar. Here we finally modify the text attribute of the label control to display the name that is entered into the text input field.

There's more...

The GUI features of Panda3D go beyond what you have seen in this recipe so far, of course. The following section is meant to give you an idea about what else you can do with the engine's DirectGui library.

More controls

Besides the DirectEntry, DirectLabel, DirectButton, DirectRadioButton, YesNoDialog, and DirectWaitBar controls we used so far in this recipe, there are several more that might be useful for your purposes:

  • DirectCheckButton is a button control that toggles between a checked and unchecked state every time it is clicked.
  • DirectDialog is used for building popup dialogs like the confirmation used in the sample code. There are several pre-built default dialogs included in the DirectGui library like YesNoDialog, OkDialog, or RetryCancelDialog.
  • DirectFrame acts as a container for controls. This allows us to group multiple controls and positions them relative to the frame.
  • DirectOptionMenu works like a drop-down menu. When clicked, a menu opens and the control state is set to the selected item.
  • DirectScrolledList is a container control similar to DirectFrame, with the difference that items are being placed in a scrollable list.
  • DirectSlider is a control that allows the user to select an arbitrary value between two boundaries.
  • DirectScrollBar allows you to build controls similar to DirectScrolledList by hand.
  • DirectScrolledFrame works just like a DirectFrame, but it allows objects that are positioned outside of the container's boundaries to be reached using scroll bars.

More parameters

Apart from the parameters we used for setting up our sample GUI, there are some more common options that allow customizing Panda3D's user interface controls:

  • frameSize makes it possible to set the measures of the control using a four-component vector that specifies the left, right, bottom, and top positions of its frame.
  • frameColor sets the color of the user interface control element.
  • image sets the texture that is rendered on the control.
  • geom allows to set a Geom object that is rendered in place of the control.
  • suppressKeys turns off global keyboard events when set to 1. This is useful for implementing a menu for the pause state of a game, as it makes sure that the game logic is not notified about any keys being pressed when interacting with the user interface.
  • suppressMouse works like suppressKeys, but for the mouse.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset