【发布时间】:2017-12-10 04:41:42
【问题描述】:
所以我使用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 的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 时单独否定它:
# Face towards target
dx = self.target.x - self.x
dy = self.target.y - self.y
angle = math.atan2(dy, dx)
self.angle = -angle
# 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)
但这只是在乞求更多的错误,我正在寻找一个更通用的解决方案。
【问题讨论】:
-
pygame 有
pygame.math.Vector2,适合计算。顺便说一句:即使使用math模块,我也从来没有遇到过角度问题 -
我对这个解决方案也没有问题。你具体指的是什么问题?我通常也使用
pygame.math.Vector2s。 Here's an example,其中我还使用as_polar方法而不是math.atan2来获取角度。 -
好吧,以前从未听说过
Vector2,应该一开始就使用它。 Omw 然后重构......谢谢大家 -
顺便说一句:几天前我用
Vector2-stackoverflow.com/a/47644510/1832058做了例子 -
当我阅读您的问题时,我认为问题不是角度而是翻转坐标。您在 bottom 左角使用
(0,0)在系统中计算所有内容,并且您必须在 top 左角使用(0,0)在翻转系统中绘制它。因此,您必须在绘制之前翻转所有y值,然后在 bottom 角落中获得(0,0)。screen_y = SCREEN_HEIGHT - real_y
标签: python pygame coordinates python-3.6 angle