zoukankan      html  css  js  c++  java
  • Python——项目-小游戏3-精灵?蓝精灵?

    等等,我们好像只是绘制了一动的张图

    项目源码

    不知道你有没有发现,我们现在好像只是绘制了一张动的图,只是一张!!!就这么多代码了,如果有100张 10000+张?那我们这么高?

    别担心,pygame给我们提供了解决方案------精灵还有精灵组

    精灵?精灵组?蓝精灵?皮卡丘?

    精灵

    在游戏开发中 显示图像的对象 就是精灵

    1. 别着急我们先来看一下,它确实是一个类,这里是它的类图

    1. 作用:
      • pygame.sprite.Sprite —— 存储 图像数据 image位置 rect 的 **对象
      • pygame.sprite.Group,用来储存之前 pygame.sprite.Sprite创建出来的对象,统一在窗口主程序中的进行绘制
    2. 分析一下这个类的构成
      • 精灵 需要 有 两个重要的属性
      • image 要显示的图像, rect 图像要显示在屏幕的位置
      • 默认的 update() 方法什么事情也没做,子类可以重写此方法,在每次刷新屏幕时,更新精灵位置
    3. 小心有坑!
      • pygame.sprite.Sprite 并没有提供 imagerect 两个属性
      • 需要程序员从 pygame.sprite.Sprite 派生子类
      • 并在 子类初始化方法 中,设置 imagerect 属性

    精灵组

    1. 一个 精灵组 可以包含多个 精灵 对象
    2. 调用 精灵组 对象的 update() 方法
      • 可以 自动 调用 组内每一个精灵update() 方法
    3. 调用 精灵组 对象的 draw(屏幕对象) 方法
      • 可以将 组内每一个精灵image 绘制在 rect 位置
    4. 总的来说就是统一指挥 统一行动,但是每一个项又有自己的独立的运动方法和属性
    Group(*sprites) -> Group
    

    实例代码:

    # 1. 新建 `plane_sprites.py` 文件
    # 2. 定义 `GameSprite` 继承自 `pygame.sprite.Sprite`
    import pygame
    
    # 3.写在括号里的意思是继承父类
    class GameSprite(pygame.sprite.Sprite):
        """飞机大战中的游戏精灵,根据设计的UML编写代码"""
    #注意这里要重写init方法,我们在init初始化方法(行函数)传参
        def __init__(self, image_name, speed=1):
    
            # 调用父类的初始化方法,当我们的父类不是object基类的时候一定要调用super()对象来调用父类的初始化inint方法
            super().__init__()
    
            # 定义对象的属性,它们分别记录着精灵的图片位置速度还有运动方式
            # 加载图像
            self.image = pygame.image.load(image_name)
            # 设置尺寸
            self.rect = self.image.get_rect()
            # 记录速度
            self.speed = speed
    
        def update(self):
    
            # 在屏幕的垂直方向上移动
            self.rect.y += self.speed
    

    如何在我们之前的主程序中使用他们?

    什么?你不知道我们的主程序是什么?好吧,是我忘记告诉你了,我们的主程序就是我们之前写的 绘制窗口的那个程序,

    其实这也非常的简单 ,你只需要在游戏主程序中导入包
    如何完成添加“敌机”精灵,并且让它动起来,再把它们放到游戏循环里面就行了

    1. 注意:
    我们先来明确一下精灵还有精灵组的分工
    1. 精灵
        * 封装 **图像 image**、**位置 rect** 和 **速度 speed**
        * 提供 `update()` 方法,根据游戏需求,**更新位置 rect**
    2. 精灵组
        * 包含 **多个** **精灵对象**
        * `update` 方法,让精灵组中的所有精灵调用 `update` 方法更新位置
        * `draw(screen)` 方法,在 `screen` 上绘制精灵组中的所有精灵
    
    1. 完整的代码实例
    import pygame
    # 你需要导入 form和import 使用inprom导入的时候需要.来使用 使用form的时候 直接使用模块提供的工具就行了。
    # 它们都是实现了导入模块的功能
    from plane_sprites import *
    
    
    # 游戏的初始化
    pygame.init()
    
    # 创建游戏的窗口 480 * 700
    screen = pygame.display.set_mode((480, 700))
    
    # 绘制背景图像
    bg = pygame.image.load("./images/background.png")
    screen.blit(bg, (0, 0))
    # pygame.display.update()
    
    # 绘制英雄的飞机
    hero = pygame.image.load("./images/me1.png")
    screen.blit(hero, (150, 300))
    
    # 可以在所有绘制工作完成之后,统一调用update方法
    pygame.display.update()
    
    # 创建时钟对象
    clock = pygame.time.Clock()
    
    # 1. 定义rect记录飞机的初始位置
    hero_rect = pygame.Rect(150, 300, 102, 126)
    
    
    
    # 开始我们的业务逻辑
    # 创建敌机的精灵
    # 敌人的战斗机对象
    enemy = GameSprite("./images/enemy1.png")
    enemy1 = GameSprite("./images/enemy1.png", 2)
    # 创建敌机的精灵组,我们可以使用多值的方式传递精灵组合,有了这个精灵组,我们就可以直接使用精灵的方法了,一次性的绘制所有的图像
    enemy_group = pygame.sprite.Group(enemy, enemy1)
    
        # # 让精灵组调用两个方法
        # # update - 让组中的所有精灵更新位置,这个是更新位置
        # enemy_group.update()
    
        # # draw - 在screen上绘制所有的精灵,这个是绘制
        # enemy_group.draw(screen)
        # 我们只是调用一次,现在我们把它丢到我们的游戏循环里面去
    
    # 游戏循环 -> 意味着游戏的正式开始!
    while True:
    
        # 可以指定循环体内部的代码执行的频率
        clock.tick(60)
    
        # 监听事件
        for event in pygame.event.get():
    
            # 判断事件类型是否是退出事件
            if event.type == pygame.QUIT:
                print("游戏退出...")
    
                # quit 卸载所有的模块
                pygame.quit()
    
                # exit() 直接终止当前正在执行的程序
                exit()
    
        # 2. 修改飞机的位置
        hero_rect.y -= 1
    
        # 判断飞机的位置
        if hero_rect.y <= 0:
            hero_rect.y = 700
    
        # 3. 调用blit方法绘制图像
        screen.blit(bg, (0, 0))
        screen.blit(hero, hero_rect)
    
        # 让精灵组调用两个方法
        # update - 让组中的所有精灵更新位置,这个是更新位置
        enemy_group.update()
    
        # draw - 在screen上绘制所有的精灵,这个是绘制
        enemy_group.draw(screen)
    
    
        # 4. 调用update方法更新显示
        pygame.display.update()
    
    pygame.quit()
    
    
  • 相关阅读:
    安装 Panda3D 并使用原有的Python
    Jupyter Notebook PDF输出的中文支持
    lua的文件管理
    elasticsearch-hadoop.jar, 适用于spark3,hadoop3
    shell中递归遍历指定文件夹下的文件
    JDBC的ResultSet游标转spark的DataFrame,数据类型的映射以TeraData数据库为例
    Pandas一些小技巧
    用c++后缀自动机实现最大公共字符串算法,并封装成Python库
    后缀自动机的python实现
    PYTHON调用C接口(基于Ctypes)实现stein算法最大公约数的计算
  • 原文地址:https://www.cnblogs.com/BM-laoli/p/12551439.html
Copyright © 2011-2022 走看看