python - Sprite 没有正确地朝向玩家旋转 我该如何解决这个问题?

标签 python pygame sprite

我试图让我的 Sprite 向玩家旋转,但旋转不合适。这是video of the behaviour .

我不知道如何解决这个问题,

Sprite 类

  #-------------------------------- enemy shoots left and right

    shotsright = pygame.image.load("canss.png")
    class enemyshoot:
        def __init__(self,x,y,height,width,color):
            self.x = x
            self.y =y
            self.height = height
            self.width = width
            self.color = color
            self.rect = pygame.Rect(x,y,height,width)
            self.health = 10
            self.hitbox = (self.x + -20, self.y + 30, 31, 57)
           #-------------------------------------------------------
            # Make a Reference Copy of the bitmap for later rotation
            self.shootsright = pygame.image.load("canss.png")
            self.shootsright = pygame.transform.scale(self.shootsright,(self.shootsright.get_width()-150,self.shootsright.get_height()-150))            
            self.image    = self.shootsright
            self.rect     = self.image.get_rect()
            self.position = pygame.math.Vector2( (200, 180) )
            self.isLookingAtPlayer = False
        def draw(self):
            self.rect.topleft = (self.x,self.y)
            window.blit(self.image, self.rect)
            self.hits = (self.x + 20, self.y, 28,60)
            pygame.draw.rect(window, (255,0,0), (self.hitbox[0], self.hitbox[1] - 60, 100, 10)) # NEW
            pygame.draw.rect(window, (0,255,0), (self.hitbox[0], self.hitbox[1] - 60, 100 - (5 * (10 - self.health)), 10))
            self.hitbox = (self.x + 200, self.y + 200, 51, 65)
        def lookAt( self, coordinate ):
            # Rotate image to point in the new direction
            delta_vector  = coordinate - self.position
            radius, angle = delta_vector.as_polar()
            self.image    = pygame.transform.rotate(self.shootsright, -angle)
            # Re-set the bounding rectangle and position since 
            # the dimensions and centroid will have (probably) changed.
            current_pos      = self.rect.center
            self.rect        = self.image.get_rect()
            self.rect.center = current_pos
            


            
    black = (0,0,0)
    enemyshooting = []
    platformGroup = pygame.sprite.Group
    platformList = []
    level = ["                                                                                                                     p               p           p                         p                        p        ",
             "                                       ",
             "                             ",
             "                                      ",
             "                                  ",
             "                           ",
             "                                      ",
             "                                      ",
             "                                    ",
             "                                   ",
             "                    ",]
    for iy, row in enumerate(level):
        for ix, col in enumerate(row):
            if col == "p":
                new_platforms = enemyshoot(ix*10, iy*50, 10,10,(255,255,255))
                enemyshooting.append(new_platforms)

这是旋转部分


class enemyshoot:
     def __init__(self,x,y,height,width,color):
       # [................]
           #-------------------------------------------------------
            # Make a Reference Copy of the bitmap for later rotation
            self.shootsright = pygame.image.load("canss.png")
            self.shootsright = pygame.transform.scale(self.shootsright,(self.shootsright.get_width()-150,self.shootsright.get_height()-150))            
            self.image    = self.shootsright
            self.rect     = self.image.get_rect()
            self.position = pygame.math.Vector2( (200, 180) )      


        def lookAt( self, coordinate ):
            # Rotate image to point in the new direction
            delta_vector  = coordinate - pygame.math.Vector2(self.rect.center)
            radius, angle = delta_vector.as_polar()
            self.image    = pygame.transform.rotate(self.shootsright, -angle)
            # Re-set the bounding rectangle and position since 
            # the dimensions and centroid will have (probably) changed.
            current_pos      = self.rect.center
            self.rect        = self.image.get_rect()
            self.rect.center = current_pos



这是我调用 LookAt 函数来面对玩家的地方:

      # so instead of this 
            for enemyshoot in enemyshooting:
                if not enemyshoot.isLookingAtPlayer:
                    enemyshoot.lookAt((playerman.x, playerman.y)) 

