no working loop

Hello
I am trying to make a method that uses PosInterval to move an object randomly from the top of the screen to the bottom of the screen. It was suggested to me that i use this new method with the Func command which creates the loop so that a random new position can be chosen after the sequence has stopped playing. Then call that method in the init to make it work, I have tried to do this however i am doing something wrong because the error I get in my terminal is this

DirectStart: Starting the game.
Known pipe types:
  glxGraphicsPipe
(all display modules loaded.)
:display:glxdisplay(warning): No suitable FBConfig contexts available; using XVisual only.
depth_bits=24 color_bits=24 alpha_bits=8 stencil_bits=8 back_buffers=1 force_hardware=1 
Traceback (most recent call last):
  File "ball02.py", line 80, in <module>
    w = world()                         
TypeError: __init__() takes exactly 2 arguments (1 given)

and here is the actual code

from direct.showbase.DirectObject import DirectObject
import direct.directbase.DirectStart
from random import choice

from direct.interval.IntervalGlobal import Sequence,Func
from panda3d.core import Point3
from direct.showbase.ShowBase import ShowBase
from direct.showbase import Audio3DManager



class world(DirectObject):
    def __init__ (self, balloop):
   
        
        base.setBackgroundColor(0, 0, 0)    #Set the background to black
        base.disableMouse()
        camera.setPos (0, 0, 45)          #Set the camera position (X, Y, Z)
        camera.setHpr (0, -90, 0)         #Set the camera orientation
       
        #load the model and render it to the screen
        self.sun = loader.loadModel("models/planet_sphere")
        self.sun.reparentTo(render)
        
        self.box = loader.loadModel("models/box")
        self.box.reparentTo(render)
        self.box.setPos(0, 0, 0)
       
        
        self.audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], self.box)
        self.audio3d.attachListener(self.box)    
        
        self.loop = self.audio3d.loadSfx("SFXmusic/sonicballs1.wav")
        self.loop.setLoop(True)
        self.audio3d.attachSoundToObject(self.loop, self.sun)
        self.loop.play()
        self.audio3d.setSoundVelocityAuto("SFXmusic/sonicballs1.wav")
         
        #list of positions at the top of the screen    
        toppos = [ (-10, 20, 0),
                  (-8, 20, 0),
                  (-6, 20, 0),
                  (-4, 20, 0),
                  (-2, 20, 0),
                  (0, 20, 0),
                  (2, 20, 0),
                  (4, 20, 0),
                  (6, 20, 0),
                  (8, 20, 0),
                  (10, 20, 0) ]  
                  
         
        bottompos = [ (-10, -20, 0),
                      (-8, -20, 0),
                      (-6, -20, 0),
                      (-4, -20, 0),
                      (-2, -20, 0),
                      (0, -20, 0),
                      (2, -20, 0),
                      (4, -20, 0),
                      (6, -20, 0),
                      (8, -20, 0),
                      (10, -20, 0)] 
                      
        
        
    def balloop(self):                              
        sunPosInterval1 = self.sun.posInterval(5, 
                                              Point3 (choice(bottompos)),
                                              startPos=Point3 (choice(toppos)),
                                              blendType=("easeIn"))
                                   
                                   
        self.ball = Sequence(sunPosInterval1,
                             Func(self.balloop))
        self.ball.loop()
       
   
          
w = world()                         
run()

So i know it has something to do with the init so am I not calling the method correctly can anyone suggest a solution to this problem
thanks

def __init__ (self, balloop): 

This indicates that the “init” method expects two parameters: the automatically-provided “self” parameter that should refer to the object in question, and something called “balloop”. Your problem appears to be that you’re attempting to call it with only one parameter (the automatically-provided “self” parameter) when you create your “world” object, in this line:

w = world()

Note that you give no parameters, when one is called for by the method.

What is the “balloop” parameter supposed to be, and why are you including it in your “init” method? It doesn’t appear to be used in that method, and, strangely, appears to have the same name as a method defined further down.

Thanks for the reply
what I am trying to do is get the method to initialize so that a loop will be created. For example I have removed the balloop from the init and ran the program. What happens is that the object ie. self.sun is supposed to randomly move form the top of the screen to the bottom of the screen but doesn’t. So what
I think is happening that the method, def balloop(self): is not being recognized properly. That is why I put the balloop in the init to initialize it which if what you are telling me is the wrong thing to do.
So what am I not doing to make the loop work so that the object will move?

looks over the code again

Okay, the first issue seems to me to be that you’re simply not calling “balloop” anywhere.

However, before I return to that, I note that “balloop” creates and loops a Sequence that itself calls “balloop”, meaning that every call causes the number of calls to multiply. This is likely to break things somewhat.

Instead, try just using “self.ball.play()” instead of “.loop()”. This way the method should be called just once again per call, I think.

Now, as to setting it going, no, the “balloop” parameter shouldn’t do what you seem to want. Indeed, I imagine that the class knows well enough about the method in question. Instead, in the “init” method, simply call balloop, like so:

# Somewhere after the line that starts with "bottompos = "
self.balloop()

If you prefer, you should be able to instead call it after you create your “world” object, like so:

w = world()
w.balloop()
run() 

Hi Thaumaturge
Thanks for the info I have tried out what you suggested as in using self.ball.play()
however when I tried to call the method ie. w.balloop()
this is the message i got in my terminal

Traceback (most recent call last):
  File "ball02.py", line 83, in <module>
    w.balloop()                      
  File "ball02.py", line 70, in balloop
    Point3 (choice(bottompos)),
NameError: global name 'bottompos' is not defined

so what is going on because this is a simple list I didn’t think that a list had to be defined.
so I tried the self.ball.play() and changed the bottompos and the toppos to self.bottompos, self.toppos and got this message in my terminal

Traceback (most recent call last):
  File "ball02.py", line 84, in <module>
    w.balloop()                      
  File "ball02.py", line 79, in balloop
    self.ball.play()
  File "/usr/share/panda3d/pandac/libp3directModules.py", line 33, in play
    self.notify.error("using deprecated CInterval.play() interface")
  File "/usr/share/panda3d/direct/directnotify/Notifier.py", line 136, in error
    raise exception(errorString)
StandardError: using deprecated CInterval.play() interface

So I changed the self.ball.play() back to self.ball.loop()
and the program ran however every call causes the number of calls to multiply which you said it would
my question now is it there a command that is an updated version of .play()

Hello again
So after reading a bit of the manual the phrase “RTFM” comes to mind.
I have found a solution instead of using the .play() I used the .start() command and hey presto it works
So thanks very much for the help I much appreciated it.

I’m glad that you got it working. :slight_smile:

To answer this question:

The problem, I believe, is that you had defined “bottompos” to be a local variable in your constructor – as soon as the constructor was done, the variable was free to be cleaned up. When you changed it to “self.bottompos”, you defined it to be a member of your “world” class, and so it became accessible from elsewhere, I believe.

[edit] Oh, and my apologies on the confusion regarding the “play” method – I was probably thinking of animations, which have a similar interface, and I fear that I didn’t think to check myself. Again, I’m glad that you found the problem.