[Solved] Movement changes after beaming


#1

Hi there,

I made a dungeon crawler/maze runner. In the maze is a ghost. If he catches you, you get beamed back to the start. But after getting beamed to the start, the move velocity changes. Before everything is fine the character walks like he should. But after getting caught, the player moves the distance where he would need 2 to 3 secondes for with one tip of the key.
Code used to beam the character back to the beginning(100% the same function like the character is positioned for the first time!):

self.ownNode.setPos(-self.offset/2,-(self.offset/2)-self.entrance*self.offset,-1)
self.ownNode.setHpr(-90,-6.95,0)

Code to move the player forward:
z_pos=self.ownNode.getPos().get_z()
self.ownNode.setPos(self.ownNode,0, self.moveVelocity * dt,0)
self.ownNode.setPos(self.ownNode.getPos().get_x(),self.ownNode.getPos().get_y(),z_pos)

Debugging already showed that dt and self.moveVelocity do not change.
self.moveVelocity is set only outside of the functions at the beginning of the class:
moveVelocity=7.5

Also after getting caught the hud freezes and winning is not possible anymore I don’t understand why.
The part of the code of the ghost catching the player:

    #got anybody??? collision
    self.catchcTrav.traverse(render)
    entries = list(self.catchHandler.getEntries())
    alreadycaught=False
    for caught in entries:
     if re.match("player\d",caught.getIntoNode().getName()):
      if not alreadycaught:
       alreadycaught=True
       self.actor.stop(self.actor.getCurrentAnim())
       self.actor.play('catch')
       self.status="catch"
      number=int(re.search('\d',caught.getIntoNode().getName()).group(0))
      self.playerCaught.append(number)
      self.caughtdisabled=False;
      taskMgr.doMethodLater(0.1,self.catchTask,'ghosteating')
      if alreadycaught:
       return task.done

Here is the task moving the players back to the beginning:

    def catchTask(self,task):
     if not self.caughtdisabled:
      for i in self.playerCaught:
       self.base.players[i-1].disableControls()
      self.caughtdisabled=True;
      catchcontrol=self.actor.getAnimControl('catch')
      if catchcontrol.isPlaying():
       #got anybody??? collision
       self.catchcTrav.traverse(render)
       entries = list(self.catchHandler.getEntries())
       for caught in entries:
        if re.match("player\d",caught.getIntoNode().getName()):
         number=int(re.search('\d',caught.getIntoNode().getName()).group(0))
         self.playerCaught.append(number)
         self.base.players[number-1].disableControls()
       return task.cont
       else:
         #animation done, move back to the beginning and reenable controls
         for i in self.playerCaught:
          self.base.players[i-1].setStart()
          self.base.players[i-1].enableControls()
         #remove ghost
         self.getAway()

PS: How to enable proper indentation when posting here? # Thanks serega-kkz


#2
``` python
 
 "code"

```

This is clearly a problem with logic, but it should be clear to you as a creator what happens where and when.


#3

