Advice and help thread...

A little guidance please…

I noticed that 2 of your moves are on base.mc and the other two are on base.camera. If you haven’t disabled the mouse control of the camera, then the moves on the camera are not going to have any effect.

I am not familiar with parenting everything from base. Does that just make everything global? I don’t see anything being passed into your Controls function. Is Controls supposed to be a class? If so, then it should be declared as a class rather than with def. Seeing as you are defining more functions inside of controls, I am guessing that is what you intended.

finally, if Controls is a class, make sure it is instantiated before you execute your run() command. ie: ctrl=Controls() if it IS just a function, then you need to fix your indenting, and make sure that Controls is being called periodically to execute the code.

I disabled the mouse control, yes. I believe that parenting objects to base does that, since I did not start working in clases and its hard trying to switch in at the halfway mark in your project. What do you mean things being passed in? im confused. I tried editing my code to suggestions i read on this thread and whatever else I could find and I got:

def controls():
    base.keyMap={"left":0, "right":0, "forward":0, "back":0}
    base.accept("escape",sys.exit)
    base.accept("w",base.setKey, ["forward",1])
    base.accept("w-up",base.setKey,["forward",0])
    base.accept("a",base.setKey,["left",1])
    base.accept("a-up",base.setKey,["left",0])
    base.accept("d",base.setKey,["right",1])
    base.accept("d-up",base.setKey,["right",0])
    base.accept("s",base.setKey,["back",1])
    base.accept("s-up",base.setKey,["back",0])

    taskMgr.add(self.move,"moveTask")

    

def move(base, task):
    elapsed = task.time - base.prevtime
    
    base.prevtime = 0

    if (base.keyMap["left"]!=0):
        mc.setX(mc, - (elapsed*25))
        if (base.keyMap["right"]!=0):
            mc.setX(mc, + (elapsed*25))
        if (base.keyMap["forward"]!=0):
            mc.camera.setY(mc, + (elapsed*25))
        if (base.keyMap["back"]!=0):
            mc.setY(mc, - (elapsed*25))

        base.prevtime = base.time
        return Task.cont





run()

any better?

thank you for all of your help,

KOZ

What result did you get when you ran it?

The program ran with all the models I had put in, but the object didn’t move.

Are you calling Controls() anywhere in your script? You define it, but you need to make sure that you call it so it gets executed to add the event handlers and recurring task.

Also, I am not sure, but you may need to change the references to mc in your task to base.mc so that it gets the right reference. I may be wrong, but I think that the fact that it is not erroring out means that the task is not running.

Your indenting is wrong in your task as well. Everything is under the “left” if condition. Fix your indents as well.

Try adding some print lines to your task to see if it is executing at all. For example:

def move(base, task):
    elapsed = task.time - base.prevtime
   
    base.prevtime = 0

    if (base.keyMap["left"]!=0):
        base.mc.setX(mc, - (elapsed*25))
        print "Left!"
    if (base.keyMap["right"]!=0):
        base.mc.setX(mc, + (elapsed*25))
        print "Right!"
    if (base.keyMap["forward"]!=0):
        base.mc.camera.setY(mc, + (elapsed*25))
        print "Forward!"
    if (base.keyMap["back"]!=0):
        base.mc.setY(mc, - (elapsed*25))
        print "Back!"

    base.prevtime = base.time
    return Task.cont 

You should see the text printed in the window that you start the program from. It won’t be on your main display window.

Let me know what comes from that!

It apparently wasn’t running, so I took it out of the the function. turns out , it has to be in a class or else it won’t be able to run. so I’ll try that and let ya know how it works.

I have read the above and you guys keep saying ‘setting up in blender’.

  1. how do you setup and octree in blender
  2. is this question answered in a tutorial for blender?

If your using Chicken Exporter, I believe you click on the make Octree Button. This question is answered more in depth in the Chicken Help File.

Btw, how do you make classes be able to be used in the main line of code? I did the

c=World()

thing but it didn’t work. To test that it was running thru all the code I did this:

import direct.directbase.DirectStart

class Actor_j():
    def _init_(self):
        print "sumo JUDDDDO!"



person=Actor_j()

run()

It runs the program fine, but it doesn’t touch the Class :frowning: . any help?

regards,

KOZ

Your init function needs to have 2 underscores before and after, not just one, plus it neds to accept the reference to self. ie: def init(self):

not: def init():

Hey thanks, that part works, but now I’m havin’ issues with the actual code:

class MoveP(DirectObject):
    def __init__(self):

        d=Actor_j()#imports the character,environment and sets the camera

        def setKey(key,value):
            self.keyMap[key] = value

        self.keyMap={"left":0, "right":0, "forward":0, "back":0}
        self.accept("escape",sys.exit)
        self.accept("w",setKey, ["forward",1])
        self.accept("w-up",setKey,["forward",0])
        self.accept("a",setKey,["left",1])
        self.accept("a-up",setKey,["left",0])
        self.accept("d",setKey,["right",1])
        self.accept("d-up",setKey,["right",0])
        self.accept("s",setKey,["back",1])
        self.accept("s-up",setKey,["back",0])

        self.isMoving = False

        
            
        def move(self, task):
            
            elapsed = globalClock.getDt()

            taskMgr.add(self.move,"moveTask")

            if (self.keyMap["left"]!=0):
                self.sichar.setH(self.sichar.getH() + elapsed*300)
            if (self.keyMap["right"]!=0):
                self.sichar.setH(self.sichar.getH() - elapsed*300)
            if (self.keyMap["forward"]!=0):
                self.sichar.setY(self.sichar, -(elapsed*25))

            if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
                if self.isMoving is False:
                    self.sichar.loop("run")
                    self.isMoving = True
                else:
                    if self.isMoving:
                        self.sichar.stop()
                        self.isMoving = False