旋转不合适,我不知道如何修复它。我试图使炮口向玩家旋转,因为子弹将从那里附加。

最佳答案

我同意@Rabbid76 在上面的答案中所说的一切。

我怀疑您的部分问题可能是位图的“人类可读”部分不以位图的 centroid 为中心。 。因此,当旋转时,它“扫过”弧线,而不是“绕自身”旋转。 (保留中心坐标是保持围绕对象质心平滑旋转的重要步骤)。

考虑两个位图(右侧图像左上角有一个大的 3/4 透明部分):

centred image off-centred image

两者都围绕其质心旋转,但由于第二张图像上的可见部分不居中,因此它旋转得很奇怪。

example video

因此请确保您的实际位图位于其自身中心。

引用代码:

import pygame
import random

# Window size
WINDOW_WIDTH    = 800
WINDOW_HEIGHT   = 400
WINDOW_SURFACE  = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE

DARK_BLUE = (   3,   5,  54 )

class RotationSprite( pygame.sprite.Sprite ):
    def __init__( self, image, x, y, ):
        pygame.sprite.Sprite.__init__(self)
        self.original = image
        self.image    = image
        self.rect     = self.image.get_rect()
        self.rect.center = ( x, y )
        # for maintaining trajectory
        self.position    = pygame.math.Vector2( ( x, y ) )
        self.velocity    = pygame.math.Vector2( ( 0, 0 ) )

    def lookAt( self, co_ordinate ):
        # Rotate image to point in the new direction
        delta_vector  = co_ordinate - self.position
        radius, angle = delta_vector.as_polar()
        self.image    = pygame.transform.rotozoom( self.original, -angle, 1 )
        # Re-set the bounding rectagle
        current_pos      = self.rect.center
        self.rect        = self.image.get_rect()
        self.rect.center = current_pos



### initialisation
pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), WINDOW_SURFACE )
pygame.display.set_caption( "Rotation Example" )

### Missiles!
rotation_sprites = pygame.sprite.Group()
rotation_image1 = pygame.image.load( 'rot_offcentre_1.png' )
rotation_image2 = pygame.image.load( 'rot_offcentre_2.png' )
rotation_sprites.add( RotationSprite( rotation_image1, WINDOW_WIDTH//3, WINDOW_HEIGHT//2 ) )
rotation_sprites.add( RotationSprite( rotation_image2, 2*( WINDOW_WIDTH//3 ), WINDOW_HEIGHT//2 ) )


### Main Loop
clock = pygame.time.Clock()
done = False
while not done:

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True
        elif ( event.type == pygame.MOUSEBUTTONUP ):
            # On mouse-click
            pass

    # Record mouse movements for positioning the paddle
    mouse_pos = pygame.mouse.get_pos()
    for m in rotation_sprites:
        m.lookAt( mouse_pos )
    rotation_sprites.update()

    # Update the window, but not more than 60 FPS
    window.fill( DARK_BLUE )
    rotation_sprites.draw( window )
    pygame.display.flip()

    # Clamp FPS
    clock.tick_busy_loop(60)

pygame.quit()

关于python - Sprite 没有正确地朝向玩家旋转 我该如何解决这个问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62542099/

相关文章:

python - 计算 pandas 中先前找到的重复项的数量

python - 离线绘图忽略plotly python API中的布局参数

python - 我的 Pygame 游戏打不开,但没有报错

javascript - Angular2 xlink :href Issues

objective-c - 在 Xcode 中使用纹理图集而不使用 cocos2d

ios - 在 Cocos2d 中的 Sprites 制作的两点之间绘制一条线 Sprite

python - 在 virtualenv 中使用 pip install 时出现 UnicodeDecodeError

python - 如何生成一个不在Python列表中的随机ID?

python - 如何修改我的代码,以便列表中的图像显示在行和图 block 中?

python - Pygame 窗口在 Mac 上不接收键盘事件