passing args to tasks

The following code demonstrates passing parameters to both tasks and event handlers:


from ShowBaseGlobal import * 

class World( DirectObject.DirectObject ):
	def __init__( self ):
		base.mouseInterfaceNode.setPos( 0, 20, 0 )

		teapot = loader.loadModel( "teapot" )
		teapot.reparentTo( render )

		self.lightAttrib = LightAttrib.makeAllOff()
		self.ambientLight = AmbientLight( "ambientLight" )
		self.ambientLight.setColor( Vec4( .3, .3, .3, 1 ) )
		self.lightAttrib = self.lightAttrib.addLight( self.ambientLight )
		self.directionalLight = DirectionalLight( "directionalLight" )
		self.directionalLight.setColor( Vec4( .7, .7, .7, 1 ) )
		self.directionalLight.setDirection( Vec3( 1, 1, -2 ) )
		self.lightAttrib = self.lightAttrib.addLight( self.directionalLight ) 
		render.node().setAttrib( self.lightAttrib )

		self.accept( "arrow_left", self.turnObject, [teapot, -40, 0, 0] )
		self.accept( "arrow_right", self.turnObject, [teapot,  40, 0, 0] )
		self.accept( "arrow_up", self.turnObject, [teapot,  0, -40, 0] )
		self.accept( "arrow_down", self.turnObject, [teapot,  0, 40, 0] )

	def turnObject( self, object, h, p, r ):
		taskMgr.add( self.turnObjectTask, "turnObjectTask" + `globalClock.getLongTime()`, extraArgs=[object, h, p, r] )

	def turnObjectTask( task, object, h, p, r ):
		dt = globalClock.getDt()
		object.setHpr( object.getH() + h*dt, object.getP() + p*dt, object.getR() + r*dt )
		return Task.cont

world = World()

run()

Note that this isn’t a particularly efficient way of getting the demonstrated behavior, since a new task is created for each key press, but I felt this was closer to what you’re trying to do, since you want to launch multiple tasks simultaneously.

The extraArgs parameter is new, so you will have to download the latest installer before running the above code.

Also of note is that the task function requires you to omit the usually obligatory “self” argument. I think this is a flaw in the implementation.