所以我正在使用pygame
创建一个简单的自上而下的射击游戏,我从上到下的角度进行了大量的角度计算。让我们用一个简单的箭头和一个球作为例子,我希望红色箭头指向蓝色的球,无论蓝色球在哪里移动:
这似乎很容易,我只需要atan2
:
angle = math.atan2(blue.y - red.y, blue.x - red.x)
但问题是,atan2
适用于这样的数学坐标网格:
alpha = math.atan2(blue.y - red.y, blue.x - red.x)
但pygame
(至少在Windows上)的问题是坐标网格不像数学坐标网格那样工作,它实际上从游戏窗口的左上角开始颠倒:
因此,虽然看起来蓝球更高,因此在数学上blue.y
应该大于red.y
,但实际情况并非如此,因为倒置的坐标网格是Python的{{ 1}}不知道,我原来的计算:
math.atan2()
实际上会产生正确的角度否定。
现在,我想出的第一个明显的解决方案就是翻转标志,并且公平地使用了它:
angle = math.atan2(blue.y - red.y, blue.x - red.x)
但是,一旦我需要根据之前计算的角度进行进一步的计算,这个问题又开始了,技术上现在这个角度是颠倒的。
我可以采取什么对策来“永久”摆脱这个问题?
这是一个我需要这个的实际例子,我有一个“僵尸”实体,除了它已经给出的目标之外什么都不做:
angle = -math.atan2(blue.y - red.y, blue.x - red.x)
对于这个特殊情况,我设法通过将角度存储到一个单独的变量供以后使用来解决它,并在设置class Zombie(Entity):
def __init__(self, *args, target=None, **kwargs):
super().__init__(*args, **kwargs)
self.target = target
def update(self, dt, app):
if self.target:
# Face towards target
dx = self.target.x - self.x
dy = self.target.y - self.y
self.angle = math.atan2(dy, dx)
# Change velocity towards target
speed = self.get_max_speed()
vel_x = math.cos(angle) * speed
vel_y = math.sin(angle) * speed
self.velocity = (vel_x, vel_y)
else:
self.velocity = (0, 0)
# Moves the zombie based on velocity
super().update(dt, app)
后单独否定它:
self.angle
但这只是乞求更多错误,我正在寻找一个更通用的解决方案。
答案 0 :(得分:0)
您可以计算自己的角度,而不是更改为负号。我用过你的球和箭的例子。这是一个非常简单的三角函数:
#Import needed programs
import pygame, sys, time, math
from pygame.locals import *
#Initialize pygame
pygame.init()
window = pygame.display.set_mode((600, 450))
pygame.display.set_caption('PyCloud')
#Define colours
aqua = 0,255,255
white = 255,255,255
#Defne an arrow sprite class
arrow = pygame.image.load("arrow.png")
arrow = pygame.transform.scale(arrow,(50,200))
#Define a function to calculate angle
def calcAngle(triangleA,triangleB):
sinAngle = triangleA/triangleB
angle = math.asin(sinAngle)
return math.degrees(angle)
#Creat clock lop for stability
clock = pygame.time.Clock()
#start main loop
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
else:
pass
#Get mouse pos
mouse = pygame.mouse.get_pos()
x = mouse[0]
y = mouse[1]
#calculate triangle lengths
triangleA = x
triangleB = math.hypot(x,(450-y))
angle = calcAngle(triangleA,triangleB)
print(angle)
#draw screen
window.fill(white)
pygame.draw.circle(window,aqua,(x,y),10,0)
window.blit(arrow,(0,350))
clock.tick(1000)
pygame.display.update()
程序存储箭头在名为angle
的变量中应转动的确切角度。我会让你决定你对这个角度本身做些什么。你和你所做的之间的区别在于它是根据pygame轴计算的,而不是数学轴。