• C++
  • pygame第六课-播放动画

  • @ 2024-4-13 19:17:48
import sys
import pygame
from pygame.locals import *
import random


class Fish(pygame.sprite.Sprite):
    """创建动画精灵的子类,命名为Fish"""
    def __init__(self, image):
        """初始化"""
        pygame.sprite.Sprite.__init__(self)  #初始化动画精灵
        self.image = image  # 加载图像
        self.rect = self.image.get_rect()  # 获取图像的矩形区域
        self.speedx = random.randint(1,3)
        self.speedy = random.randint(1,3)

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.left < 0 or self.rect.right > WIDTH:
            self.speedx = -self.speedx
            self.reversed()  # 水平翻转图片
        if self.rect.top < 0 or self.rect.bottom > HEIGHT:
            self.speedy = -self.speedy
    
    def reversed(self):
        self.image = pygame.transform.flip(self.image, True, False)


class FishAnimation(pygame.sprite.Sprite):
    def __init__(self, images):
        """
        有动画的精灵
        :param images: 动画帧列表
        :param rate: 动画的播放间隔,毫秒
        """
        pygame.sprite.Sprite.__init__(self)  #初始化动画精灵
        self.images = images
        self.image = self.images[0]  # 加载图像
        self.rect = self.image.get_rect()  # 获取图像的矩形区域
        self.speedx = random.randint(1, 2)
        self.speedy = random.randint(1, 2)

        self.all_frame = len(self.images)  # 总的动画帧数目
        self.frame = 0  # 当前动画帧

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.left < 0 or self.rect.right > WIDTH:
            self.speedx = -self.speedx
            self.reversed()  # 水平翻转图片
        if self.rect.top < 0 or self.rect.bottom > HEIGHT:
            self.speedy = -self.speedy

        self.frame += 1  # [6]动画帧数加1
        if self.frame >= self.all_frame:
            self.frame = 0
        self.image = self.images[self.frame]  # [6]更新图片
    
    def reversed(self):
        """水平翻转图片"""
        for i in range(self.all_frame):
            self.images[i] = pygame.transform.flip(self.images[i], True, False)


def load_images(filename, rows, columns):
    """
    加载动画图片
    :param filename: 图片的文件名
    :param rows: 动画的行数
    :param columns: 动画的列数
    :return:
    """
    images = []  # 存储动画帧的列表
    master_image = pygame.image.load(filename).convert_alpha()  # 加载动画主图
    master_rect = master_image.get_rect()  # 获取序列图的尺寸
    frame_width = master_rect.width//columns  # 单个动画帧的宽度
    frame_height = master_rect.height//rows  # 单个动画帧的高度
    for row in range(rows):  # 根据单个动画帧尺寸切割图片
        for col in range(columns):
            frame_rect = (col * frame_width, row * frame_height, frame_width, frame_height)
            frame_image = master_image.subsurface(frame_rect)
            images.append(frame_image)  # 将单个动画帧加入到列表
    return images


pygame.init()  # 初始化pygame模块

WIDTH = 1024  # 定义游戏窗口的宽
HEIGHT = 600  # 定义游戏窗口的高
FPS = 60
SCREEN_SIZE = (WIDTH, HEIGHT)  # 定义一个元组

mode_list = pygame.display.list_modes()  # 获取电脑支持的全屏分辨率
SCREEN_FULL = mode_list[0]


screen = pygame.display.set_mode(SCREEN_SIZE)  # 初始化一个显示画面的窗口
pygame.display.set_caption("MyPygame")  # 设置标题
bg = pygame.image.load("./PNG/Background.png").convert()  # 加载背景图片

fishGroup = pygame.sprite.Group()  # 创建一个精灵组
# 水母
jellyfish_images = load_images("./PNG/Jellyfish.png", 1, 6)
jellyfish = FishAnimation(jellyfish_images)
fishGroup.add(jellyfish)

# 比目鱼
for i in range(5):
    fish_images = load_images("./PNG/Flatfish{}.png".format(i), 5, 4)
    fish = FishAnimation(fish_images)
    fish.rect.center = [100+100*i, 100+100*i]
    fishGroup.add(fish)

# 古比鱼
for i in range(6):
    image = pygame.image.load("./PNG/Guppy{}.png".format(i)).convert_alpha()
    fish = Fish(image)
    fish.rect.center = 300, 300  # 更改位置,否则会卡住
    fishGroup.add(fish)  # 将精灵添加到精灵组

