Problem with Python

Hi there. I have a little problem which is rather related to Python than Panda.

I use a dictionary in order to store some states for my game. Then I use a task which reads those states (the keys) every frame and depending on the “1” value sets the game`s state.

Now, the problem is that if I define the dictionary using

global [varname]

in my code I get this error:

NameError: global name 'states' is not defined

Then if I use “self” to access it, “self” is not defined and I just don`t know how to pass “self” to the task. I have tried to add the task with arguments but I cannot pass “self” as an argument.

Here is my code:

from direct.showbase.ShowBase import ShowBase
from direct.task import Task

class Main(ShowBase):

    # States dictionary
    states = {"STARTUP":0, "SHOWMENU":0, "STOP":0}   
    
    # Constructor
    def __init__(self):
        ShowBase.__init__(self)
    
    # Methods
    def setState(self, key):
        for key_d in self.states:
            if(key_d == key):
                self.states[key_d] = 1
            else:
                self.states[key_d] = 0
    
    # Tasks
    ## Task manager
    taskMgr = Task.TaskManager()
    ## Game state task
    def gameStateTask(task):
        global states
        for key, value in states:
            if(key == "STARTUP"):
                if(value == 1):
                    print("start")
                    return task.cont                 
            elif(key == "SHOWMENU"):
                if(value==1):       
                    print("showmenu")
            elif(key == "STOP"):
                if(value == 1):
                    print("stop")
                    
    ## Add the tasks
    taskMgr.add(gameStateTask, "StateManager")
   
    
# Run the app
app = Main()
app.run()

Any solution?

Try this:

class Main(ShowBase): 

    # States dictionary 
    states = {"STARTUP":0, "SHOWMENU":0, "STOP":0}    
    
    # Constructor 
    def __init__(self): 
        ShowBase.__init__(self)

        # We don't need to make a taskMgr instance -
        # ShowBase's constructor does that for us

        # Add the tasks
        self.taskMgr.add(self.gameStateTask, "StateManager") 
    
    # Methods 
    def setState(self, key): 
        for key_d in self.states: 
            if(key_d == key): 
                self.states[key_d] = 1 
            else: 
                self.states[key_d] = 0 
    
    ## Game state task 
    def gameStateTask(self, task): 
        for key, value in self.states.iteritems(): 
            if(key == "STARTUP"): 
                if(value == 1): 
                    print("start") 
                    return task.cont                  
            elif(key == "SHOWMENU"): 
                if(value==1):        
                    print("showmenu") 
            elif(key == "STOP"): 
                if(value == 1): 
                    print("stop") 

    
    
# Run the app 
app = Main()
app.run()

All I’ve done is move the task manager initialization code to Main’s init method, and added the self parameter to gameStateTask. I think the reason your code wasn’t working was because you thought tasks had to have “task” as their only parameter, which isn’t true - tasks are normal Python functions, and can have “self” as their first parameter as long as they’re part of a class.

Okay, tried.

Now I get this error:

Traceback (most recent call last):
  File "D:\Programming\Workspaces\python.workspace\GamePrototype\Main\__init__.py", line 29, in gameStateTask
    for key, value in self.states: 
ValueError: too many values to unpack
:task(error): Exception occurred in PythonTask StateManager
Traceback (most recent call last):
  File "D:\Programming\Workspaces\python.workspace\GamePrototype\Main\__init__.py", line 45, in <module>
    app.run()
  File "D:\Programming\SDK\Panda3D-1.8.0\direct\showbase\ShowBase.py", line 2910, in run
    self.taskMgr.run()
  File "D:\Programming\SDK\Panda3D-1.8.0\direct\task\Task.py", line 502, in run
    self.step()
  File "D:\Programming\SDK\Panda3D-1.8.0\direct\task\Task.py", line 460, in step
    self.mgr.poll()
  File "D:\Programming\Workspaces\python.workspace\GamePrototype\Main\__init__.py", line 29, in gameStateTask
    for key, value in self.states: 
ValueError: too many values to unpack

The line with the error (29) is this:

for key, value in self.states:

Oops. Switch line 29 to read:

for key, value in self.states.iteritems():

Oh yea. Now it works. Thank you!