Home > Back-end >  Problems with moving an enemy towards a character in pygame
Problems with moving an enemy towards a character in pygame

Time:01-02

I am having problems with making a homing algorithm to move an enemy towards a player in a game. For some reason, the algorithm works sometimes, but as you move the player around, the enemy gets to points where it just stops even though there is still a difference between the player x and y variables and the enemy x and y variables (which the code should be applying to the enemy at all times). If you run the code you'll see what I mean.

Here is my code:

import pygame
import sys, os, random
from pygame.locals import *
from pygame import mixer
import math

clock = pygame.time.Clock()

screen_width = 700
screen_height = 700 
screen = pygame.display.set_mode((screen_width, screen_height))

player_rect = pygame.Rect(200, 200, 10, 10)
moving_left = False 
moving_right = False 
moving_down = False 
moving_up = False

hunter_rect = pygame.Rect(500, 500, 48, 60)

player_rect.x = 300 
player_rect.y = 200
while True:
    screen.fill((50, 50, 50))


    #screen.blit(player, (player_rect.x, player_rect.y))
    #screen.blit(hunter, (hunter_rect.x, hunter_rect.y))
    pygame.draw.rect(screen, (255, 255, 255), player_rect)
    pygame.draw.rect(screen, (255, 0, 0), hunter_rect)

    #### getting the change in y and the change in x from enemy to player ###
    ychange = (hunter_rect.y - player_rect.y)/100
    xchange = (hunter_rect.x - player_rect.x)/100   


    hunter_rect.x -= xchange
    hunter_rect.y -= ychange


    if moving_left:
        player_rect.x -= 4
    if moving_right:
        player_rect.x  = 4
    if moving_up:
        player_rect.y -= 4
    if moving_down:
        player_rect.y  = 4

    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
            pygame.quit()
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()
            if event.key == K_a:
                moving_left = True 
            if event.key == K_d:
                moving_right = True 
            if event.key == K_s:
                moving_down = True
            if event.key == K_w:
                moving_up = True
        if event.type == KEYUP:
            if event.key == K_a:
                moving_left = False 
            if event.key == K_d:
                moving_right = False
            if event.key == K_w:
                moving_up = False 
            if event.key == K_s:
                moving_down = False
    
    pygame.display.update()
    clock.tick(60) 

CodePudding user response:

Since pygame.Rect is supposed to represent an area on the screen, a pygame.Rect object can only store integral data.

The coordinates for Rect objects are all integers. [...]

The fraction part of the movement gets lost when the movement is add to the position of the rectangle.
If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables and to synchronize the pygame.Rect object. round the coordinates and assign it to the location (e.g. .topleft) of the rectangle:

hunter_rect = pygame.Rect(500, 500, 48, 60)
hunter_x, hunter_y = hunter_rect.topleft

# [...]
while True:
    # [...]

    hunter_x -= xchange
    hunter_y -= ychange
    hunter_rect.topleft = round(hunter_x), round(hunter_y)

    # [...]
  • Related