clock = pygame.time.Clock()
while True:  # 游戏主循环
    clock.tick(FPS)
    for event in pygame.event.get():  # 获取事件
        if event.type == QUIT:  # 退出
            pygame.quit()  # 退出pygame模块
            sys.exit()  # 退出系统

    screen.blit(bg, (0, 0))  # # 绘制背景
    fishGroup.update()  # 调用组中动画精灵的update方法
    fishGroup.draw(screen)  # 绘制精灵组中的精灵到surface图象上

    pygame.display.update()  # 更新窗口画面显示

2 条评论

  • @ 2024-4-20 20:32:40
    import sys
    import pygame
    from pygame.locals import *
    import random
    
    
    class Fish(pygame.sprite.Sprite):
        """创建动画精灵的子类,命名为Fish"""
        def __init__(self, image):
            """初始化"""
            pygame.sprite.Sprite.__init__(self)  #初始化动画精灵
            self.image = image  # 加载图像
            self.rect = self.image.get_rect()  # 获取图像的矩形区域
            self.speedx = random.randint(1,3)
            self.speedy = random.randint(1,3)
            self.mask = pygame.mask.from_surface(self.image)
    
        def update(self):
            self.rect.x += self.speedx
            self.rect.y += self.speedy
            if self.rect.left < 0 or self.rect.right > WIDTH:
                self.speedx = -self.speedx
                self.reversed()  # 水平翻转图片
            if self.rect.top < 0 or self.rect.bottom > HEIGHT:
                self.speedy = -self.speedy
        
        def reversed(self):
            self.image = pygame.transform.flip(self.image, True, False)
    
    
    class FishAnimation(pygame.sprite.Sprite):
        def __init__(self, images):
            """
            有动画的精灵
            :param images: 动画帧列表
            :param rate: 动画的播放间隔,毫秒
            """
            pygame.sprite.Sprite.__init__(self)  #初始化动画精灵
            self.images = images
            self.image = self.images[0]  # 加载图像
            self.rect = self.image.get_rect()  # 获取图像的矩形区域
            self.speedx = random.randint(1, 2)
            self.speedy = random.randint(1, 2)
            self.last_time=0 # 记录上一次更新帧的时间
            self.rate = 200 # 更新帧的间隔时间
            self.mask = pygame.mask.from_surface(self.image)
            self.all_frame = len(self.images)  # 总的动画帧数目
            self.frame = 0  # 当前动画帧
    
        def update(self):
            self.rect.x += self.speedx
            self.rect.y += self.speedy
            if self.rect.left < 0 or self.rect.right > WIDTH:
                self.speedx = -self.speedx
                self.reversed()  # 水平翻转图片
            if self.rect.top < 0 or self.rect.bottom > HEIGHT:
                self.speedy = -self.speedy
            now = pygame.time.get_ticks() # 获取当前的时间,单位是毫秒
            if now-self.last_time > self.rate:
                # 判断当前时间减去上次更新时间大于间隔时间才会更新下一帧图片
                self.last_time = now;
                self.frame += 1  # [6]动画帧数加1
                if self.frame >= self.all_frame:
                    self.frame = 0
                self.image = self.images[self.frame]  # [6]更新图片
        
        def reversed(self):
            """水平翻转图片"""
            for i in range(self.all_frame):
                self.images[i] = pygame.transform.flip(self.images[i], True, False)
    
    
    def load_images(filename, rows, columns):
        """
        加载动画图片
        :param filename: 图片的文件名
        :param rows: 动画的行数
        :param columns: 动画的列数
        :return:
        """
        images = []  # 存储动画帧的列表
        master_image = pygame.image.load(filename).convert_alpha()  # 加载动画主图
        master_rect = master_image.get_rect()  # 获取序列图的尺寸
        frame_width = master_rect.width//columns  # 单个动画帧的宽度
        frame_height = master_rect.height//rows  # 单个动画帧的高度
        for row in range(rows):  # 根据单个动画帧尺寸切割图片
            for col in range(columns):
                frame_rect = (col * frame_width, row * frame_height, frame_width, frame_height)
                frame_image = master_image.subsurface(frame_rect)
                images.append(frame_image)  # 将单个动画帧加入到列表
        return images
    
    
    pygame.init()  # 初始化pygame模块
    
    WIDTH = 1024  # 定义游戏窗口的宽
    HEIGHT = 600  # 定义游戏窗口的高
    FPS = 60
    SCREEN_SIZE = (WIDTH, HEIGHT)  # 定义一个元组
    
    mode_list = pygame.display.list_modes()  # 获取电脑支持的全屏分辨率
    SCREEN_FULL = mode_list[0]
    
    
    screen = pygame.display.set_mode(SCREEN_SIZE)  # 初始化一个显示画面的窗口
    pygame.display.set_caption("MyPygame")  # 设置标题
    bg = pygame.image.load("./PNG/Background.png").convert()  # 加载背景图片
    
    fishGroup = pygame.sprite.Group()  # 创建一个精灵组
    # 水母
    jellyfish_images = load_images("./PNG/Jellyfish.png", 1, 6)
    jellyfish = FishAnimation(jellyfish_images)
    fishGroup.add(jellyfish)
    
    FlatfishGroup = pygame.sprite.Group()  # 创建一个比目鱼精灵组
    # 比目鱼
    for i in range(5):
        fish_images = load_images("./PNG/Flatfish{}.png".format(i), 5, 4)
        fish = FishAnimation(fish_images)
        fish.rect.center = [100+100*i, 100+100*i]
        FlatfishGroup.add(fish) # 将生成的动画比目鱼对象,添加到比目鱼组
    
    GuppyGroup = pygame.sprite.Group()  # 创建一个古比精灵组
    # 古比鱼
    for i in range(6):
        image = pygame.image.load("./PNG/Guppy{}.png".format(i)).convert_alpha()
        fish = Fish(image)
        fish.rect.center = 300, 300  # 更改位置,否则会卡住
        GuppyGroup.add(fish)  # 将生成的图片古比鱼对象,添加到古比鱼组
    
    clock = pygame.time.Clock()
    while True:  # 游戏主循环
        clock.tick(FPS)
        for event in pygame.event.get():  # 获取事件
            if event.type == QUIT:  # 退出
                pygame.quit()  # 退出pygame模块
                sys.exit()  # 退出系统
        hits = pygame.sprite.spritecollide(jellyfish,
                                           GuppyGroup,
                                           False ,
                                           pygame.sprite.collide_mask)
        if hits:
            jellyfish.speedx = -jellyfish.speedx
            jellyfish.speedy = -jellyfish.speedy
            jellyfish.reversed()
            for hit in hits:
                hit.speedx =  - hit.speedx
                hit.speedy =  - hit.speedy
                hit.reversed()
        
        screen.blit(bg, (0, 0))  # # 绘制背景
        fishGroup.update()  # 调用组中动画精灵的update方法
        fishGroup.draw(screen)  # 绘制精灵组中的精灵到surface图象上
        FlatfishGroup.update()  # 调用组中动画精灵的update方法
        FlatfishGroup.draw(screen)  # 绘制精灵组中的精灵到surface图象上
        GuppyGroup.update()  # 调用组中动画精灵的update方法
        GuppyGroup.draw(screen)  # 绘制精灵组中的精灵到surface图象上
    
        pygame.display.update()  # 更新窗口画面显示
    
    
    
    • @ 2024-4-20 20:17:27
      import sys
      import pygame
      from pygame.locals import *
      import random
      
      
      class Fish(pygame.sprite.Sprite):
          """创建动画精灵的子类,命名为Fish"""
          def __init__(self, image):
              """初始化"""
              pygame.sprite.Sprite.__init__(self)  #初始化动画精灵
              self.image = image  # 加载图像
              self.rect = self.image.get_rect()  # 获取图像的矩形区域
              self.speedx = random.randint(1,3)
              self.speedy = random.randint(1,3)
      
          def update(self):
              self.rect.x += self.speedx
              self.rect.y += self.speedy
              if self.rect.left < 0 or self.rect.right > WIDTH:
                  self.speedx = -self.speedx
                  self.reversed()  # 水平翻转图片
              if self.rect.top < 0 or self.rect.bottom > HEIGHT:
                  self.speedy = -self.speedy
          
          def reversed(self):
              self.image = pygame.transform.flip(self.image, True, False)
      
      
      class FishAnimation(pygame.sprite.Sprite):
          def __init__(self, images):
              """
              有动画的精灵
              :param images: 动画帧列表
              :param rate: 动画的播放间隔,毫秒
              """
              pygame.sprite.Sprite.__init__(self)  #初始化动画精灵
              self.images = images
              self.image = self.images[0]  # 加载图像
              self.rect = self.image.get_rect()  # 获取图像的矩形区域
              self.speedx = random.randint(1, 2)
              self.speedy = random.randint(1, 2)
              self.last_time=0 # 记录上一次更新帧的时间
              self.rate = 200 # 更新帧的间隔时间
      
              self.all_frame = len(self.images)  # 总的动画帧数目
              self.frame = 0  # 当前动画帧
      
          def update(self):
              self.rect.x += self.speedx
              self.rect.y += self.speedy
              if self.rect.left < 0 or self.rect.right > WIDTH:
                  self.speedx = -self.speedx
                  self.reversed()  # 水平翻转图片
              if self.rect.top < 0 or self.rect.bottom > HEIGHT:
                  self.speedy = -self.speedy
              now = pygame.time.get_ticks() # 获取当前的时间,单位是毫秒
              if now-self.last_time > self.rate:
                  # 判断当前时间减去上次更新时间大于间隔时间才会更新下一帧图片
                  self.last_time = now;
                  self.frame += 1  # [6]动画帧数加1
                  if self.frame >= self.all_frame:
                      self.frame = 0
                  self.image = self.images[self.frame]  # [6]更新图片
          
          def reversed(self):
              """水平翻转图片"""
              for i in range(self.all_frame):
                  self.images[i] = pygame.transform.flip(self.images[i], True, False)
      
      
      def load_images(filename, rows, columns):
          """
          加载动画图片
          :param filename: 图片的文件名
          :param rows: 动画的行数
          :param columns: 动画的列数
          :return:
          """
          images = []  # 存储动画帧的列表
          master_image = pygame.image.load(filename).convert_alpha()  # 加载动画主图
          master_rect = master_image.get_rect()  # 获取序列图的尺寸
          frame_width = master_rect.width//columns  # 单个动画帧的宽度
          frame_height = master_rect.height//rows  # 单个动画帧的高度
          for row in range(rows):  # 根据单个动画帧尺寸切割图片
              for col in range(columns):
                  frame_rect = (col * frame_width, row * frame_height, frame_width, frame_height)
                  frame_image = master_image.subsurface(frame_rect)
                  images.append(frame_image)  # 将单个动画帧加入到列表
          return images
      
      
      pygame.init()  # 初始化pygame模块
      
      WIDTH = 1024  # 定义游戏窗口的宽
      HEIGHT = 600  # 定义游戏窗口的高
      FPS = 60
      SCREEN_SIZE = (WIDTH, HEIGHT)  # 定义一个元组
      
      mode_list = pygame.display.list_modes()  # 获取电脑支持的全屏分辨率
      SCREEN_FULL = mode_list[0]
      
      
      screen = pygame.display.set_mode(SCREEN_SIZE)  # 初始化一个显示画面的窗口
      pygame.display.set_caption("MyPygame")  # 设置标题
      bg = pygame.image.load("./PNG/Background.png").convert()  # 加载背景图片
      
      fishGroup = pygame.sprite.Group()  # 创建一个精灵组
      # 水母
      jellyfish_images = load_images("./PNG/Jellyfish.png", 1, 6)
      jellyfish = FishAnimation(jellyfish_images)
      fishGroup.add(jellyfish)
      
      FlatfishGroup = pygame.sprite.Group()  # 创建一个比目鱼精灵组
      # 比目鱼
      for i in range(5):
          fish_images = load_images("./PNG/Flatfish{}.png".format(i), 5, 4)
          fish = FishAnimation(fish_images)
          fish.rect.center = [100+100*i, 100+100*i]
          FlatfishGroup.add(fish) # 将生成的动画比目鱼对象,添加到比目鱼组
      
      GuppyGroup = pygame.sprite.Group()  # 创建一个古比精灵组
      # 古比鱼
      for i in range(6):
          image = pygame.image.load("./PNG/Guppy{}.png".format(i)).convert_alpha()
          fish = Fish(image)
          fish.rect.center = 300, 300  # 更改位置,否则会卡住
          GuppyGroup.add(fish)  # 将生成的图片古比鱼对象,添加到古比鱼组
      
      clock = pygame.time.Clock()
      while True:  # 游戏主循环
          clock.tick(FPS)
          for event in pygame.event.get():  # 获取事件
              if event.type == QUIT:  # 退出
                  pygame.quit()  # 退出pygame模块
                  sys.exit()  # 退出系统
          hits = pygame.sprite.spritecollide(jellyfish,GuppyGroup,False )
          if hits:
              jellyfish.speedx = -jellyfish.speedx
              jellyfish.speedy = -jellyfish.speedy
              jellyfish.reversed()
              for hit in hits:
                  hit.speedx =  - hit.speedx
                  hit.speedy =  - hit.speedy
                  hit.reversed()
          
          screen.blit(bg, (0, 0))  # # 绘制背景
          fishGroup.update()  # 调用组中动画精灵的update方法
          fishGroup.draw(screen)  # 绘制精灵组中的精灵到surface图象上
          FlatfishGroup.update()  # 调用组中动画精灵的update方法
          FlatfishGroup.draw(screen)  # 绘制精灵组中的精灵到surface图象上
          GuppyGroup.update()  # 调用组中动画精灵的update方法
          GuppyGroup.draw(screen)  # 绘制精灵组中的精灵到surface图象上
      
          pygame.display.update()  # 更新窗口画面显示
      
      
      
      • 1