将坐标网格颠倒过来的对策?

时间:2017-12-10 04:41:42

标签: python pygame coordinates python-3.6 angle

所以我正在使用pygame创建一个简单的自上而下的射击游戏,我从上到下的角度进行了大量的角度计算。让我们用一个简单的箭头和一个球作为例子,我希望红色箭头指向蓝色的球,无论蓝色球在哪里移动:

enter image description here

这似乎很容易,我只需要atan2

angle = math.atan2(blue.y - red.y, blue.x - red.x)

但问题是,atan2适用于这样的数学坐标网格:

enter image description here

alpha = math.atan2(blue.y - red.y, blue.x - red.x)

pygame(至少在Windows上)的问题是坐标网格不像数学坐标网格那样工作,它实际上从游戏窗口的左上角开始颠倒:

enter image description here

因此,虽然看起来蓝球更高,因此在数学上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

但这只是乞求更多错误,我正在寻找一个更通用的解决方案。

1 个答案:

答案 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轴计算的,而不是数学轴。

如果您想测试它,这是箭头图像。只需将以下图像保存在与程序相同的文件夹中: Arrow image used in program