Problem automatically moving objects

 def update_zombie(self, task):
        self.zombie = [x for x in self.zombie if x.getPythonTag("HP") > 0] 
        for i in self.zombie:


            zdummy = i.getPythonTag("ZDummy")
            
            zdummy.lookAt(self.cam)
            zdummy.setH(zdummy.getH()-180)

            if i.getPythonTag("justHit") == False and i.getPythonTag("next2Protag") == False:
                i.setH(zdummy.getH())
                i.setY(i, -.2)
            if i.getPythonTag("next2Protag") == True and i.getPythonTag("justHit") == False:
                i.setPythonTag("justHit", True)
                self.playerHP = ((self.playerHP)-10)
                i.setPythonTag("justHit", True)
                self.taskMgr.doMethodLater(.5, self.resetZombieHit, "reset zombie hit", extraArgs = [i])
            
        return task.cont

And the zombies are not moving correctly. What’s going on?

What do you mean by “not moving correctly”? What do you expect to get, and what do you get?

Off-hand, I note that you’re not taking into account the time between frames: in short, the amount of time between calls of your update method may not be constant. This means that the speed of the zombies may vary, producing movement that likely doesn’t look good and the speed of which may depend on the speed at which the game runs on a given computer.

To rectify this, get the time since the last frame (look here) and multiply it by your desired speed, likely first increasing the number that you use for that to account for the fact that the time between frames will likely be less than 1.0.

I expect the zombies to move towards me. Instead they move pretty erratically. It’s hard to describe.

this spawns zombies.

def spawnWave(self):
        self.abc = True
        for x in range(self.maxZombieInThisWave):
            realRowUp = None
            lastDigit = None
            rowLeft = None
            rowUp = None
            i = x+1
            self.zombie.append("blank")
            self.zombie[x] = loader.loadModel("zombie")
            self.zombie[x].reparentTo(render)
            r = x/3
            rowUp = str(r)[0]
            length = len(str(x))
            
            lastDigit = str(x)[(length)-1]

            if lastDigit == 1 or 4 or 7 or 0:
                rowLeft = 1505.4
            if lastDigit == 2 or 5 or 8:
                rowLeft = 1502.9
            if lastDigit == 3 or 6 or 9:
                rowLeft == 1498.2

            
            
            if rowUp == '1' or '0':
                realRowUp = 245.3
            if rowUp == '2':
                realRowUp = 155.3
            if rowUp == '3':
                realRowUp = -14.6

            
            self.zombie[x].setPos((rowLeft), (realRowUp), 12)
            self.zombie[x].setScale(5)
            self.zombie[x].setP(0)
            self.zombie[x].setR(0)
            self.zombie[x].setPythonTag("HP", 100)
            self.colNode.append(None)
            self.zombie[x].setPythonTag("COLNODE", self.colNode[x])
            self.colNode[x] = self.zombie[x].attachNewNode(CollisionNode("z"))
            self.colNode[x].setPythonTag("ZOMBIE", self.zombie[x])
            
            self.colNode[x].show()
            self.colNode[x].node().addSolid(CollisionTube(0, 0, 20, 0, 0, -20, 50000))
            
            self.zdummy.append(None)
            self.zdummy[x] = self.loader.loadModel("smiley")
	    self.zdummy[x].hide 
	    self.zombie[x].setPythonTag("ZDummy", self.zdummy[x])
            
            

            self.zombie[x].setPythonTag("next2Protag", False)
            self.zombie[x].setPythonTag("justHit", False

changed updatezombie while bugfixing, still don’t work tho:

def update_zombie(self, task):
        self.zombie = [x for x in self.zombie if x.getPythonTag("HP") > 0] 
        for i in self.zombie:


            zdummy = i.getPythonTag("ZDummy")
            zdummy.setPos(i.getPythonTag("ZDummy").getPos())
            zdummy.lookAt(self.cam)
            zdummy.setH(zdummy.getH()-180)

            if i.getPythonTag("justHit") == False and i.getPythonTag("next2Protag") == False:
                i.setH(zdummy.getH())
                i.setY(i, -.2)
            if i.getPythonTag("next2Protag") == True and i.getPythonTag("justHit") == False:
                i.setPythonTag("justHit", True)
                self.playerHP = ((self.playerHP)-10)
                i.setPythonTag("justHit", True)
                self.taskMgr.doMethodLater(.5, self.resetZombieHit, "reset zombie hit", extraArgs = [i])
            
        return task.cont

I have no idea what’s causing your problem because I can’t read your code. I suggest you spend more time learning Python itself before trying to make something as complex as a zombie.

I can’t really offer any specific help because just about every aspect of your code is wrong, if not logically then pythonically.

I will suggest that you make a Zombie class, though. It should contain a reference to the model and the information you’re currently getting with “getPythonTag”. But more importantly, your update_zombie() task shouldn’t know /anything/ about what a zombie is or does. It should only know that the Zombie objects you’re now using has a method called update() or move() or something similar. The Zombie class should define how a zombie moves and attacks, not a task.

One minor point: it’s really confusing that you’ve called a list of zombies self.zombie. It makes it look like it refers to a zombie and not a collection of them.

Also, lines such as “self.zombie = [x for x in self.zombie if x.getPythonTag(“HP”) > 0]” are a bad idea. If you change the implementation of zombie such that it no longer has a python tag HP, this breaks. You should probably encapsulate this in a method such as self.getAliveZombies(), which asks each of your zombies whether it is alive and returns those that say yes. This way, whether a zombie is alive is ultimately decided by the zombie class itself, and so if you ever change how that class handles whether it’s alive, you won’t break any other code in the process.

Basically, you should never have a situation where one thing relies on another thing being structured a specific way (such as having a specific tag with a specific name). You should instead provide methods like isAlive() or getPos() (these are usually called setters and getters). That way, when you change the class’s structure (and you will), you only need to update the setters and getters and not every single instance of where you accessed that structure by hand.

Referring to the last part (regarding the “[x for x in…]” section), I don’t know your intended meaning, Tober, but I don’t think that there’s a problem with the “[x for x in…]” approach; I do agree that it would probably be wise to create a zombie class, have that include a method along the lines of “isAlive”, and then change that line to “self.zombies = [x for x in self.zombies if x.isAlive()]”

It may be that this is what you meant; I’m afraid that I wasn’t sure after reading those two paragraphs, and wanted to clarify and give my opinion.

Otherwise, I believe that I largely agree with you and second your advice. :slight_smile:

aw f :frowning: ck

Guess this is too hard for me… I’ll get there one day though, and I will never stop programming. I want to finish this.

Edit: I’ll drop this project and pick up something easier, maybe come back. Do you guys think this is a good idea?

Thanks.

It might be.

Nevertheless, I agree on another point: don’t give up. It might take some work, but programming is something that can very much be improved through experience, I believe.

Do you know much about object-oriented programming yet? If not, you might look up a tutorial on it, as it can be a rather useful concept.

If you do know object-orientation, then here’s a thought:

Start a new project, at first displaying only a blank screen.

Next, create a new class to encapsulate a game object, intended to be a parent class to most objects, both player and enemy. Decide which elements are common (such as having a model, for example), and have it handle those. Give it appropriate methods, and be careful to give both its methods and attributes clear names.

That done, use it to implement a player character; depending on your desires for this, the player character could be just an instance of the above class, controlled by code in the class that handles your overall logic, or you might have a child class for players.

Once that is working, and you can move your character around a little, create a new sub-class of your “game object” class to handle enemies. Use that to place a single enemy into your game, and then implement some code to allow you to kill it.

Continue on from there! :slight_smile:

Yeah, i know about oop. I’ve already done this with my zombie program, but it got hard when I tried to control multiple at the same time. I didn’t know you could make multiple classes with panda :open_mouth:

I think I’ll try making a “running fred” game. Starting off real basic and then becoming more like the above game.