4

I am making a top-down shooter and want my zombie to follow my character, and my program uses a main loop. The position of my character is x and y and he is controlled by the arrow keys. I have a zombie that as of right now randomly spawns at the left edge of the screen when shot at. How can I make the zombie follow my position from where it spawns?

This is the zombie function:

def makezombie():
    global zom
    zom = Rect (0,randint(0, height-40), 49, 38)
    return zom

I set zombie=makezombie()

In my main loop I have the following:

for shot in shots:
    if zombie.collidepoint(shot[X],shot[Y]):
        zombie=makezombie()
        points+=1000
        impact.play()
        blood.play()
Andre
  • 59
  • 1
  • 3

2 Answers2

6

I'm not sure I fully understand the question but essentially what you can do is take the players (x, y) coordiantes and the zombies (x, y) coordinate. Assuming (xp, yp) are the players coordinates and (xz, yz) are the zombies, you can use the following algorithm to find the direction from the zombie to the player:

import math
(dx, dy) = ((xp - xz)/math.sqrt((xp - xz) ** 2 + (yp - yz) ** 2), 
            (yp - yz)/math.sqrt((xp - xz) ** 2 + (yp - yz) ** 2))

Then in the main loop you want to update the zombies x and y position coordinates by doing newCoord = (xp + dx * spped, yp + dy * speed) where speed is some number of pixels that you want the zombie to move per loop. Then redraw the zombie at this new position.

Hope that helps! If not, please clarify the question.

user1413793
  • 9,057
  • 7
  • 30
  • 42
  • 1
    Why not use math.sqrt instead of ** 0.5? – sloth Jun 11 '12 at 06:46
  • Either one works but I prefer not to import too many modules if I don't have to. I'm really not sure if one is better over the other although I will admit math.sqrt is probably more understandable to someone reading the code. – user1413793 Jun 11 '12 at 07:47
  • On my laptop (Python 2.7 under Ubuntu), using ``math.sqrt`` is twice as fast when measured using the ``timeit.timeit()`` function. ``math.sqrt`` takes around 631ns per calculation (averaged over 1 million) while ``x**0.5`` takes about 1260ns. Not a big difference taken individually, but if you are doing a large number of calculations in a loop, say when updating the positions of a large number of characters in a game, it could make quite a difference... – Blair Jun 11 '12 at 09:23
  • To measure the ** route: ``import timeit; timeit.timeit('y = x**0.5', 'x=101398', number=1000000)``. To measure the math.sqrt() method: ``import timeit; timeit.timeit('y = sqrt(x)', 'from math import sqrt; x=101398', number=1000000)``. – Blair Jun 11 '12 at 09:24
  • 1
    Ah didn't realize math.sqrt was faster. Well that would be a reason to start using that. Thanks! – user1413793 Jun 11 '12 at 16:59
1

If you know about vector math ( ie: euclid ), you can use vector subtraction.

zombie_speed = 50 # pixels / an update
player = Vector2(player.rect.x, player.rect.y)
zombie = Vector2(zombie.rect.x, zombie.rect.y)
movement = player - zombie
movement.normalize()
movement *= zombie_speed

Then add movement's x,y values to zombie's Rect()

ninMonkey
  • 7,211
  • 8
  • 37
  • 66