https://i.sstatic.net/jjDi8.jpg
Sorry for the lag, but as visible my enemies(green) spawn but after if i move my player(gray) they sometimes stop moving until i move my player again.
But even after moving my player the pre existing enemies dont move closer to the player and retain their distance to the player
this is the file which contains the main loop of the game
this is the file which contains the player class
this is the file which contains the enemy class
and this is the file which is the main run file
i feel the problem exists in my main loop class which is as follows:
import pygame, random
from Folder.scripts.TopDown.script_files.td_Player import Player
from Folder.scripts.TopDown.script_files.td_enemy import Enemy
from Folder.scripts.TopDown.script_files.td_colours import colours
pygame.init()
class Main:
def __init__(self):
self.FPS = 60
self.WIDTH = self.HEIGHT = 1280
self.MAP = pygame.Surface((self.WIDTH, self.HEIGHT))
self.enemies = []
def main(self,WINDOW ,clock):
WINDOW.fill(colours['white'])
player = Player()
camera_pos = (0, 0)
enemy_time = 0
run = True
while run:
clock.tick(self.FPS)
enemy_y = random.randint(0, 1220)
enemy_x = random.randint(0, 1220)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
current_time = pygame.time.get_ticks()
if current_time > enemy_time:
enemy_time = current_time + 1000
self.enemies.append(Enemy(enemy_y, enemy_x))
camera_pos = player.movement(camera_pos)
self.WindowUpdate(WINDOW, player, camera_pos)
pygame.quit()
def WindowUpdate(self,WINDOW, player, camera_pos):
player_x, player_y = player.playerMove()
WINDOW.fill((255, 255, 255))
self.MAP.fill(colours['gray'])
player.renderPlayer(self.MAP)
WINDOW.blit(self.MAP, camera_pos)
for e in self.enemies:
e.renderEnemy(WINDOW)
e.enemyMovement(player_x, player_y)
pygame.display.update()
Enemy
class:
import pygame, os, random, math
pygame.init()
# current_time = pygame.time.get_ticks()
# if current_time > self.enemy_time:
# self.enemy_time = current_time + 1000
# self.enemies.append()
class Enemy:
def __init__(self, enemy_y, enemy_x):
self.ENEMY_HEIGHT = self.ENEMY_WIDTH = 64
self.ENEMY_ACCELERATION = 5
self.enemy_rect = pygame.Rect(enemy_x, enemy_y, self.ENEMY_HEIGHT, self.ENEMY_WIDTH)
self.ENEMY = {
'up': pygame.transform.scale(pygame.image.load(
os.path.join(r'C:\Users\ajeen\PycharmProjects\Games\Folder\scripts\TopDown\assets', 'enemy_up.png')),
(self.ENEMY_HEIGHT, self.ENEMY_WIDTH)),
'down': pygame.transform.scale(pygame.image.load(
os.path.join(r'C:\Users\ajeen\PycharmProjects\Games\Folder\scripts\TopDown\assets', 'enemy_down.png')),
(self.ENEMY_HEIGHT, self.ENEMY_WIDTH)),
'left': pygame.transform.scale(pygame.image.load(
os.path.join(r'C:\Users\ajeen\PycharmProjects\Games\Folder\scripts\TopDown\assets', 'enemy_left.png')),
(self.ENEMY_HEIGHT, self.ENEMY_WIDTH)),
'right': pygame.transform.scale(pygame.image.load(
os.path.join(r'C:\Users\ajeen\PycharmProjects\Games\Folder\scripts\TopDown\assets', 'enemy_right.png')),
(self.ENEMY_HEIGHT, self.ENEMY_WIDTH))
}
self.enemy_state = 'up'
def enemyMovement(self, player_x, player_y):
ene_x, ene_y = player_x - self.enemy_rect.x, player_y - self.enemy_rect.y
dist = math.hypot(ene_x, ene_y)
ene_x, ene_y = ene_x // dist, ene_y // dist
self.enemy_rect.x += ene_x * self.ENEMY_ACCELERATION
self.enemy_rect.y += ene_y * self.ENEMY_ACCELERATION
print(self.enemy_rect.x, self.enemy_rect.y)
def renderEnemy(self, WINDOW):
WINDOW.blit(self.ENEMY[self.enemy_state] , (self.enemy_rect.x, self.enemy_rect.y))
I hope the imgur link to the vid showcasing my problem gets embedded. Any input or help will be appreciated
The result of ene_x // dist
and ene_y // dist
is always 0. To calculate the movement, you must use the /
(division) operator rather than the //
(floor division) operator
ene_x, ene_y = ene_x // dist, ene_y // dist
ene_x, ene_y = ene_x / dist, ene_y / dist
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 position of the object incremented:
self.enemy_rect.x += ene_x * self.ENEMY_ACCELERATION self.enemy_rect.y += ene_y * self.ENEMY_ACCELERATION
If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables respectively attributes and to synchronize the pygame.Rect
object. round
the coordinates and assign it to the location (e.g. .topleft
) of the rectangle:
x, y = # floating point coordinates
rect.topleft = round(x), round(y)
Add floating point coordinates to the Enemy
class:
class Enemy:
def __init__(self, enemy_y, enemy_x):
# [...]
self.enemy_rect = pygame.Rect(enemy_x, enemy_y, self.ENEMY_HEIGHT, self.ENEMY_WIDTH)
self.x, self.y = self.enemy_rect.topleft
# [...]
def enemyMovement(self, player_x, player_y):
ene_x, ene_y = player_x - self.x, player_y - self.y
dist = math.hypot(ene_x, ene_y)
ene_x, ene_y = ene_x / dist, ene_y / dist
self.x += ene_x * self.ENEMY_ACCELERATION
self.y += ene_y * self.ENEMY_ACCELERATION
self.enemy_rect = round(self.x), round(self.y)