Sequence and task (solved)

hi!

it’s my first post here, I come from china. really, no kidding!
the hometown of panda…

I just took nearly one month to get study with C++ and then python and then Panda3D.

there maybe some barriers in the communication since my English sucks
if you are frowning on grammar mistakes or misspellings, bear with me.

I just wrote some codes to test the difference between sequence and task.

It’s just a simple “count-from-1000-to-0”

I wrote it with sequence and then with task

here are the codes , questions are listed below the codes

sequence version:

class pointMgr():
    def __init__(self):
        #initial points are 1000 
        pointMgr._point = 1000
        pointMgr._level = 1
        self.seq_PointCountDown = Sequence(Func(self.checkCount), 
                                           Func(self.RepresentPoint), 
                                           Func(self.CountDown), 
                                           Wait(1))
        #initialize methods
        self.seq_PointCountDown.loop()
    def checkCount(self):
        if pointMgr._point > 0:
            self.seq_PointCountDown.loop()
        else:
            self.seq_PointCountDown.finish()
        
    #points are counted down by current level
    def CountDown(self):
        pointMgr._point = pointMgr._point - pointMgr._level *100
        
    #represent points
    def RepresentPoint(self):
        print pointMgr._point
#end class
##--------------------------------------------------------------------------##
#main
p = pointMgr()
run()

and the task version:

class pointMgr():
    def __init__(self):
        #initial points are 1000 
        pointMgr._point = 1000
        pointMgr._level = 1
        
        #initialize task
        taskMgr.doMethodLater(1, self.CountDown, 'CountDown', extraArgs = [])
    #points are counted down by current level
    def CountDown(task):
        self.RepresentPoint()
        #print pointMgr._point
        pointMgr._point = pointMgr._point - pointMgr._level *100
        if pointMgr._point > 0:
            return Task.again
        else:
            return Task.done
        
    #represent points
    def RepresentPoint(self):
        print pointMgr._point
#end class
##--------------------------------------------------------------------------##

#main(){
pointMgr()
run()

questions:

  1. the result in the sequence version printed “0” which means the sequence does not stop immediately after the Func(self.checkCount). still I can not understand why…

  2. and in the task version, an error came out as below:

  File "CountSheep_pointMgr_01.py", line 25, in CountDown
    self.RepresentPoint()
NameError: global name 'self' is not defined

It seems task don’t allow me to insert another functon. what should I do if I really want?

  1. here are the central question:
    which one is better?
    sequence and task can both achieve the same application. which is better when I try to run it through out the mainloop and controll it anytime I want to?(later, I gonna add events to handle this class)

  2. still I find there is a warning in the feedback of console

**** End of process output ****
DirectStart: Starting the game.
Warning: DirectNotify: category 'Interval' already exists

every script I have wrote till today has this warning, I can not figure it out
here are the imports:

import direct.directbase.DirectStart
from direct.interval.FunctionInterval import Func,Wait
from direct.interval.MetaInterval import Sequence
from direct.task import Task

and and I still got a extra one, sorry I just have so many questions…
why on earth do all the Panda 3D scripters put every thing in a world class and then instantiate it? As to me, it’s a little wierd way to run it. in the class you have to use so many “self” and make variables and methods a little bit redundant. Is it a convention all a better way? what are the pros?
(I do rewrite the introduction tutorial “solar system” in another way and it runs as well as the official version…)

Thanks!!!

Welcome!

This sort of question comes up often. When you call finish(), the sequence finishes itself. This means it plays everything remaining in the sequence immediately. If you just want to stop it where it is and not finish it, then call pause() instead.

Still, I think you are abusing the sequence a bit. You are calling sequence.loop() from within the sequence, but this is not necessary. (The sequence has already started, no need to call loop() again and again as it plays. The sequence will take care of itself.)

In Python, you always need to pass in self explicitly. Change your function definition to:

def CountDown(self):

In fact, you are not passing the task object at all, because you set extraArgs = . This is why there is no task parameter on your argument list, but you still need the self parameter.

It is true that sequences and tasks can be used for many of the same things. There are some things that sequences are better at, and some things that tasks are better at. For instance, a sequence’s duration must be known at start time, and it cannot change while the sequence is playing; but a task can be open-ended. So if the thing you want to do is open-ended in nature, you’d better use a task. On the other hand, a sequence can be much easier for building up complex scripting actions, especially if you have many nested sequences and parallels.

Please ignore this warning. It is part of the normal operation of Panda. We should remove it, but we haven’t gotten around to it; I apologize for the confusion.

It’s just an object-oriented coding style. If you prefer not to use this coding style, there is no reason to do so. It’s strictly a question of personal preference.

David

David

thankyou!
I decided to write a game by own
this is just a auspicious beginning
thank you again for your help

sophos