In my code I have a zombie that looks to a player and follows it, it is ok for the player to move up/down left/right or in diagonals because the person controlling is using the arrows on the keyboard, but for the zombie it feels very weird not to have a large range of directions it can go, the discrepancy got very weird when I added the fact that the zombie had a free range of motion to look at the player but not to walk directly in its direction. What changes can I make to make his movement more smooth?
this is how I move the player:
playerSprite.vel = 3
playerSprite.x = (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * playerSprite.vel
playerSprite.y = (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * playerSprite.vel
this is how I move the zombie:
zombieSprite.vel = 1
if zombieSprite.x > playerSprite.x:
zombieSprite.x -= zombieSprite.vel
if zombieSprite.x < playerSprite.x:
zombieSprite.x = zombieSprite.vel
if zombieSprite.y > playerSprite.y:
zombieSprite.y -= zombieSprite.vel
if zombieSprite.y < playerSprite.y:
zombieSprite.y = zombieSprite.vel
CodePudding user response:
How to make smooth movement in pygame. You can use the following function to make an enemy follow a player smoothly:
LERP_FACTOR = 0.05
minimum_distance = 25
maximum_distance = 100
def follow_me(target_pos, follower_pos):
target_vector = pygame.math.Vector2(*target_pos)
follower_vector = pygame.math.Vector2(*follower_pos)
new_follower_vector = pygame.math.Vector2(*follower_pos)
distance = follower_vector.distance_to(target_vector)
if distance > minimum_distance:
direction_vector = (target_vector - follower_vector) / distance
min_step = max(0, distance - maximum_distance)
max_step = distance - minimum_distance
step_distance = min_step (max_step - min_step) * LERP_FACTOR
new_follower_vector = follower_vector direction_vector * step_distance
return (new_follower_vector.x, new_follower_vector.y)
Call the function and assign the return value back to the zombies position:
zombieSprite.x, zombieSprite.y = follow_me(
(playerSprite.x, playerSprite.y), (zombieSprite.x, zombieSprite.y))
CodePudding user response:
@Rabbid76 solution is good, but in case you don't want such "complicated" solution you can do the following: convert the difference in position to polar coordinates, and then split your zombie velocity into x and y vectors based on the angle from polar coordinates.
import numpy as np
from math import sin, cos
def cart2pol(x, y):
rho = np.sqrt(x**2 y**2)
phi = np.arctan2(y, x)
return(rho, phi)
class Pos:
def __init__(self, x, y):
self.x = x
self.y = y
player = Pos(5, 1)
zombie = Pos(3, 2)
diff = Pos(player.x - zombie.x, player.y - zombie.y)
dist, angle = cart2pol(diff.x, diff.y)
zombieVelocity = 0.5
newZombiePos = (zombie.x zombieVelocity * cos(angle), zombie.y zombieVelocity * sin(angle))
print(newZombiePos)
CodePudding user response:
this is a solution i think is good using the module import pygame
win = pygame display.set_mode((size, size))
