2

Trig 不是我的强项,这就是为什么我试图让我的导弹正确旋转的原因。看起来我的方向很好,虽然我对这个动作仍然不是 100% 满意,所以我希望通过修复旋转它也能解决这个问题。问题是我的导弹没有指向目标(玩家),它们也会在某个点翻转超过目标。这是代码......旋转无法正常工作。

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

工作代码 这是整个班级的新工作代码。此行末尾的表达式启用正确的旋转“弧度 = 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
4

1 回答 1

1

调用calcPos()时必须重新计算self.vectXand self.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,calcVectupdateto移动__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)
于 2013-06-16T21:51:50.183 回答