试图在pygame中旋转导弹

时间:2013-06-16 11:52:43

标签: pygame angle

Trig不是我强大的西装,这就是为什么我要让probs试图让我的导弹正确旋转。看起来我的方向很好,虽然我仍然不是100%满意的运动,所以我希望通过固定旋转它也将修复。问题是我的导弹不指向目标(玩家),他们也会在目标之后的某个点上翻转。 Heres是代码......旋转不能正常工作。

def update(self):
    self.calcVect()
    self.calcPos()
    self.rotate()
    self.checkBounds()
    self.rect.center = (self.x, self.y)

def calcVect(self):
    self.vectX = self.targetX - self.x
    self.vectY = self.targetY - self.y
    self.length = math.sqrt((self.vectX*self.vectX)+(self.vectY*self.vectY)) 
    self.normX = self.vectX/self.length
    self.normY = self.vectY/self.length
    self.dx += self.normX*self.power
    self.dy += self.normY*self.power

def calcPos(self):
    self.x += self.dx*0.2
    self.y += self.dy*0.2

def rotate(self):
    radians = math.atan2(-self.vectY,self.vectX)
    radians %= 2*math.pi
    self.dir = math.degrees(radians)
    print self.dir
    oldCenter = self.rect.center
    self.image = pygame.transform.rotate(self.imageMissile, self.dir)
    self.rect = self.image.get_rect()
    self.rect.center = oldCenter

工作代码 这是整个班级的新工作代码。该行末尾的表达式启用了正确的旋转“radians = math.atan2(self.vectX,self.vectY) - math.pi / 2”,即使图像是水平的,也可以开始。

class GuidedMissile(pygame.sprite.Sprite):
def __init__(self, source):
    pygame.sprite.Sprite.__init__(self)
    self.screen = source.screen

    self.imageMissile = pygame.image.load("Images/missile.tga").convert()
    self.imageMissile.set_colorkey((0,0,255))
    self.image = self.imageMissile
    self.rect = self.image.get_rect()
    self.rect.center = source.rect.midbottom

    self.rect.inflate_ip(-15, -5)        

    self.x, self.y = self.rect.center
    self.X, self.Y = self.rect.center
    self.dx = 0
    self.dy = 0
    self.power = 3
    self.dir = 0

def update(self):
    self.player = goodSpritesOneGRP.sprite
    self.targetX, self.targetY = self.player.rect.center
    NX, NY = self.calcVect()
    self.calcVel(NX, NY)
    self.calcPos()
    self.rotate()
    self.checkBounds()
    self.rect.center = (self.x, self.y)

def calcVect(self):
    self.vectX = self.targetX - self.x
    self.vectY = self.targetY - self.y
    self.length = math.sqrt((self.vectX*self.vectX)+(self.vectY*self.vectY)) 
    if self.length == 0:
        self.normX = 0
        self.normY = 1
    else:
        self.normX = self.vectX/self.length
        self.normY = self.vectY/self.length
    return (self.normX, self.normY)

def calcVel(self,NX,NY ):
    self.dx += NX*self.power
    self.dy += NY*self.power            

def calcPos(self):
    self.x += self.dx*0.05
    self.y += self.dy*0.05

def rotate(self):
    radians = math.atan2(self.vectX, self.vectY)- math.pi/2
    radians %= 2*math.pi
    self.dir = math.degrees(radians)
    oldCenter = self.rect.center
    self.image = pygame.transform.rotate(self.imageMissile, self.dir)
    self.rect = self.image.get_rect()
    self.rect.center = oldCenter

def checkBounds(self):
    global guidedMissile
    screen = self.screen
    if self.x > screen.get_width():
        self.kill()
        guidedMissile -= 1
    if self.x < -100:
        self.kill()            
        guidedMissile -= 1
    if self.y > screen.get_height() + 100:
        self.kill()
        guidedMissile -= 1
    if self.y < -100:
        self.kill()            
        guidedMissile -= 1

1 个答案:

答案 0 :(得分:1)

当你致电calcPos()时,你必须重新计算self.vectXself.vectY,否则导弹将不会指向目标。不要忘记检查是否self.length == 0

您可以修复拆分calcVect()

def calcVect(self):
    self.vectX = self.targetX - self.x
    self.vectY = self.targetY - self.y
    self.length = math.sqrt((self.vectX*self.vectX)+(self.vectY*self.vectY)) 
    if self.length != 0:
        normX = vectX/self.length
        normY = vectY/self.length

# Update velocity
def calcVel(self):
    self.dx += self.normX*self.power
    self.dy += self.normY*self.power

然后

def update(self):
    self.calcVect()
    self.calcVel()
    self.calcPos()
    self.calcVect()
    self.rotate()
    self.checkBounds()
    self.rect.center = (self.x, self.y)

此解决方案有效,但我建议您编写一个通用方法calcVectTo(self, target),它返回指向(target.x, target.y)的酉向量:

def calcVect(self, target):
    vectX = target.x - self.x
    vectY = target.y - self.y
    length = math.sqrt((vectX*vectX)+(vectY*vectY)) 
    if length == 0:
        normX = 0
        normY = 1
    else
        normX = vectX/length
        normY = vectY/length
    return (normX, normY)

修改

我不明白目标是固定的,现在它更容易:你只需要在类的构造中计算vect,将calcVectupdate移动到__construct (忽略我对calcVect的第二次实现):

class GuidedMissile(pygame.sprite.Sprite):
def __init__(self, source, target):
    ...
    self.calcVect()

def update(self):
    self.calcVel()
    self.calcPos()
    self.rotate()
    self.checkBounds()
    self.rect.center = (self.x, self.y)