若角度为负,则玩家转向错误方向

2024-09-28 05:34:29 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,我正在制作一个关于用炮塔射击敌人的游戏,我想慢慢转动玩家的炮塔,所以我使用以下代码:

    #if the angle is larger than the playerangle
    if getangle() > playerangle:
        playerangle += 1
    #if the angle is smaller than the playerangele
    elif getangle() < playerangle:
        playerangle -= 1
    #draw the player
    player(playerangle)

但不知何故,炮塔并不总是选择最短的路径:角度从0到-269,它转错了方向。我如何解决这个问题

如果需要函数getangle()和player()的代码,请点击这里:

def player(angle):
    pos_org = [width/2, height/2]
    image_rotated = pygame.transform.rotate(playericon, -angle)
    pos_new = (pos_org[0] - image_rotated.get_rect().width / 2, pos_org[1] - image_rotated.get_rect().height / 2)
    screen.blit(image_rotated, pos_new)
def getangle():
    x = width/2
    y = height/2
    mousex, mousey = pygame.mouse.get_pos()
    angle = math.atan2((y-mousey), (x-mousex))*180/math.pi
    return int(angle - 90)

Tags: the代码orgposimagegetifwidth
1条回答
网友
1楼 · 发布于 2024-09-28 05:34:29

^{}返回范围为-pi,pi的角度。问题可能是由从pi到-pi的转换引起的

你知道从中心到鼠标的向量

def mouse_direction():
    x, y = width/2, height/2
    mousex, mousey = pygame.mouse.get_pos()
    dx, dy = mousex - x, mousey - y
    return dx, dy

你知道玩家当前的方向:

player_dir = math.cos(math.radians(player_angle)), math.sin(math.radians(player_angle)) 

计算法线(Perpendicular)方向到当前目标方向的距离

direction = mouse_direction()
normal_dir = -direction[1], direction[0] 

并计算当前方向和目标方向法线之间的Dot product

dot_p_n = player_dir[0]*normal_dir[0] + player_dir[1]*normal_dir[1]

由于点积与2个向量之间的角度的余弦成正比,因此可以根据dot_p_n的符号改变角度:

player_angle += -1 if dot_p_n > 0 else 1

请参见示例:

enter image description here

import pygame
import math

def rotate_triangle(center, scale, mouse_pos):

    dx = mouse_pos[0] - center[0]
    dy = mouse_pos[1] - center[1]
    len = math.sqrt(dx*dx + dy*dy)
    dx, dy = (dx*scale/len, dy*scale/len) if len > 0 else (1, 0)

    pts = [(-0.5, -0.866), (-0.5, 0.866), (4.0, 0.0)]
    pts = [(center[0] + p[0]*dx + p[1]*dy, center[1] + p[0]*dy - p[1]*dx) for p in pts]
    return pts

disp = pygame.display.set_mode((200,200))
width, height = disp.get_size()
clock = pygame.time.Clock()

def mouse_direction():
    x, y = width/2, height/2
    mousex, mousey = pygame.mouse.get_pos()
    dx, dy = mousex - x, mousey - y
    return dx, dy


player_angle = 0

run = True
while run:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    player_dir = math.cos(math.radians(player_angle)), math.sin(math.radians(player_angle)) 

    direction = mouse_direction()
    normal_dir = -direction[1], direction[0] 

    dot_p_n = player_dir[0]*normal_dir[0] + player_dir[1]*normal_dir[1]
    player_angle += -1 if dot_p_n > 0 else 1

    target_pos = width/2 + math.cos(math.radians(player_angle)), height/2 + math.sin(math.radians(player_angle)) 
    points = rotate_triangle((100, 100), 10, target_pos)

    pygame.Surface.fill(disp, (255,255,255))
    pygame.draw.polygon(disp, (0,0,0), points)
    pygame.display.update()

相关问题 更多 >

    热门问题