Further investigations show that if I do not call self.base.players[i-1].disableControls() and self.base.players[i-1].enableControls() the players can move freely/with the right speed/velocity afterwards. But also while they are caught which should not be the case.
So here is the source of those two:

    def enableControls(self):
        if self.number==1:
            self.base.accept("arrow_left", self.setKey, ["left", True])
            self.base.accept("arrow_right", self.setKey, ["right", True])
            self.base.accept("arrow_up", self.setKey, ["forward", True])
            self.base.accept("arrow_down", self.setKey, ["backward", True])
            if self.useItems:
                self.base.accept("lcontrol", self.setAction, ["use", True])
                self.base.accept("r", self.setAction, ["get", True])
            self.base.accept("arrow_left-up", self.setKey, ["left", False])
            self.base.accept("arrow_right-up", self.setKey, ["right", False])
            self.base.accept("arrow_up-up", self.setKey, ["forward", False])
            self.base.accept("arrow_down-up", self.setKey, ["backward", False])
        elif self.number==2:
            self.base.accept("d", self.setKey, ["left", True])
            self.base.accept("g", self.setKey, ["right", True])
            self.base.accept("t", self.setKey, ["forward", True])
            self.base.accept("f", self.setKey, ["backward", True])
            if self.useItems:
                self.base.accept("a", self.setAction, ["use", True])
                self.base.accept("s", self.setAction, ["get", True])
            self.base.accept("d-up", self.setKey, ["left", False])
            self.base.accept("g-up", self.setKey, ["right", False])
            self.base.accept("t-up", self.setKey, ["forward", False])
            self.base.accept("f-up", self.setKey, ["backward", False])
        elif self.number==3:
            self.base.accept("j", self.setKey, ["left", True])
            self.base.accept("l", self.setKey, ["right", True])
            self.base.accept("i", self.setKey, ["forward", True])
            self.base.accept("k", self.setKey, ["backward", True])
            if self.useItems:
                self.base.accept("rcontrol", self.setAction, ["use", True])
                self.base.accept("rshift", self.setAction, ["get", True])
            self.base.accept("j-up", self.setKey, ["left", False])
            self.base.accept("l-up", self.setKey, ["right", False])
            self.base.accept("i-up", self.setKey, ["forward", False])
            self.base.accept("k-up", self.setKey, ["backward", False])
        elif self.number==4:
            self.base.accept("delete", self.setKey, ["left", True])
            self.base.accept("page_down", self.setKey, ["right", True])
            self.base.accept("home", self.setKey, ["forward", True])
            self.base.accept("end", self.setKey, ["backward", True])
            if self.useItems:
                self.base.accept("page_up", self.setAction, ["use", True])
                self.base.accept("c", self.setAction, ["get", True])
            self.base.accept("delete-up", self.setKey, ["left", False])
            self.base.accept("page_down-up", self.setKey, ["right", False])
            self.base.accept("home-up", self.setKey, ["forward", False])
            self.base.accept("end-up", self.setKey, ["backward", False])
         #walking saves if he moves for sound effects
        self.walking=False
        self.countWalkKeys=0
        #move saves if he can move/movetask is called
        self.move=True
        #taskMgr.add(self.moveTask, "moveTask")
        taskMgr.doMethodLater(1,self.moveTask, "moveTask")
	
    def disableControls(self):
        if self.number==1:
            self.base.ignore("arrow_left")
            self.base.ignore("arrow_right")
            self.base.ignore("arrow_up")
            self.base.ignore("arrow")
            self.base.ignore("lcontrol")
            self.base.ignore("r")
            self.base.ignore("arrow_left-up")
            self.base.ignore("arrow_right-up")
            self.base.ignore("arrow_up-up")
            self.base.ignore("arrow_down-up")
        elif self.number==2:
            self.base.ignore("d")
            self.base.ignore("g")
            self.base.ignore("t")
            self.base.ignore("f")
            self.base.ignore("a")
            self.base.ignore("s")
            self.base.ignore("d-up")
            self.base.ignore("g-up")
            self.base.ignore("t-up")
            self.base.ignore("f-up")
        elif self.number==3:
            self.base.ignore("j")
            self.base.ignore("l")
            self.base.ignore("i")
            self.base.ignore("k")
            self.base.ignore("rcontrol")
            self.base.ignore("rshift")
            self.base.ignore("j-up")
            self.base.ignore("l-up")
            self.base.ignore("i-up")
            self.base.ignore("k-up")
        elif self.number==4:
            self.base.ignore("delete")
            self.base.ignore("page_down")
            self.base.ignore("home")
            self.base.ignore("end")
            self.base.ignore("page_up")
            self.base.ignore("c")
            self.base.ignore("delete-up")
            self.base.ignore("page_down-up")
            self.base.ignore("home-up")
            self.base.ignore("end-up")
        self.keyMap["left"]=False
        self.keyMap["forward"]=False
        self.keyMap["backward"]=False
        self.keyMap["right"]=False
        self.keyMap["use"]=False
        self.keyMap["get"]=False
        self.move=False

The moveTask starts with:

        if not self.move:
            return task.done

and ends with:

        if self.move:
            return task.cont

So that setting self.move=False in disableControls should stop it.

Printing how often the movement is called shows me that moving forward is called 205(!) times in one frame when this bug occurs!!! So the question is: WHY? (taskMgr.remove(“moveTask”) in disableControls does not change anything)

Finally got it and asking myself why i have not seen this earlier:
while the ghost is “eating” one person, it is looking for other persons running into him and eating them, too. Of course the players which are already caught are detected there, too… so as long as the animation is running, it is adding the player which is already caught into the list of people caught… Having one player in that list over 200 times.
So in catchTask i changed it:

                    if not number in self.playerCaught:
                        self.playerCaught.append(number)
                        self.base.players[number-1].disableControls()