keep a task inactive until mouse click

Hello all, i currently have a task that i need to run once the mouse is clicked. Sadly the only way i know to control when a task is executed is do later tasks, and they only use time to tell them when to start.

from direct.showbase.ShowBase import ShowBase 
from direct.showbase import DirectObject 
from direct.task import Task 
from direct.gui.OnscreenText import OnscreenText
from math import pi, sin, cos 

hitcount = 0 
    
class MyApp(ShowBase): 
  
    def __init__(self): 
        ShowBase.__init__(self) 
        base.disableMouse() 
        
        self.box = self.loader.loadModel('samples/Ball-in-Maze/models/ball')
        self.box.reparentTo(self.render)
        
        
    	self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")    
        
    def spinCameraTask(self, task):
        angleDegrees = task.time * 100
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        self.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont
      
  
class Hello(DirectObject.DirectObject): 
    
    def __init__(self): 
        self.accept('mouse1',self.hitcountfunction) 
        self.accept('mouse3',self.hitcountfunction) 
        self.accept('z',self.hitcountfunction)
        self.accept('x',self.hitcountfunction)      
        
    def hitcountfunction(self): 
        global hitcount 
        hitcount += 1 
        print hitcount 
        
    def cpm( self, task ): 
      if task.time < 20:
    	task.time and \
        cpm.setText( 
          str( 
            round( 
              (hitcount / ( task.time / 60 )) / 4, 
              2 ) ) ) 
      return task.cont 
    
h = Hello() 

app = MyApp() 

cpm = OnscreenText( pos = ( 0, -.2 ), scale = .05, mayChange = True ) 
app.taskMgr.add( h.cpm, '...' ) 

app.run()

i need the

app.taskMgr.add( h.cpm, '...' )

task to only be executed once

