在圆上旋转精灵

时间:2014-10-22 21:38:33

标签: python pygame game-physics

有一个精灵在围绕屏幕中心的圆上移动,半径= 30像素。运动或多或少都可以,但精灵根本不会旋转。我已经尝试了一些教程(例如How to animate scale and rotate in pygame using rotozoom),当精灵沿着一条线移动或随机改变它的轨迹时 - 没有问题。那么当它沿着圆圈移动时有什么不对?这是代码:

class EnemiesStrong(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)     
        self.image = pygame.image.load("enemy3.png").convert_alpha()
        self.image2 = self.image        
        self.rect = self.image2.get_rect()  
        self.angle = 0

    def initLoc(self, pos, x_pos, y_pos):

        self.rect.x = pos[0]/2 + x_pos
        self.rect.y = y_pos


    def update(self, pos, x_pos, y_pos, quadrant, newcoord):
        #print(quadrant)

        self.rect.y = y_pos


        if (quadrant==1 and newcoord==0):
            self.rect.x-=1            
        elif (quadrant==1 and newcoord==1):
            self.rect.x=x_pos

        elif (quadrant==2):           

            oldcenter = self.rect.center
            **self.image2 = pygame.transform.rotate(self.image, self.angle)**
            self.rect = self.image2.get_rect()
            self.rect.center = oldcenter  
            self.rect.x+=1


        elif (quadrant==3 and newcoord==0):
            self.rect.x+=1   

        elif (quadrant==4 and newcoord==0):
            self.rect.x-=1
        elif (quadrant==4 and newcoord==1):
            self.rect.x=x_pos                   

    def turnLeft(self, pos):

        self.angle = (self.angle + 10) % 360
        print(self.angle)

    def whereEnemy(self):
        return (self.rect.x, self.rect.y)    

def OrbitalCoordinates(loc, xpos, radius, quadrant):

    #do lots of stuff to determine the location of the ship in the screen
    #and return its Y-coordinate
    disc = np.power(radius,2) - np.power(xpos - loc[0]/2,2)
    ypos = loc[1]/2 - np.sqrt(disc)                
    return ypos

enemy_s = EnemiesStrong()
ypos = OrbitalCoordinates(screenpar, xpos + screenpar[0]/2, radius,2)
enemy_s.initLoc(screenpar, xpos, ypos)
enemiesupdate.add(enemy_s)
where_strong_enemy = enemy_s.whereEnemy()
bg = pygame.image.load("outer_space.jpg")
screenpar = [bg.get_width(), bg.get_height()]

def main():
   #various useless crap
   for enemy_s in enemiesupdate:
         #do lots of stuff to determine the x- position and direction of movement of the ship 
         #and pass these values to OrbitalCoordinates  
         enemy_s.turnLeft(screenpar) 
         ypos = OrbitalCoordinates(screenpar, where_strong_enemy[0], radius, quadrant)
         enemy_s.update(screenpar, where_strong_enemy[0], ypos, quadrant, 0)
         where_strong_enemy = list(enemy_s.whereEnemy())
         #then check if the y-coordinates are close to the middle of the screen to tweak them a                          
         #little bit
screen.blit(bg, [0, 0])   
enemiesupdate.draw(screen)
pygame.display.flip() 

我省略了我认为不必要的代码块。我确定我正在制造一些愚蠢的错误。

1 个答案:

答案 0 :(得分:0)

阅读pygame.sprite.Group.draw的文档:

将包含的Sprite绘制到Surface参数。这会将Sprite.image属性用于源曲面,并将Sprite.rect用于位置。

因此,旋转后的图像必须存储在image属性中。您不会看到任何旋转,因为您将旋转后的图像保存在image2属性中,但是image是原始旋转后的图像。将原始图像存储在original_image中,将旋转后的图像存储在image中:

class EnemiesStrong(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)     
        self.image = pygame.image.load("enemy3.png").convert_alpha()
        self.image = self.original_image        
        self.rect = self.image.get_rect()  
        self.angle = 0

    def update(self):
        # [...]

        self.image = pygame.transform.rotate(self.original_image, self.angle)
        self.rect = self.image.get_rect(center = oldcenter)

        # [...]      

最小示例:

import pygame

class EnemiesStrong(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)     
        self.original_image = pygame.image.load(r"arrow_up.png").convert_alpha()
        self.image = self.original_image        
        self.rect = self.image.get_rect()  
        self.angle = 0

    def initLoc(self, pos, radius):
        self.pos = pos
        self.radius = radius

    def update(self):
        center = pygame.math.Vector2(self.pos) + pygame.math.Vector2(0, -self.radius).rotate(-self.angle) 
        self.image = pygame.transform.rotate(self.original_image, self.angle)
        self.rect = self.image.get_rect(center = (round(center.x), round(center.y)))            

    def turnLeft(self):
        self.angle = (self.angle + 1) % 360
   
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()

enemy_s = EnemiesStrong()
enemy_s.initLoc(window.get_rect().center, 100)
all_sprites = pygame.sprite.Group(enemy_s)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    enemy_s.turnLeft()
    all_sprites.update()

    window.fill(0)
    pygame.draw.circle(window, (127, 127, 127), window.get_rect().center, 100, 1)
    all_sprites.draw(window)
    pygame.display.flip()

pygame.quit()
exit()