Pygame 2 Dimensional Movement of an Enemy Towards the Player, How to Calculate X and Y Velocity

pygame 2 dimensional movement of an enemy towards the player, how to calculate x and y velocity?

Compute the vector from the the enemy position to the the player position:

dx = player_x - enemy_x
dy = player_y - enemy_y

Compute the length of the vector (Euclidean distance):

dist = math.sqrt(dx*dx + dy*dy)

or

dist = math.hypot(dx, dy)

Normalize the vector (Unit vector). A normalized vector has a length of 1:

if dist > 0:
dx /= dist
dy /= dist

Move the enemy a certain distance in the direction of the vector. Make sure the moving distance is no greater than the remaining distance of the enemy to the player:

move_dist = min(enemy_vel, dist)

enemy_x += move_dist * dx
enemy_y += move_dist * dy

For a more sophisticated solution see How to make smooth movement in pygame

See also Follow target or mouse


Minimal example:

Sample Image

import pygame, math

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
player_x, player_y, player_vel = 100, 100, 5
enemy_x, enemy_y, enemy_vel = 300, 300, 3

run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False

keys = pygame.key.get_pressed()
player_x = max(10, min(390, player_x + player_vel * (keys[pygame.K_d] - keys[pygame.K_a])))
player_y = max(10, min(390, player_y + player_vel * (keys[pygame.K_s] - keys[pygame.K_w])))

dx = player_x - enemy_x
dy = player_y - enemy_y
dist = math.hypot(dx, dy)
if dist > 0:
enemy_x += min(enemy_vel, dist) * dx / dist
enemy_y += min(enemy_vel, dist) * dy / dist

window.fill(0)
pygame.draw.circle(window, (0, 128, 255), (player_x, player_y), 10)
pygame.draw.circle(window, (255, 32, 32), (enemy_x, enemy_y), 10)
pygame.display.flip()

pygame.quit()
exit()

For your particular code, the calculate_enemy_movement function might look like this:

def calculate_enemy_movement(enemy_blob):
dx = player.player_rect.x - enemy_blob.x
dy = player.player_rect.y - enemy_blob.y
dist = math.hypot(dx, dy)
if dist > 0:
move_x = min(enemy_blob.speed, dist) * dx / dist
move_y = min(enemy_blob.speed, dist) * dy / dist
return move_x, move_y
return 0, 0
move_x, move_y = calculate_enemy_movement(enemy_blob)
enemy_blob.x += move_x
enemy_blob.y += move_y

Make moving more realistic

You need to calculate the direction vector, normalize it and multiply it with the desired speed, then apply that to the circles position.

The easiest way is to use pygame's built-in Vector2 class for this:

import pygame

def main():
pygame.init()
screen = pygame.display.set_mode((600, 600))
pos = pygame.Vector2()
clock = pygame.time.Clock()
speed = 10
while True:

for e in pygame.event.get():
if e.type == pygame.QUIT:
return

movement = pygame.mouse.get_pos() - pos
if movement.length() > 6: # some margin so we don't flicker between two coordinates
if movement.length() > 0: # when we move, we want to move at a constant speed
movement.normalize_ip()
pos += movement * speed # change the position

screen.fill((20, 20, 20))
pygame.draw.circle(screen, 'dodgerblue', pos, 30)
pygame.display.flip()
clock.tick(30)

main()

Sample Image

How to move a object in straight line in pygame?

Compute the direction vector from the object to the target. Normalize the direction vector (Unit vector). Scale the vector to a certain length and add the vector to the position:

dx = x_cord[0]-roborect.x
dy = y_cord[0]-roborect.y
distance = math.sqrt(dx*dy + dy*dy)
if distance > 15:
vx = dx * 5 / distance
vy = dy * 5 / distance
roborect.x += vx
roborect.x += vy


Related Topics



Leave a reply



Submit