Message handles

Im sry to ask what seems like such a noob question, but im fairly new to panda, and need help with event handlers. Ive gone through all the tutorials, searched the manual, but i always end up creating some sort of error. Im confused way beyond question. Plz help me!

What do you need to know?

I usually end up with a syntax error or an error than resembles :

Name error: (whatever) is not a global name

I know this is bad etiquette, but could i get a snippet of code containing a handler? From there i might be able to sort it out myself.

Thx

It looks like you’re calling a local var/function the way you call a global variable/function.
Please show your code. Note to always use self.varname for local variable names.

Yeah. Look inside the samples subdirectory of the Panda3D installation dir.

When Python (not Panda3D!) works through the code and tries to find the right variables/methods/whatever it first looks in the local namespace of a method, then the global namespace. If neither has such a name then it raises the error you get.

Look at this example:

y = 123 # defined in global namespace

def test( ):
    x = 456 # defined in local namespace
    print x
    print y
    print z

test( )

When printing “x” Python finds this variable in the local namespace. “x” is defined one line above. When printing “y” Python doesn’t find “y” in the local namespace. So it looks in the global namespace, where it is defined (in the first line). Finally, when printing “z” Python finds this name neighter in the local namespace nor in the global namespace. So it gives you the following error message:

NameError: global name 'z' is not defined

This means for you: look at your code. “whatever” is not defined. Perhaps you mixed upper-case/lower-case? Python is case-sensitive. Or you misspelled the variable “whatever”?
enn0x

This is what i have. Its my first attempt at movement, so its probably nowhere near a good implementation. Lemme know if you find anything.

# all the imports
import direct.directbase.DirectStart
from direct.showbase import DirectObject
from direct.task import Task

#load an environment
environ = loader.loadModel('/c/Panda3D-1.3.2/models/environment')
environ.reparentTo(render)

# this program plays sounds to tell if the functions
# are really bieng called
mySound = loader.loadSfx('snare05.wav')

#Create variable
heading = 0

#set up camera
base.disableMouse()
base.camera.setPos(1,41,10)

#Create class to handle keypresses
class keyPress(DirectObject.DirectObject): 
	def __init__(self): 
		self.accept('arrow_left',self.turnleft)
		self.accept('arrow_right',self.turnright)
	def turnleft(self): 
		mySound.play()
		heading += 1 
	def turnright(self): 
		mySound.play()
		heading -= 1
h = keyPress() 	 

#Task to position camera
def camerapos(Task): 
	base.camera.setHpr(heading, 0, 0)
	return Task.cont
taskMgr.add(camerapos, 'mainloop')

#run level
run()

Im still getting the global name error, but now i think its because i dont understand how variables in classes work.

Thx for the help.

Hmm… this won’t work:

heading = 0
...
class keyPress(DirectObject.DirectObject):
    ....
   def turnleft(self):
      heading += 1

Assignment happens always in local namespace, except if you explicitly declare a name to be global, e.g. like this:

   def turnleft(self):
      global heading
      heading += 1

What happens is this: Python tries to assign a value to the name “heading”. “heading” is not defined so far in this local namespace, so a new name “heading” is created. Then Python determines what value will be assigned to “heading”: it is “heading + 1”. Now Python has a problem. Heading is a new local name, but it has no value (it is unbound), and so Python can not compute “heading + 1”. Error is raised.

What puzzles me is that you get a global name error, and not a “UnboundLocalError: local variable ‘heading’ referenced before assignment” error.

When asking for help with Python errors it is always helpful to post the traceback, that is the few lines that Python gives you in the console. These lines tell you what has gone wrong, and where it has gone wrong. Post it!

enn0x

Another hint: don’t try to create complex global/local namespace dependencies. Make “heading” a member (attribute, property) of class “keyPress”:

class keyPress(DirectObject.DirectObject):
   def __init__(self):
      self.heading =  0
      self.accept('arrow_left',self.turnleft)
      self.accept('arrow_right',self.turnright)
   def turnleft(self):
      mySound.play()
      self.heading += 1 

enn0x

Wow! you got it working! Quite impressive :smiley:
I like your idea about the complex dependencies. Never thought of that b4…

Thx alot!!

BTW : Lol i did get the unbound local error.