I'm making some kind of RPG-styled game and I am trying to implement the Zombie looking direction. I have a Zombie class and Zombies are supposed to follow the player. I determine the Zombie direction (where he is going) by calculating the degree of the (player position - zombie position) to a vector, which is parallel to the x-axis and by using this degree in some if-elif blocks I determine the Zombie-moving. (for example "self.vel = vec(zombieSpeed,0)")
The code is working fine, but when the Zombie crosses one of the degrees of 22.5 + 45* the zombiedirection is changing in the frequency of the game update, because in the next followObject(...)-call the velocity of the zombie changes to another direction.
At first: I made a variable vec at the top of the Zombie class:
vec = pg.math.Vector2
Now the Zombie follow Object, where the moving speed and direction is set:
def followObject(self, entity):
degree = (self.game.player.newPos - self.newPos).angle_to(vec(1,0))
if (degree > -22.5 and degree <= 22.5):
self.vel = vec(zombieSpeed,0)
elif (degree > 22.5 and degree <= 67.5):
self.vel = vec(zombieSpeed,-zombieSpeed)
elif (degree > 67.5 and degree <= 112.5):
self.vel = vec(0,-zombieSpeed)
elif (degree > 112.5 and degree <= 157.5):
self.vel = vec(-zombieSpeed,-zombieSpeed)
elif (degree > 157.5 and degree <= 180) or (degree <= -180 and degree >= -157.5):
self.vel = vec(-zombieSpeed,0)
elif (degree > -157.5 and degree <= -112.5):
self.vel = vec(-zombieSpeed,zombieSpeed)
elif (degree > -112.5 and degree <= -67.5):
self.vel = vec(0,zombieSpeed)
elif (degree > -67.5 and degree <= -22.5):
self.vel = vec(zombieSpeed,zombieSpeed)
if self.vel.x != 0 and self.vel.y != 0:
self.vel *= math.sqrt(2)/2
And I created this Method to determine, where characters have to look:
def getDirectionLooking(self, oldPos, newPos):
vecPosition = newPos - oldPos
degree = vecPosition.angle_to(vec(1,0))
if self.isMoving == True:
if (degree >= -45 and degree <= 45):
return 'r' #character right sprites
elif (degree > 45 and degree < 135):
return 'b' #character back sprites
elif (degree >= 135 and degree <= 180) or (degree >= -180 and degree <= -135):
return 'l' #character left sprites
elif (degree < -45 and degree > -135):
return 'f' #character front sprites
else:
return self.oldDir
This is the update function for the Zombie, which is repeated every gametick:
def update(self):
print(self.newDir,end=' ')
self.followObject(self.followEntity) #followEntity is the playerinstance
self.oldPos = vec(self.newPos)
self.newPos += self.vel * self.game.dt
self.newDir = self.getDirectionLooking(self.oldPos, self.newPos)
self.animationUpdate(self.newDir)
self.rect.x = self.newPos.x
self.collideWithWalls('x')
self.rect.y = self.newPos.y
self.collideWithWalls('y')
So I need a method, where I can make the Zombie follow the character without this 'bug'. But I still want the Zombie to only be able to move to 8 directions.
output of Zombie direction:
l f f f f f f f f f f l l f f f l f f l l f l f
Here is the project: