Home > Mobile >  How to move a sprite in a smooth way?
How to move a sprite in a smooth way?

Time:02-01

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))

  •  Tags:  
  • Related