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)
# [...]