self.accept('mouse1',self.hitcountfunction) 
self.accept('mouse3',self.hitcountfunction) 
self.accept('z',self.hitcountfunction)
self.accept('x',self.hitcountfunction

one of those happens. is that possible?

Yeah, just call taskMgr.add in the mouse1 event function. Be sure to store a boolean to check whether you didn’t already add it.

can i add multiple functions to be run? example

self.accept('mouse1',self.hitcountfunction, self.taskMgr.add(self.cpm, '...'))

No, but you can call self.taskMgr.add() within hitcountfunction. Or write a new function that calls both of these, add bind this new function to accept() instead.

David

ive tried calling self.taskMgr.add() within hitcountfunction but something goes wrong and it doesnt work. once i click the app crashes, and for some reason i cant run my .py files with the version of pythin .exe that opens the console too =/ heres the code

from direct.showbase.ShowBase import ShowBase 
from direct.showbase import DirectObject 
from direct.task import Task 
from direct.gui.OnscreenText import OnscreenText
from math import pi, sin, cos 

hitcount = 0 
    
class MyApp(ShowBase): 
  
    def __init__(self): 
        ShowBase.__init__(self) 
        base.disableMouse() 
        
        self.box = self.loader.loadModel('samples/Ball-in-Maze/models/ball')
        self.box.reparentTo(self.render)
        self.box.setPos(0, 15, 0)
        
    	self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")    
        
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        self.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont
      
  
class Hello(DirectObject.DirectObject): 
    
    def __init__(self): 
        self.accept('mouse1',self.hitcountfunction) 
        self.accept('mouse3',self.hitcountfunction) 
        self.accept('z',self.hitcountfunction)
        self.accept('x',self.hitcountfunction)      
        
    def hitcountfunction(self): 
        global hitcount 
        hitcount += 1 
        print hitcount
        self.taskMgr.add(self.cpm, '...') 
        
    def cpm( self, task ): 
      if task.time < 20:
    	task.time and \
        cpm.setText( 
          str( 
            round( 
              (hitcount / ( task.time / 60 )) / 4, 
              2 ) ) ) 
      return task.cont 
    
h = Hello() 

app = MyApp() 

cpm = OnscreenText( pos = ( 0, -.2 ), scale = .05, mayChange = True ) 

app.run()


that is the error i get, i was able to open it via console with ppython directory, hurp =/[/img]

Actually, it should be just taskMgr.add, not self.taskMgr.add.

David

i tried taskMgr.add(cpm, ‘…’) which gave me an error saying it couldnt find a function or task named cpm.

from direct.showbase.ShowBase import ShowBase 
from direct.showbase import DirectObject 
from direct.task import Task 
from direct.gui.OnscreenText import OnscreenText
from math import pi, sin, cos 

hitcount = 0 
    
class MyApp(ShowBase): 
  
    def __init__(self): 
        ShowBase.__init__(self) 
        base.disableMouse() 
        
        self.box = self.loader.loadModel('samples/Ball-in-Maze/models/ball')
        self.box.reparentTo(self.render)
        self.box.setPos(0, 15, 0)
        
    	self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")    
        
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        self.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont
      
  
class Hello(DirectObject.DirectObject): 
    
    def __init__(self): 
        self.accept('mouse1',self.hitcountfunction) 
        self.accept('mouse3',self.hitcountfunction) 
        self.accept('z',self.hitcountfunction)
        self.accept('x',self.hitcountfunction)      
        
    def hitcountfunction(self): 
        global hitcount 
        hitcount += 1 
        print hitcount
        taskMgr.add(cpm, '...') 
        
    def cpm( self, task ): 
      if task.time < 20:
    	task.time and \
        cpm.setText( 
          str( 
            round( 
              (hitcount / ( task.time / 60 )) / 4, 
              2 ) ) ) 
      return task.cont 
    
h = Hello() 

app = MyApp() 

cpm = OnscreenText( pos = ( 0, -.2 ), scale = .05, mayChange = True ) 

app.run()

i think i need a boolean, but when i try booleans i get more errors lol
[/quote]
EDIT: so i got it working but there is one small issue, when i click there is nothing in the textbox, BUT it doesnt crash. Its almost like the task wasnt added =/ idk any ideas?

from direct.showbase.ShowBase import ShowBase 
from direct.showbase import DirectObject 
from direct.task import Task 
from direct.gui.OnscreenText import OnscreenText
from math import pi, sin, cos 

hitcount = 0 
startfun = None
    
class MyApp(ShowBase): 
  
    def __init__(self): 
        ShowBase.__init__(self) 
        base.disableMouse() 
        
        self.box = self.loader.loadModel('samples/Ball-in-Maze/models/ball')
        self.box.reparentTo(self.render)
        self.box.setPos(0, 15, 0)
        
    	self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")    
        
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        self.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont
      
  
class Hello(DirectObject.DirectObject): 
    
    def __init__(self): 
        self.accept('mouse1',self.hitcountfunction) 
        self.accept('mouse3',self.hitcountfunction) 
        self.accept('z',self.hitcountfunction)
        self.accept('x',self.hitcountfunction)      
        
    def hitcountfunction(self): 
        global hitcount 
        hitcount += 1 
        print hitcount
        global startfun
        startfun = True
        
        
    def cpm(self, task): 
      if task.time < 20:
    	task.time and \
        cpmt.setText( 
          str( 
            round( 
              (hitcount / ( task.time / 60 )) / 4, 
              2 ) ) ) 
      return task.cont 
 
if startfun:
	app.taskMgr.add(h.cpm, "cpm")
         
h = Hello() 

app = MyApp() 

cpmt = OnscreenText( pos = ( 0, -.2 ), scale = .05, mayChange = True ) 

app.run()

I don’t think you’re ever calling taskMgr.add(). Try putting print statements in various places of your program–like, right before and after the call to taskMgr.add()–to get a sense for how the execution flow goes.

David

so as you said the task is not getting added. I dont see why though. its as if the

if startfun:
	app.taskMgr.add(h.cpm, "...")
	print startfun

is just not there =/
EDIT: i tried this code

from direct.showbase.ShowBase import ShowBase 
from direct.showbase import DirectObject 
from direct.task import Task 
from direct.gui.OnscreenText import OnscreenText
from math import pi, sin, cos 

hitcount = 0 
startfun = None
    
class MyApp(ShowBase): 
  
    def __init__(self): 
        ShowBase.__init__(self) 
        base.disableMouse() 
        
        self.box = self.loader.loadModel('samples/Ball-in-Maze/models/ball')
        self.box.reparentTo(self.render)
        self.box.setPos(0, 15, 0)
        
    	self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")    
        
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        self.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont
      
  
class Hello(DirectObject.DirectObject): 
    
    def __init__(self): 
        self.accept('mouse1',self.hitcountfunction) 
        self.accept('mouse3',self.hitcountfunction) 
        self.accept('z',self.hitcountfunction)
        self.accept('x',self.hitcountfunction)      
        
    def hitcountfunction(self): 
        global hitcount 
        hitcount += 1 
        print hitcount
        global startfun
        startfun = True
        print startfun
        if startfun:
			taskMgr.add(cpm, "...")
			print startfun
        
        
    def cpm(self, task): 
      if task.time < 20:
    	task.time and \
        cpmt.setText( 
          str( 
            round( 
              (hitcount / ( task.time / 60 )) / 4, 
              2 ) ) ) 
      return task.cont 
 
         
h = Hello() 

app = MyApp() 

cpmt = OnscreenText( pos = ( 0, -.2 ), scale = .05, mayChange = True ) 

app.run()

and get the following error once i click:

aight i got it finally lol. I just had to change it to task.add(h.cpm, ‘…’). But how could i make it only run once, because atm its adding it every click, and if i make startfun false under the if statement it will just become true again when i click.

Well think about it. You’re doing this:

startfun = True
if startfun:

So that’s really the same as writing:

if True:

I think what you want is to check if it is NOT True, THEN set it True:

if not startfun:
    startfun = True
    taskMgr.add(self.cpm, '...')

gah hurp it works perfectly. hehe i love how simple the solutions are, it practilly slaps u in the face XD Thank you :smiley: