Je fais du petit gibier avec Pygame et j'ai fabriqué un pistolet qui tourne autour de son centre. Mon problème est que je veux que le canon tourne par lui-même dans la direction de l'ennemi, mais je ne pouvais pas le faire car je ne pouvais pas trouver l'angle entre le canon et l'ennemi pour faire pivoter le canon, j'ai cherché et j'ai a constaté que je devais utiliser le atan2
mais je n’ai trouvé aucun code fonctionnel et j’espère que l’on pourra m'aider.
Voici mon code:
import pygame
from pygame.locals import*
pygame.init()
height=650
width=650
screen=pygame.display.set_mode((height,width))
clock=pygame.time.Clock()
gun=pygame.image.load("m2.png").convert_alpha()
gun=pygame.transform.smoothscale(gun,(200,200)).convert_alpha()
angle=0
angle_change=0
RED=(255,0,0)
x=525
y=155
while True :
screen.fill((150,150,150))
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
quit()
if event.type==KEYDOWN:
if event.key==K_a:
angle_change=+1
if event.key==K_d:
angle_change=-1
Elif event.type==KEYUP:
angle_change=0
angle+=angle_change
if angle>360:
angle=0
if angle<0:
angle=360
pygame.draw.rect(screen,RED,(x,y,64,64))
position = (height/2,width/2)
gun_rotate=pygame.transform.rotate(gun,angle)
rotate_rect = gun_rotate.get_rect()
rotate_rect.center = position
screen.blit(gun_rotate, rotate_rect)
pygame.display.update()
clock.tick(60)
Et voici une photo essayant de le rendre clair:
Merci.
La tangente de l'angle entre deux points est définie par delta y/delta x C'est-à-dire (y2 - y1)/(x2-x1). Cela signifie que math.atan2(dy, dx)
donne l'angle entre les deux points en supposant que que vous connaissiez l'axe de base qui définit les coordonnées.
Votre arme est supposée être le point (0, 0) des axes afin de calculer l'angle en radians. Une fois que vous avez cet angle, vous pouvez utiliser cet angle pour le reste de vos calculs.
Notez que, l'angle étant en radians, vous devez utiliser le fichier math.pi au lieu de 180 degrés dans votre code. De plus, votre test pour plus de 360 degrés (2 * math.pi) n'est pas nécessaire. Le test pour négatif (<0) est incorrect car vous le forcez ensuite à 0, ce qui oblige la cible à se trouver sur l'axe des x dans le sens positif.
Votre code pour calculer l’angle entre le canon et la cible est donc
myradians = math.atan2(targetY-gunY, targetX-gunX)
Si vous voulez convertir des radians en degrés
mydegrees = math.degrees(myradians)
Pour convertir des degrés en radians
myradians = math.radians(mydegrees)
La fonction Python ATAN2 est l’une des fonctions mathématiques Python utilisée avec Utilisée pour renvoyer l’angle (en radians) du X -Axis au point Spécifié (y, x).
Définition Renvoie la tangente (y, x) en rayon.
Syntaxe
math.atan2 (y, x)Paramètres
y, x = nombresExemples
Le retour est:>>> import math >>> math.atan2(88,34) 1.202100424136847 >>>
Comme l’a déjà dit un intervenant, il n’existe qu’un angle entre trois points ou entre deux vecteurs qui s’intersectent et qui peut être déduit de ces trois points. Je suppose que vous voulez l'angle, le pistolet et la cible (vecteur 1) et l'axe des x (vecteur 2). Voici un lien vers une page, qui explique comment calculer cet angle. http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm
Exemple Python:
import math
def angle(vector1, vector2):
length1 = math.sqrt(vector1[0] * vector1[0] + vector1[1] * vector1[1])
length2 = math.sqrt(vector2[0] * vector2[0] + vector2[1] * vector2[1])
return math.acos((vector1[0] * vector2[0] + vector1[1] * vector2[1])/ (length1 * length2))
vector1 = [targetX - gunX, targetY - gunY] # Vector of aiming of the gun at the target
vector2 = [1,0] #vector of X-axis
print(angle(vector1, vector2))
Spécifiquement pour travailler avec des objets shapely linestring
, en supposant que votre objet (deux points) est de la forme (min long, min lat, max long, max lat)
from math import atan2,degrees
line = #Your-LineString-Object
lineList = list(line.coords)
def AngleBtw2Points(pointA, pointB):
changeInX = pointB[0] - pointA[0]
changeInY = pointB[1] - pointA[1]
return degrees(atan2(changeInY,changeInX)) #remove degrees if you want your answer in radians
AngleBtw2Points(lineList[0],lineList[1])
Vous pouvez simplement utiliser la méthode as_polar
de la classe Vector2 de Pygame qui renvoie les coordonnées polaires du vecteur (rayon et angle polaire (en degrés)).
Il suffit donc de soustraire le premier vecteur de points du second et d’appeler la méthode as_polar
du vecteur résultant.
import pygame as pg
from pygame.math import Vector2
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray12')
point = Vector2(320, 240)
mouse_pos = Vector2(0, 0)
radius, angle = (mouse_pos - point).as_polar()
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
Elif event.type == pg.MOUSEMOTION:
mouse_pos = event.pos
radius, angle = (mouse_pos - point).as_polar()
screen.fill(BG_COLOR)
pg.draw.line(screen, (0, 100, 255), point, mouse_pos)
pg.display.set_caption(f'radius: {radius:.2f} angle: {angle:.2f}')
pg.display.flip()
clock.tick(60)