Как заставить объект двигаться под углом в pygame

#python #pygame

Вопрос:

Я хочу переместить своего врага через воображаемую гипотенузу треугольника в pygame из переменной start_x, start_y в переменную target_x, target_y, как бы я это сделал? Это часть моего служебного файла

 def polar_to_rectangularD(degrees, hypotenuse=1.0, inverted_y=True):
    opp = math.sin(math.degrees(degrees))*hypotenuse
    adj = math.cos(math.degrees(degrees))*hypotenuse
    if inverted_y:
        opp = -opp
    return opp,adj

def angle_towardsD(start_x, start_y, target_x, target_y, inverted_y=True):
    opp = target_y - start_y
    adj = target_x - start_x
    if inverted_y:
        opp = -opp
    angle = math.atan2(opp, adj)
    return math.degrees(angle)
 

И это часть того, что я пытался сделать с этим в своей основной

 if wall_spawn == 1:               
    enemy_y = player_ymax   player_half_height   enemy_radius     
    enemy_direction = -1
    spawn_angle = utility.angle_towardsD((win_width/6),650,(win_width/2),-100)
    enemy_x_offset, enemy_y_offset = utility.polar_to_rectangularD(spawn_angle,1)
    enemy_y -= enemy_y_offset
    enemy_movement  = enemy_x_offset
#enemy_movement is set to None
 

Ответ №1:

Вам не нужно вычислять угол. Просто рассчитайте вектор от противника к игроку. Масштабируйте вектор по скорости противника и добавьте его в положение врагов:

 def move_enemy(start_x, start_y, target_x, target_y, spped):
    dx = target_x - start_x
    dy = target_y - start_y
    dist = math.hypot(dx, dy)
    if dist > 0:
        start_x  = min(spped, dist) * dx / dist
        start_y  = min(spped, dist) * dy / dist
    return start_x, start_y
 

Минимальный пример:

 import pygame, math

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
player_x, player_y, player_vel = 100, 100, 5
enemy_x, enemy_y, enemy_vel = 300, 300, 3

def move_enemy(start_x, start_y, target_x, target_y, speed):
    dx = target_x - start_x
    dy = target_y - start_y
    dist = math.hypot(dx, dy)
    if dist > 0:
        start_x  = min(speed, dist) * dx / dist
        start_y  = min(speed, dist) * dy / dist
    return start_x, start_y


run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False          
        
    keys = pygame.key.get_pressed()
    player_x = max(10, min(390, player_x   player_vel * (keys[pygame.K_d] - keys[pygame.K_a])))
    player_y = max(10, min(390, player_y   player_vel * (keys[pygame.K_s] - keys[pygame.K_w])))

    enemy_x, enemy_y = move_enemy(enemy_x, enemy_y, player_x, player_y, enemy_vel)

    window.fill(0)
    pygame.draw.circle(window, (0, 128, 255), (player_x, player_y), 10)
    pygame.draw.circle(window, (255, 32, 32), (enemy_x, enemy_y), 10)
    pygame.display.flip()

pygame.quit()
exit()