pygame 2 dimensional movement of an enemy towards the player, how to calculate x and y velocity?
Solution 1:
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:
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