Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使我的子弹击中物体后产生动画效果_Python_Pygame - Fatal编程技术网

Python 如何使我的子弹击中物体后产生动画效果

Python 如何使我的子弹击中物体后产生动画效果,python,pygame,Python,Pygame,我想这样,当我的子弹到达一定距离时,它会通过爆炸动画,然后自行移除。我可以让它自己移除,但我不知道如何正确地设置动画 enemyShotList = pygame.sprite.spritecollide(bullet, enemyGroup, False) for enemy in enemyShotList: enemyGroup.remove(enemy) bulletGroup.remove(bullet)

我想这样,当我的子弹到达一定距离时,它会通过爆炸动画,然后自行移除。我可以让它自己移除,但我不知道如何正确地设置动画

        enemyShotList = pygame.sprite.spritecollide(bullet, enemyGroup, False)

        for enemy in enemyShotList:
            enemyGroup.remove(enemy)
            bulletGroup.remove(bullet)

        currentBulletTime = pygame.time.get_ticks()
        currentbulletx = bullet.rect.x
        currentbullety = bullet.rect.y
        if currentBulletTime - bullet.originalBulletTime > 700:
            bulletGroup.remove(bullet)
            for i in range(0,15):
                screen.blit(bulletpopList[i], [currentbulletx,currentbullety])

上述代码的问题是,它在动画中运行得太快。我不知道如何设置它的动画以使它变慢。

您似乎已经使用了
精灵类,因此很容易跟踪精灵中的时间

你应该做的是使用所谓的增量时间。基本上,您可以测量渲染帧所需的时间,并将该值传递给游戏中“随时间移动”的每个部分。因此,当最后一帧的时间为X ms时,以S的速度移动的精灵会移动S*X像素。如果下一帧采用Y毫秒,则同一精灵将移动S*Y像素

在pygame中,您通常使用
时钟
来限制调用其
勾选
方法的帧速率。此方法还将返回自上次调用以来经过的毫秒数。所以这个值是我们传递给sprite的
update
方法的delta时间


因此,由于现在每个精灵都知道每一帧经过了多少时间,我们可以通过创建一个实例变量(我们称之为
timer
),将其值设置为我们希望等待的毫秒数,并减去每一帧的增量时间(我们称之为
dt
)。一旦我们点击了
,如果你可以冻结游戏的其余部分,只需在动画循环中添加一个
time.sleep()
。@Valentino我需要游戏在冻结时不要被冻结。如果更复杂,你需要完全重新设计动画,并将其移动到游戏的主循环中。不能在单独的循环中循环
bulletpopList
。它将冻结游戏的其余部分。你缺少的技术是控制精灵的速度。用这些关键词进行研究;在线上有很多活跃的PyGame动画的例子。
import pygame
import random

TILESIZE = 32

# Since our sprites are very generic, we want to be able
# to set some attributes while creating them.
# Here we create a set of allowed options.
ACTOR_OPTIONS = set(['can_be_destroyed'])

# guess what
def random_color():
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)

# A generic Sprite class. 
# It takes a position, a velocity, a color, a function that
# controls its behaviour, and keyworded arguments.
class Actor(pygame.sprite.Sprite):
    def __init__(self, pos, vel, color, handler, all_sprites, **kwargs):
        super().__init__(all_sprites)
        # A timer and counter attribute to handle time based stuff.
        self.timer = 0
        self.counter = 0
        # Update the sprite attributes with the keyworded arguments. 
        # We only allow the keys defined in ACTOR_OPTIONS.
        self.__dict__.update(kwargs)
        self.__dict__.update((key, False) for key in ACTOR_OPTIONS)
        self.__dict__.update((key, value) for key, value in kwargs.items() if key in ACTOR_OPTIONS)
        # We keep a reference to a sprite groups that contains all sprites
        # so we can access them easily
        self.all_sprites = all_sprites
        # Simple non-colored image 
        self.image = pygame.Surface((TILESIZE, TILESIZE))
        self.image.fill(pygame.Color(color))
        self.rect = self.image.get_rect(center=pos)
        # Position and velocity as Vectors for easier math
        self.pos = pygame.Vector2(pos)
        self.vel = pygame.Vector2(vel)
        # The handler function that we're going to call each frame
        self.handler = handler

    def update(self, dt, events):
        # Let the handler function to their thing
        self.handler(self, dt, events)
        # Move the sprite
        self.pos += (self.vel * dt/10)
        self.rect.center = [int(x) for x in self.pos]

# Our sprites are very generic, so here we create some functions
# that will control the behaviour of the sprites.
# We could have created new classes and implement the update-function instead,
# but this function-approach allows us to change the behaviour of a sprite
# at runtime by setting the handler attribute

def target_handler(actor, dt, events):
    screen_rect = pygame.display.get_surface().get_rect()

    # A target does nothing but changing its direction when hittin the screen edges.
    # Note that this implementation does not handle edge cases like a huge delta time.
    if not screen_rect.contains(actor.rect):
        actor.vel *= -1

def rocket_handler(actor, dt, events):
    # A rocket will disappear when leaving the screen
    screen_rect = pygame.display.get_surface().get_rect()
    if not screen_rect.colliderect(actor.rect):
        actor.kill()

    # but when it hits a sprite with the can_be_destroyed-flag...
    collisions = pygame.sprite.spritecollide(actor, actor.all_sprites, False)
    for c in collisions:
        if c.can_be_destroyed:
            # ...we remove both sprites 
            actor.kill()
            c.kill()
            # ...and create to explosion sprites
            Actor(actor.pos, ( 0, 0), 'yellow', explosion_handler, actor.all_sprites, timer=100)
            Actor(c.pos, ( 0, 0), 'orange', explosion_handler, actor.all_sprites, timer=50)

def explosion_handler(actor, dt, events):
    # An explosion will change its color 15 times
    # every 100 milliseconds.
    if actor.timer:
        actor.timer -= dt
        if actor.timer <= 0:
            actor.image.fill(random_color())
            actor.timer = 100
            actor.counter += 1
    if actor.counter >= 15:
        actor.kill()

# Standard pygame main loop
def main():
    width, height = 640, 480
    pygame.init()
    screen = pygame.display.set_mode((width, height))
    clock = pygame.time.Clock()
    sprites = pygame.sprite.Group()
    dt = 0

    # We create three targets
    Actor((20, 20), ( 2,  0), 'dodgerblue', target_handler, sprites, can_be_destroyed=True)
    Actor((120, 120), ( 2,  0), 'dodgerblue', target_handler, sprites, can_be_destroyed=True)
    Actor((320, 220), ( 2,  0), 'dodgerblue', target_handler, sprites, can_be_destroyed=True)

    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
            if e.type == pygame.KEYDOWN:
                # Fire a rocket when we press a key
                Actor((320, 479), ( 0, -4), 'red', rocket_handler, sprites)

        sprites.update(dt, events)
        screen.fill((20, 20, 20))
        sprites.draw(screen)
        pygame.display.flip()
        dt = clock.tick(60)

if __name__ == '__main__':
    main()