How to Move Sprite to a Specific Location Without Keys

Issue

Im trying to make a game with pygame where I can click a sprite then click somewhere on the screen for the sprite to move towards. So far, I’m able to click the sprite and get a response but I’m not sure how to tell the sprite to go to a given location where I click. I’ve seen something online with sprite.goal but I can’t seem to make it work.
This is what I have

if event.type==pygame.MOUSEBUTTONDOWN:
   pos=pygame.mouse.get_pos()
   #White is a rectangle
   if White.collidepoint(pos): 
      Moving=True
   elif Moving==True:
   #This is where I would tell it to move to pos

Solution

I’ll show you a very simple example. Write a function that moves a point 1 step to a target point and returns the new position:

def move_to_target(pos, target):
    x, y = pos
    if x < target[0]:
        x += 1
    elif x > target[0]:
        x -= 1
    if y < target[1]:
        y += 1
    elif y > target[1]:
        y -= 1
    return (x, y)

Set a new target when the mouse button is pressed and call the function at each frame:

import pygame

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

def move_to_target(pos, target):
    x, y = pos
    if x < target[0]:
        x += 1
    elif x > target[0]:
        x -= 1
    if y < target[1]:
        y += 1
    elif y > target[1]:
        y -= 1
    return (x, y)

my_sprite = pygame.Surface((20, 20), pygame.SRCALPHA)
pygame.draw.circle(my_sprite, (255, 255, 0), (10, 10), 10)
pos = (200, 200)
target = (200, 200)

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 
        if event.type == pygame.MOUSEBUTTONDOWN:
            target = event.pos
        
    pos = move_to_target(pos, target)

    window.fill(0)
    window.blit(my_sprite, pos)
    pygame.display.flip()
    clock.tick(100)

pygame.quit()
exit()

For variable speed and a straighter and smoother movement, you need to tweak the function. See How to make smooth movement in pygame.

import pygame

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

LERP_FACTOR      = 0.05
minimum_distance = 0
maximum_distance = 100

def move_to_target(pos, target):
    target_vector       = pygame.math.Vector2(*target)
    follower_vector     = pygame.math.Vector2(*pos)
    new_follower_vector = pygame.math.Vector2(*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) 

my_sprite = pygame.Surface((20, 20), pygame.SRCALPHA)
pygame.draw.circle(my_sprite, (255, 255, 0), (10, 10), 10)
pos = (200, 200)
target = (200, 200)

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 
        if event.type == pygame.MOUSEBUTTONDOWN:
            target = event.pos
        
    pos = move_to_target(pos, target)

    window.fill(0)
    window.blit(my_sprite, pos)
    pygame.display.flip()
    clock.tick(100)

pygame.quit()
exit()

Answered By – Rabbid76

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published