the character isn’t moving when i press the wasd keys. Anything I can do to make my character move? Is there an easier way to make the character move?

Ok, I made some progress, but I’m getting an error. I put this in:



moving=0

def forw():
      sichar.setY(self.sichar.getY()+1)
      moving=1

self.accept("w",forw)

Then I run the program. it goes well untill i press “W” on my keyboard it gives me this error:


Traceback (most recent call last):
  File "C:\Panda3D-1.6.2\direct\showbase\EventManager.py", line 61, in eventLoopTask
    self.doEvents()
  File "C:\Panda3D-1.6.2\direct\showbase\EventManager.py", line 55, in doEvents
    processFunc(self.eventQueue.dequeueEvent())
  File "C:\Panda3D-1.6.2\direct\showbase\EventManager.py", line 124, in processEvent
    messenger.send(eventName)
  File "C:\Panda3D-1.6.2\direct\showbase\Messenger.py", line 309, in send
    self.__dispatch(acceptorDict, event, sentArgs, foundWatch)
  File "C:\Panda3D-1.6.2\direct\showbase\Messenger.py", line 371, in __dispatch
    method (*(extraArgs + sentArgs))
  File "C:\Documents and Settings\Owner\My Documents\Project B.A.M-Chaos Reigns\Code\FacelessChronicles\src\FacelessChronicles.py", line 47, in forw
    sichar.setY(self.sichar.getY()+1)
AttributeError: Actor_j instance has no attribute 'sichar'
:task(error): Exception occurred in PythonTask eventManager
Traceback (most recent call last):
  File "C:\Documents and Settings\Owner\My Documents\Project B.A.M-Chaos Reigns\Code\FacelessChronicles\src\FacelessChronicles.py", line 80, in <module>
    run()
  File "C:\Panda3D-1.6.2\direct\showbase\ShowBase.py", line 2423, in run
    self.taskMgr.run()
  File "C:\Panda3D-1.6.2\direct\task\TaskNew.py", line 471, in run
    self.step()
  File "C:\Panda3D-1.6.2\direct\task\TaskNew.py", line 429, in step
    self.mgr.poll()
  File "C:\Panda3D-1.6.2\direct\showbase\EventManager.py", line 61, in eventLoopTask
    self.doEvents()
  File "C:\Panda3D-1.6.2\direct\showbase\EventManager.py", line 55, in doEvents
    processFunc(self.eventQueue.dequeueEvent())
  File "C:\Panda3D-1.6.2\direct\showbase\EventManager.py", line 124, in processEvent
    messenger.send(eventName)
  File "C:\Panda3D-1.6.2\direct\showbase\Messenger.py", line 309, in send
    self.__dispatch(acceptorDict, event, sentArgs, foundWatch)
  File "C:\Panda3D-1.6.2\direct\showbase\Messenger.py", line 371, in __dispatch
    method (*(extraArgs + sentArgs))
  File "C:\Documents and Settings\Owner\My Documents\Project B.A.M-Chaos Reigns\Code\FacelessChronicles\src\FacelessChronicles.py", line 47, in forw
    sichar.setY(self.sichar.getY()+1)
AttributeError: Actor_j instance has no attribute 'sichar'

Any ideas what could be causing it?
Thank you,

KOZ

The last couple lines of the traceback:


\FacelessChronicles\src\FacelessChronicles.py", line 47, in forw
    sichar.setY(self.sichar.getY()+1)
AttributeError: Actor_j instance has no attribute 'sichar' 

are telling you that it cannot find the reference to sichar. Where are you defining it? you need to make sure you have a reference to the class that it is in so that it can read the getY value.

In the first post, I noticed 2 things right away.

1: the line d=Actor_j()

d is only going to exist inside the init function, and will be destroyed at the end of the function. This is probably not what you want. Instead, use:

self.d=Actor_j()

Do you see the definition of the init function, where you are passing in a variable ‘self’?

def initb[/b]:

This is a reference to the class that is being initialized. Any variables that you define as self.someVariable will exist for all functions inside of the class. If the character, environment, etc. all exist in Actor_j() then d, which is the reference that everything in MoveP is going to use to access what is in Actor_j(), needs to be created as self.d so that the other functions (like move) can find it.

Inside move, then, if you need to modify or read or do anything to something that is defined inside Actor_j, you will use:

self.d.someValue

to access it. If your main actor is called sichar, for example, you would, in theory, use:

self.d.sichar.setY(self.d.sichar.getY()+elapsed*25)

This ASSUMES that somewhere in Actor_j you have defined something as

self.sichar=Actor(actor information in here)

again, using the self.xxx syntax ensures that sichar will exist after the function finishes running.

The other thing I noticed is the line:



            taskMgr.add(self.move,"moveTask") 

should be inside the init function instead of inside the move function. If it is inside move, it never runs, since move has never been called anywhere else. By putting it inside init you make sure that the task gets started, and runs each frame. At the end of move, remember to

return task.cont

so that it gets put back into the queue to run again next frame.

In summary:

make sure that anything that is not a temporary working variable inside the function gets defined with the self.xxx format to make sure it exists inside the entire class. Do a bit of internet reading about scope and Python. I think a lot of your trouble is coming from a misunderstanding of how Python handles variable scope.

Make sure that sichar exists somewhere, and that there is a reference to it inside the MoveP class so that you can manipulate the actor.

Hope this makes sense! Let me know how it goes.

EDIT: Fix the task.cont info…

I think I will have to review classes in Python before I continue my project. Thanks for all the help and I’ll try what you suggested.

Thanks.

hey guys. i’m back and hope to be more productive now.