Python项目——飞机大战!

article/2025/4/21 11:00:31

文章目录

  • 一、项目介绍——飞机大战
    • 实战步骤
    • 确认模块 —— pygame
      • 安装 pygame
      • 验证安装
  • 二、pygame 快速入门
    • 项目准备
    • 1. 使用 `pygame` 创建图形窗口
      • 小节目标
      • 1.1 游戏的初始化和退出
      • 1.2 理解游戏中的坐标系
        • 案例演练
      • 1.3 创建游戏主窗口
      • 1.4 简单的游戏循环
    • 2. 理解 **图像** 并实现图像绘制
      • 代码演练 I —— 绘制背景图像
      • 代码演练 II —— 绘制英雄图像
      • 理解 `update()` 方法的作用
    • 3. 理解 **游戏循环** 和 **游戏时钟**
      • 3.1 游戏中的动画实现原理
      • 3.2 **游戏循环**
        • 游戏的两个组成部分
        • 游戏循环的作用
      • 3.3 游戏时钟
      • 3.4 英雄的简单动画实现
        • 作业
      • 3.5 在游戏循环中 监听 事件
        • 事件 `event`
        • 监听
        • 代码实现
    • 4. 理解 **精灵** 和 **精灵组**
      • 4.1 精灵 和 精灵组
        • 精灵
        • 精灵组
      • 4.2 派生精灵子类
      • 4.3 使用 游戏精灵 和 精灵组 创建敌机
        • 实现步骤
  • 三、游戏框架搭建
    • 1. 明确主程序职责
    • 2. 实现飞机大战主游戏类
      • 2.1 明确文件职责
        • 代码实现
      • 2.3 游戏初始化部分
        • 使用 常量 代替固定的数值
      • 2.4 游戏循环部分
    • 3. 准备游戏精灵组
      • 3.1 确定精灵组
      • 3.2 代码实现
  • 四、游戏背景滚动
    • 1. 背景交替滚动的思路确定
      • 1.1 实现思路分析
      • 1.2 设计背景类
    • 2. 显示游戏背景
      • 2.1 背景精灵的基本实现
      • 2.2 在 `plane_main.py` 中显示背景精灵
      • 2.3 利用初始化方法,简化背景精灵创建
  • 五、敌机出场
    • 1. 使用定时器添加敌机
      • 1.1 定时器
      • 1.2 定义并监听创建敌机的定时器事件
        • 1) 定义事件
        • 2) 监听定时器事件
    • 2. 设计 `Enemy` 类
      • 2.1 敌机类的准备
      • 2.2 创建敌机
      • 2.3 随机敌机位置和速度
        • 1) 导入模块
        • 2) 随机位置
        • 3) 代码实现
      • 2.4 移出屏幕销毁敌机
        • 检测敌机被销毁
        • 代码实现
  • 六、英雄登场
    • 1. 设计 **英雄** 和 **子弹** 类
      • 英雄需求
      • 子弹需求
      • Hero —— 英雄
      • Bullet —— 子弹
    • 2. 创建英雄
      • 2.1 准备英雄类
      • 2.2 绘制英雄
        • 代码实现
    • 3. 移动英雄位置
      • 3.1 移动英雄位置
      • 3.2 控制英雄运动边界
    • 4. 发射子弹
      • 需求回顾 —— 英雄需求
      • 4.1 添加发射子弹事件
      • 4.2 定义子弹类
        • 需求回顾 —— 子弹需求
        • Bullet —— 子弹
        • 定义子弹类
      • 4.3 发射子弹
        • 一次发射三枚子弹
  • 七、碰撞检测
    • 1. 了解碰撞检测方法
      • pygame.sprite.groupcollide()
      • pygame.sprite.spritecollide()
    • 2. 碰撞实现

一、项目介绍——飞机大战

按照黑马的教程完成飞机大战项目,我们的项目最终目标如下:

代码放在Gitee上了:https://gitee.com/aniu251700/python-aircraft-war

在这里插入图片描述

在这里插入图片描述

实战步骤

  1. pygame 快速体验
  2. 飞机大战 实战

确认模块 —— pygame

  • pygame 就是一个 Python 模块,专为电子游戏设计
  • 官方网站:https://www.pygame.org/
    • 提示:要学习第三方模块,通常最好的参考资料就在官方网站
网站栏目内容
GettingStarted在各平台安装模块的说明
Docspygame 模块所有 子类 的参考手册

安装 pygame

$ sudo pip3 install pygame

验证安装

$ python3 -m pygame.examples.aliens

输入后会出现这样一个游戏,就表示安装成功了

在这里插入图片描述

二、pygame 快速入门

  1. 项目准备
  2. 使用 pygame 创建图形窗口
  3. 理解 图像 并实现图像绘制
  4. 理解 游戏循环游戏时钟
  5. 理解 精灵精灵组

项目准备

  1. 新建 飞机大战 项目
  2. 新建一个 hm_01_pygame入门.py
  3. 导入 游戏素材图片

游戏的第一印象

  • 把一些 静止的图像 绘制到 游戏窗口
  • 根据 用户的交互 或其他情况,移动 这些图像,产生动画效果
  • 根据 图像之间 是否发生重叠,判断 敌机是否被摧毁 等其他情况

1. 使用 pygame 创建图形窗口

小节目标

  1. 游戏的初始化和退出
  2. 理解游戏中的坐标系
  3. 创建游戏主窗口
  4. 简单的游戏循环

可以将图片素材 绘制游戏的窗口 上,开发游戏之前需要先知道 如何建立游戏窗口

1.1 游戏的初始化和退出

  • 要使用 pygame 提供的所有功能之前,需要调用 init 方法
  • 在游戏结束前需要调用一下 quit 方法
方法说明
pygame.init()导入并初始化所有 pygame 模块,使用其他模块之前,必须先调用 init 方法
pygame.quit()卸载所有 pygame 模块,在游戏结束之前调用!

在这里插入图片描述

import pygamepygame.init()# 游戏代码...pygame.quit()

1.2 理解游戏中的坐标系

  • 坐标系
    • 原点左上角 (0, 0)
    • x 轴 水平方向向 ,逐渐增加
    • y 轴 垂直方向向 ,逐渐增加

在这里插入图片描述

  • 在游戏中,所有可见的元素 都是以 矩形区域 来描述位置的

    • 要描述一个矩形区域有四个要素:(x, y) (width, height)
  • pygame 专门提供了一个类 pygame.Rect 用于描述 矩形区域

Rect(x, y, width, height) -> Rect

在这里插入图片描述

提示

  • pygame.Rect 是一个比较特殊的类,内部只是封装了一些数字计算
  • 不执行 pygame.init() 方法同样能够直接使用

案例演练

需求

  1. 定义 hero_rect 矩形描述 英雄的位置和大小
  2. 输出英雄的 坐标原点xy
  3. 输出英雄的 尺寸宽度高度
hero_rect = pygame.Rect(100, 500, 120, 126)print("坐标原点 %d %d" % (hero_rect.x, hero_rect.y))  # 100 500
print("英雄大小 %d %d" % (hero_rect.width, hero_rect.height))  # 120 126
# size 属性会返回矩形区域的 (宽, 高) 元组
print("英雄大小 %d %d" % hero_rect.size)  # 120 126

1.3 创建游戏主窗口

  • pygame 专门提供了一个 模块 pygame.display 用于创建、管理 游戏窗口
方法说明
pygame.display.set_mode()初始化游戏显示窗口
pygame.display.update()刷新屏幕内容显示,稍后使用

set_mode 方法

set_mode(resolution=(0,0), flags=0, depth=0) -> Surface
  • 作用 —— 创建游戏显示窗口

  • 参数

    • resolution 指定屏幕的 ,默认创建的窗口大小和屏幕大小一致
    • flags 参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递
    • depth 参数表示颜色的位数,默认自动匹配
  • 返回值

    • 暂时 可以理解为 游戏的屏幕游戏的元素 都需要被绘制到 游戏的屏幕
  • 注意:必须使用变量记录 set_mode 方法的返回结果!因为:后续所有的图像绘制都基于这个返回结果

# 创建游戏主窗口
screen = pygame.display.set_mode((480, 700))

1.4 简单的游戏循环

  • 为了做到游戏程序启动后,不会立即退出,通常会在游戏程序中增加一个 游戏循环
  • 所谓 游戏循环 就是一个 无限循环
  • 创建游戏窗口 代码下方,增加一个无限循环
    • 注意:游戏窗口不需要重复创建
# 创建游戏主窗口
screen = pygame.display.set_mode((480, 700))# 游戏循环
while True:pass

2. 理解 图像 并实现图像绘制

  • 在游戏中,能够看到的 游戏元素 大多都是 图像
    • 图像文件 初始是保存在磁盘上的,如果需要使用,第一步 就需要 被加载到内存
  • 要在屏幕上 看到某一个图像的内容,需要按照三个步骤:
    1. 使用 pygame.image.load() 加载图像的数据
    2. 使用 游戏屏幕 对象,调用 blit 方法 将图像绘制到指定位置
    3. 调用 pygame.display.update() 方法更新整个屏幕的显示

在这里插入图片描述

提示:要想在屏幕上看到绘制的结果,就一定要调用 pygame.display.update() 方法

代码演练 I —— 绘制背景图像

需求

  1. 加载 background.png 创建背景
  2. 背景 绘制在屏幕的 (0, 0) 位置
  3. 调用屏幕更新显示背景图像
# 绘制背景图像
# 1> 加载图像
bg = pygame.image.load("./images/background.png")# 2> 绘制在屏幕
screen.blit(bg, (0, 0))# 3> 更新显示
pygame.display.update()

代码演练 II —— 绘制英雄图像

需求

  1. 加载 me1.png 创建英雄飞机
  2. 英雄飞机 绘制在屏幕的 (200, 500) 位置
  3. 调用屏幕更新显示飞机图像
# 1> 加载图像
hero = pygame.image.load("./images/me1.png")# 2> 绘制在屏幕
screen.blit(hero, (200, 500))# 3> 更新显示
pygame.display.update()

透明图像

  • png 格式的图像是支持 透明
  • 在绘制图像时,透明区域 不会显示任何内容
  • 但是如果下方已经有内容,会 透过 透明区域 显示出来

在这里插入图片描述

理解 update() 方法的作用

可以在 screen 对象完成 所有 blit 方法之后,统一调用一次 display.update 方法,同样可以在屏幕上 看到最终的绘制结果

  • 使用 display.set_mode() 创建的 screen 对象 是一个 内存中的屏幕数据对象
    • 可以理解成是 油画画布
  • screen.blit 方法可以在 画布 上绘制很多 图像
    • 例如:英雄敌机子弹
    • 这些图像 有可能 会彼此 重叠或者覆盖
  • display.update() 会将 画布最终结果 绘制在屏幕上,这样可以 提高屏幕绘制效率增加游戏的流畅度

案例调整

# 绘制背景图像
# 1> 加载图像
bg = pygame.image.load("./images/background.png")# 2> 绘制在屏幕
screen.blit(bg, (0, 0))# 绘制英雄图像
# 1> 加载图像
hero = pygame.image.load("./images/me1.png")# 2> 绘制在屏幕
screen.blit(hero, (200, 500))# 3> 更新显示 - update 方法会把之前所有绘制的结果,一次性更新到屏幕窗口上
pygame.display.update()

3. 理解 游戏循环游戏时钟

现在 英雄飞机 已经被绘制到屏幕上了,怎么能够让飞机移动呢

3.1 游戏中的动画实现原理

  • 电影 的原理类似,游戏中的动画效果,本质上是 快速 的在屏幕上绘制 图像
    • 电影是将多张 静止的电影胶片 连续、快速的播放,产生连贯的视觉效果!
  • 一般在电脑上 每秒绘制 60 次,就能够达到非常 连续 高品质 的动画效果
    • 每次绘制的结果被称为 帧 Frame

在这里插入图片描述

在这里插入图片描述

3.2 游戏循环

游戏的两个组成部分

游戏循环的开始 就意味着 游戏的正式开始

在这里插入图片描述

游戏循环的作用

  1. 保证游戏 不会直接退出
  2. 变化图像位置 —— 动画效果
    • 每隔 1 / 60 秒 移动一下所有图像的位置
    • 调用 pygame.display.update() 更新屏幕显示
  3. 检测用户交互 —— 按键、鼠标等…

3.3 游戏时钟

  • pygame 专门提供了一个类 pygame.time.Clock 可以非常方便的设置屏幕绘制速度 —— 刷新帧率
  • 要使用 时钟对象 需要两步:
    • 1)在 游戏初始化 创建一个 时钟对象
    • 2)在 游戏循环 中让时钟对象调用 tick(帧率) 方法
  • tick 方法会根据 上次被调用的时间,自动设置 游戏循环 中的延时
# 3. 创建游戏时钟对象
clock = pygame.time.Clock()
i = 0# 游戏循环
while True:# 设置屏幕刷新帧率clock.tick(60)print(i)i += 1

3.4 英雄的简单动画实现

需求

  1. 游戏初始化 定义一个 pygame.Rect 的变量记录英雄的初始位置
  2. 游戏循环 中每次让 英雄y - 1 —— 向上移动
  3. y <= 0 将英雄移动到屏幕的底部

提示:

  • 每一次调用 update() 方法之前,需要把 所有的游戏图像都重新绘制一遍
  • 而且应该 最先 重新绘制 背景图像
# 4. 定义英雄的初始位置
hero_rect = pygame.Rect(150, 500, 102, 126)while True:# 可以指定循环体内部的代码执行的频率clock.tick(60)# 更新英雄位置hero_rect.y -= 1# 如果移出屏幕,则将英雄的顶部移动到屏幕底部if hero_rect.y <= 0:hero_rect.y = 700# 绘制背景图片screen.blit(bg, (0, 0))# 绘制英雄图像screen.blit(hero, hero_rect)# 更新显示pygame.display.update()

作业

  1. 英雄向上飞行,当 英雄完全从上方飞出屏幕后
  2. 将飞机移动到屏幕的底部
if hero_rect.y + hero_rect.height <= 0:hero_rect.y = 700

提示

  • Rect 的属性 bottom = y + height
if hero_rect.bottom <= 0:hero_rect.y = 700

在这里插入图片描述

3.5 在游戏循环中 监听 事件

事件 event

  • 就是游戏启动后,用户针对游戏所做的操作
  • 例如:点击关闭按钮点击鼠标按下键盘

监听

  • 游戏循环 中,判断用户 具体的操作

只有 捕获 到用户具体的操作,才能有针对性的做出响应

代码实现

  • pygame 中通过 pygame.event.get() 可以获得 用户当前所做动作事件列表
    • 用户可以同一时间做很多事情
  • 提示:这段代码非常的固定,几乎所有的 pygame 游戏都 大同小异
# 游戏循环
while True:# 设置屏幕刷新帧率clock.tick(60)# 事件监听for event in pygame.event.get():# 判断用户是否点击了关闭按钮if event.type == pygame.QUIT:print("退出游戏...")pygame.quit()# 直接退出系统exit()

4. 理解 精灵精灵组

4.1 精灵 和 精灵组

  • 在刚刚完成的案例中,图像加载位置变化绘制图像 都需要程序员编写代码分别处理
  • 为了简化开发步骤,pygame 提供了两个类
    • pygame.sprite.Sprite —— 存储 图像数据 image位置 rect对象
    • pygame.sprite.Group

在这里插入图片描述

精灵

  • 在游戏开发中,通常把 显示图像的对象 叫做精灵 Sprite

  • 精灵 需要 有 两个重要的属性

    • image 要显示的图像
    • rect 图像要显示在屏幕的位置
  • 默认的 update() 方法什么事情也没做

    • 子类可以重写此方法,在每次刷新屏幕时,更新精灵位置
  • 注意pygame.sprite.Sprite 并没有提供 imagerect 两个属性

    • 需要程序员从 pygame.sprite.Sprite 派生子类
    • 并在 子类初始化方法 中,设置 imagerect 属性

精灵组

  • 一个 精灵组 可以包含多个 精灵 对象
  • 调用 精灵组 对象的 update() 方法
    • 可以 自动 调用 组内每一个精灵update() 方法
  • 调用 精灵组 对象的 draw(屏幕对象) 方法
    • 可以将 组内每一个精灵image 绘制在 rect 位置
Group(*sprites) -> Group

注意:仍然需要调用 pygame.display.update() 才能在屏幕看到最终结果

4.2 派生精灵子类

  1. 新建 plane_sprites.py 文件
  2. 定义 GameSprite 继承自 pygame.sprite.Sprite

注意

  • 如果一个类的 父类 不是 object
  • 在重写 初始化方法 时,一定要super() 一下父类的 __init__ 方法
  • 保证父类中实现的 __init__ 代码能够被正常执行

在这里插入图片描述

属性

  • image 精灵图像,使用 image_name 加载
  • rect 精灵大小,默认使用图像大小
  • speed 精灵移动速度,默认为 1

方法

  • update 每次更新屏幕时在游戏循环内调用
    • 让精灵的 self.rect.y += self.speed

提示

  • imageget_rect() 方法,可以返回 pygame.Rect(0, 0, 图像宽, 图像高) 的对象
import pygameclass GameSprite(pygame.sprite.Sprite):"""游戏精灵基类"""def __init__(self, image_name, speed=1):# 调用父类的初始化方法super().__init__()# 加载图像self.image = pygame.image.load(image_name)# 设置尺寸self.rect = self.image.get_rect()# 记录速度self.speed = speeddef update(self, *args):# 默认在垂直方向移动self.rect.y += self.speed

4.3 使用 游戏精灵 和 精灵组 创建敌机

需求

  • 使用刚刚派生的 游戏精灵精灵组 创建 敌机 并且实现敌机动画

步骤

  1. 使用 from 导入 plane_sprites 模块
    • from 导入的模块可以 直接使用
    • import 导入的模块需要通过 模块名. 来使用
  2. 游戏初始化 创建 精灵对象精灵组对象
  3. 游戏循环中精灵组 分别调用 update()draw(screen) 方法

职责

  • 精灵
    • 封装 图像 image位置 rect速度 speed
    • 提供 update() 方法,根据游戏需求,更新位置 rect
  • 精灵组
    • 包含 多个 精灵对象
    • update 方法,让精灵组中的所有精灵调用 update 方法更新位置
    • draw(screen) 方法,在 screen 上绘制精灵组中的所有精灵

实现步骤

  1. 导入 plane_sprites 模块
from plane_sprites import *
  1. 修改初始化部分代码
# 创建敌机精灵和精灵组
enemy1 = GameSprite("./images/enemy1.png")
enemy2 = GameSprite("./images/enemy1.png", 2)
enemy2.rect.x = 200
enemy_group = pygame.sprite.Group(enemy1, enemy2)
  1. 修改游戏循环部分代码
# 让敌机组调用 update 和 draw 方法
enemy_group.update()
enemy_group.draw(screen)# 更新屏幕显示
pygame.display.update()

三、游戏框架搭建

目标 —— 使用 面相对象 设计 飞机大战游戏类

  • 明确主程序职责
  • 实现主程序类
  • 准备游戏精灵组

1. 明确主程序职责

  • 回顾 快速入门案例,一个游戏主程序的 职责 可以分为两个部分:
    • 游戏初始化
    • 游戏循环
  • 根据明确的职责,设计 PlaneGame 类如下:

在这里插入图片描述

提示 根据 职责 封装私有方法,可以避免某一个方法的代码写得太过冗长

如果某一个方法编写的太长,既不好阅读,也不好维护!

  • 游戏初始化 —— __init__() 会调用以下方法:
方法职责
__create_sprites(self)创建所有精灵和精灵组
  • 游戏循环 —— start_game() 会调用以下方法:
方法职责
__event_handler(self)事件监听
__check_collide(self)碰撞检测 —— 子弹销毁敌机、敌机撞毁英雄
__update_sprites(self)精灵组更新和绘制
__game_over()游戏结束

2. 实现飞机大战主游戏类

2.1 明确文件职责

在这里插入图片描述

  • plane_main
    1. 封装 主游戏类
    2. 创建 游戏对象
    3. 启动游戏
  • plane_sprites
    • 封装游戏中 所有 需要使用的 精灵子类
    • 提供游戏的 相关工具

代码实现

  • 新建 plane_main.py 文件,并且设置为可执行
  • 编写 基础代码
import pygame
from plane_sprites import *class PlaneGame(object):"""飞机大战主游戏"""def __init__(self):print("游戏初始化")def start_game(self):print("开始游戏...")if __name__ == '__main__':# 创建游戏对象game = PlaneGame()# 开始游戏game.start_game()

2.3 游戏初始化部分

  • 完成 __init__() 代码如下:
def __init__(self):print("游戏初始化")# 1. 创建游戏的窗口self.screen = pygame.display.set_mode((480, 700))# 2. 创建游戏的时钟self.clock = pygame.time.Clock()# 3. 调用私有方法,精灵和精灵组的创建self.__create_sprites()def __create_sprites(self):pass

使用 常量 代替固定的数值

  • 常量 —— 不变化的量
  • 变量 —— 可以变化的量

应用场景

  • 在开发时,可能会需要使用 固定的数值,例如 屏幕的高度700
  • 这个时候,建议 不要 直接使用固定数值,而应该使用 常量
  • 在开发时,为了保证代码的可维护性,尽量不要使用 魔法数字

常量的定义

  • 定义 常量 和 定义 变量 的语法完全一样,都是使用 赋值语句
  • 常量命名 应该 所有字母都使用大写单词与单词之间使用下划线连接

常量的好处

  • 阅读代码时,通过 常量名 见名之意,不需要猜测数字的含义
  • 如果需要 调整值,只需要 修改常量定义 就可以实现 统一修改

提示:Python 中并没有真正意义的常量,只是通过命名的约定 —— 所有字母都是大写的就是常量,开发时不要轻易的修改!

代码调整

  • plane_sprites.py 中增加常量定义
import pygame# 游戏屏幕大小
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
  • 修改 plane_main.py 中的窗口大小
self.screen = pygame.display.set_mode(SCREEN_RECT.size)

2.4 游戏循环部分

  • 完成 start_game() 基础代码如下:
def start_game(self):"""开始游戏"""print("开始游戏...")while True:# 1. 设置刷新帧率self.clock.tick(60)# 2. 事件监听self.__event_handler()# 3. 碰撞检测self.__check_collide()# 4. 更新精灵组self.__update_sprites()# 5. 更新屏幕显示pygame.display.update()def __event_handler(self):"""事件监听"""for event in pygame.event.get():if event.type == pygame.QUIT:PlaneGame.__game_over()def __check_collide(self):"""碰撞检测"""passdef __update_sprites(self):"""更新精灵组"""pass@staticmethod
def __game_over():"""游戏结束"""print("游戏结束")pygame.quit()exit()

3. 准备游戏精灵组

3.1 确定精灵组

在这里插入图片描述

3.2 代码实现

  • 创建精灵组方法
def __create_sprites(self):"""创建精灵组"""# 背景组self.back_group = pygame.sprite.Group()# 敌机组self.enemy_group = pygame.sprite.Group()# 英雄组self.hero_group = pygame.sprite.Group()
  • 更新精灵组方法
def __update_sprites(self):"""更新精灵组"""for group in [self.back_group, self.enemy_group, self.hero_group]:group.update()group.draw(self.screen)

四、游戏背景滚动

  • 背景交替滚动的思路确定
  • 显示游戏背景

1. 背景交替滚动的思路确定

运行 备课代码观察 背景图像的显示效果:

  • 游戏启动后,背景图像连续不断地 向下方 移动
  • 视觉上 产生英雄的飞机不断向上方飞行的 错觉 —— 在很多跑酷类游戏中常用的套路
    • 游戏的背景 不断变化
    • 游戏的主角 位置保持不变

1.1 实现思路分析

在这里插入图片描述

解决办法

  1. 创建两张背景图像精灵
    • 1完全和屏幕重合
    • 2 张在 屏幕的正上方
  2. 两张图像 一起向下方运动
    • self.rect.y += self.speed
  3. 任意背景精灵rect.y >= 屏幕的高度 说明已经 移动到屏幕下方
  4. 移动到屏幕下方的这张图像 设置到 屏幕的正上方
    • rect.y = -rect.height

1.2 设计背景类

在这里插入图片描述

  • 初始化方法
    • 直接指定 背景图片
    • is_alt 判断是否是另一张图像
      • False 表示 第一张图像,需要与屏幕重合
      • True 表示 另一张图像,在屏幕的正上方
  • update() 方法
    • 判断 是否移动出屏幕,如果是,将图像设置到 屏幕的正上方,从而实现 交替滚动

继承 如果父类提供的方法,不能满足子类的需求:

  • 派生一个子类
  • 在子类中针对特有的需求,重写父类方法,并且进行扩展

2. 显示游戏背景

2.1 背景精灵的基本实现

  • plane_sprites 新建 Background 继承自 GameSprite
class Background(GameSprite):"""游戏背景精灵"""def update(self):# 1. 调用父类的方法实现super().update()# 2. 判断是否移出屏幕,如果移出屏幕,将图像设置到屏幕的上方if self.rect.y >= SCREEN_RECT.height:self.rect.y = -self.rect.height

2.2 在 plane_main.py 中显示背景精灵

  1. __create_sprites 方法中创建 精灵精灵组
  2. __update_sprites 方法中,让 精灵组 调用 update()draw() 方法

__create_sprites 方法

def __create_sprites(self):# 创建背景精灵和精灵组bg1 = Background("./images/background.png")bg2 = Background("./images/background.png")bg2.rect.y = -bg2.rect.heightself.back_group = pygame.sprite.Group(bg1, bg2)

__update_sprites 方法

def __update_sprites(self):self.back_group.update()self.back_group.draw(self.screen)

2.3 利用初始化方法,简化背景精灵创建

思考 —— 上一小结完成的代码存在什么样的问题?能否简化?

  • 在主程序中,创建的两个背景精灵传入了相同的图像文件路径
  • 创建 第二个 背景精灵 时,在主程序中,设置背景精灵的图像位置

思考 —— 精灵 初始位置 的设置,应该 由主程序负责?还是 由精灵自己负责

答案 —— 由精灵自己负责

  • 根据面向对象设计原则,应该将对象的职责,封装到类的代码内部
  • 尽量简化程序调用一方的代码调用

在这里插入图片描述

  • 初始化方法
    • 直接指定 背景图片
    • is_alt 判断是否是另一张图像
      • False 表示 第一张图像,需要与屏幕重合
      • True 表示 另一张图像,在屏幕的正上方

plane_sprites.py 中实现 Background初始化方法

def __init__(self, is_alt=False):image_name = "./images/background.png"super().__init__(image_name)# 判断是否交替图片,如果是,将图片设置到屏幕顶部if is_alt:self.rect.y = -self.rect.height     
  • 修改 plane_main__create_sprites 方法
# 创建背景精灵和精灵组
bg1 = Background()
bg2 = Background(True)self.back_group = pygame.sprite.Group(bg1, bg2)

五、敌机出场

  • 使用 定时器 添加敌机
  • 设计 Enemy

1. 使用定时器添加敌机

运行 备课代码观察 敌机的 出现规律

  1. 游戏启动后,每隔 1 秒出现一架敌机
  2. 每架敌机 向屏幕下方飞行,飞行 速度各不相同
  3. 每架敌机出现的 水平位置 也不尽相同
  4. 当敌机 从屏幕下方飞出,不会再飞回到屏幕中

1.1 定时器

  • pygame 中可以使用 pygame.time.set_timer() 来添加 定时器
  • 所谓 定时器,就是 每隔一段时间,去 执行一些动作
set_timer(eventid, milliseconds) -> None
  • set_timer 可以创建一个 事件
  • 可以在 游戏循环事件监听 方法中捕获到该事件
  • 第 1 个参数 事件代号 需要基于常量 pygame.USEREVENT 来指定
    • USEREVENT 是一个整数,再增加的事件可以使用 USEREVENT + 1 指定,依次类推…
  • 第 2 个参数是 事件触发 间隔的 毫秒值

定时器事件的监听

  • 通过 pygame.event.get() 可以获取当前时刻所有的 事件列表
  • 遍历列表 并且判断 event.type 是否等于 eventid,如果相等,表示 定时器事件 发生

1.2 定义并监听创建敌机的定时器事件

pygame定时器 使用套路非常固定:

  1. 定义 定时器常量 —— eventid
  2. 初始化方法 中,调用 set_timer 方法 设置定时器事件
  3. 游戏循环 中,监听定时器事件

1) 定义事件

  • plane_sprites.py 的顶部定义 事件常量
# 敌机的定时器事件常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
  • PlaneGame初始化方法创建用户事件
# 4. 设置定时器事件 - 每秒创建一架敌机
pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)

2) 监听定时器事件

  • __event_handler 方法中增加以下代码:
def __event_handler(self):for event in pygame.event.get():# 判断是否退出游戏if event.type == pygame.QUIT:PlaneGame.__game_over()elif event.type == CREATE_ENEMY_EVENT:print("敌机出场...")

2. 设计 Enemy

  1. 游戏启动后,每隔 1 秒出现一架敌机
  2. 每架敌机 向屏幕下方飞行,飞行 速度各不相同
  3. 每架敌机出现的 水平位置 也不尽相同
  4. 当敌机 从屏幕下方飞出,不会再飞回到屏幕中

在这里插入图片描述

  • 初始化方法
    • 指定 敌机图片
    • 随机 敌机的 初始位置初始速度
  • 重写 update() 方法
    • 判断 是否飞出屏幕,如果是,从 精灵组 删除

2.1 敌机类的准备

  • plane_sprites 新建 Enemy 继承自 GameSprite
  • 重写 初始化方法,直接指定 图片名称
  • 暂时 不实现 随机速度随机位置 的指定
  • 重写 update 方法,判断是否飞出屏幕
class Enemy(GameSprite):"""敌机精灵"""def __init__(self):# 1. 调用父类方法,创建敌机精灵,并且指定敌机的图像super().__init__("./images/enemy1.png")# 2. 设置敌机的随机初始速度# 3. 设置敌机的随机初始位置def update(self):# 1. 调用父类方法,让敌机在垂直方向运动super().update()# 2. 判断是否飞出屏幕,如果是,需要将敌机从精灵组删除if self.rect.y >= SCREEN_RECT.height:print("敌机飞出屏幕...")    

2.2 创建敌机

演练步骤

  1. __create_sprites,添加 敌机精灵组
    • 敌机是 定时被创建的,因此在初始化方法中,不需要创建敌机
  2. __event_handler,创建敌机,并且 添加到精灵组
    • 调用 精灵组add 方法可以 向精灵组添加精灵
  3. __update_sprites,让 敌机精灵组 调用 updatedraw 方法

在这里插入图片描述

演练代码

  • 修改 plane_main__create_sprites 方法
# 敌机组
self.enemy_group = pygame.sprite.Group()
  • 修改 plane_main__update_sprites 方法
self.enemy_group.update()
self.enemy_group.draw(self.screen)
  • 定时出现敌机
elif event.type == CREATE_ENEMY_EVENT:self.enemy_group.add(Enemy())

2.3 随机敌机位置和速度

1) 导入模块

  • 在导入模块时,建议 按照以下顺序导入
1. 官方标准模块导入
2. 第三方模块导入
3. 应用程序模块导入
  • 修改 plane_sprites.py 增加 random 的导入
import random

2) 随机位置

在这里插入图片描述

使用 pygame.Rect 提供的 bottom 属性,在指定敌机初始位置时,会比较方便

  • bottom = y + height
  • y = bottom - height

3) 代码实现

  • 修改 初始化方法,随机敌机出现 速度位置
def __init__(self):# 1. 调用父类方法,创建敌机精灵,并且指定敌机的图像super().__init__("./images/enemy1.png")# 2. 设置敌机的随机初始速度 1 ~ 3self.speed = random.randint(1, 3)# 3. 设置敌机的随机初始位置self.rect.bottom = 0max_x = SCREEN_RECT.width - self.rect.widthself.rect.x = random.randint(0, max_x)

2.4 移出屏幕销毁敌机

  • 敌机移出屏幕之后,如果 没有撞到英雄,敌机的历史使命已经终结
  • 需要从 敌机组 删除,否则会造成 内存浪费

检测敌机被销毁

  • __del__ 内置方法会在对象被销毁前调用,在开发中,可以用于 判断对象是否被销毁
def __del__(self):print("敌机挂了 %s" % self.rect)

代码实现

在这里插入图片描述

  • 判断敌机是否飞出屏幕,如果是,调用 kill() 方法从所有组中删除
def update(self):super().update()# 判断敌机是否移出屏幕if self.rect.y >= SCREEN_RECT.height:# 将精灵从所有组中删除self.kill()

六、英雄登场

  • 设计 英雄子弹
  • 使用 pygame.key.get_pressed() 移动英雄
  • 发射子弹

1. 设计 英雄子弹

英雄需求

  1. 游戏启动后,英雄 出现在屏幕的 水平中间 位置,距离 屏幕底部 120 像素
  2. 英雄 每隔 0.5 秒发射一次子弹,每次 连发三枚子弹
  3. 英雄 默认不会移动,需要通过 左/右 方向键,控制 英雄 在水平方向移动

在这里插入图片描述

子弹需求

  1. 子弹英雄 的正上方发射 沿直线上方 飞行
  2. 飞出屏幕后,需要从 精灵组 中删除

在这里插入图片描述

Hero —— 英雄

  • 初始化方法
    • 指定 英雄图片
    • 初始速度 = 0 —— 英雄默认静止不动
    • 定义 bullets 子弹精灵组 保存子弹精灵
  • 重写 update() 方法
    • 英雄需要 水平移动
    • 并且需要保证不能 移出屏幕
  • 增加 bullets 属性,记录所有 子弹精灵
  • 增加 fire 方法,用于发射子弹

Bullet —— 子弹

  • 初始化方法
    • 指定 子弹图片
    • 初始速度 = -2 —— 子弹需要向上方飞行
  • 重写 update() 方法
    • 判断 是否飞出屏幕,如果是,从 精灵组 删除

2. 创建英雄

2.1 准备英雄类

  • plane_sprites 新建 Hero
  • 重写 初始化方法,直接指定 图片名称,并且将初始速度设置为 0
  • 设置 英雄的初始位置

在这里插入图片描述

  • centerx = x + 0.5 * width
  • centery = y + 0.5 * height
  • bottom = y + height

在这里插入图片描述

class Hero(GameSprite):"""英雄精灵"""def __init__(self):super().__init__("./images/me1.png", 0)# 设置初始位置self.rect.centerx = SCREEN_RECT.centerxself.rect.bottom = SCREEN_RECT.bottom - 120

2.2 绘制英雄

  1. __create_sprites,添加 英雄精灵英雄精灵组
    • 后续要针对 英雄碰撞检测 以及 发射子弹
    • 所以 英雄 需要 单独定义成属性
  2. __update_sprites,让 英雄精灵组 调用 updatedraw 方法

代码实现

  • 修改 __create_sprites 方法如下:
# 英雄组
self.hero = Hero()
self.hero_group = pygame.sprite.Group(self.hero)
  • 修改 __update_sprites 方法如下:
self.hero_group.update()
self.hero_group.draw(self.screen)

3. 移动英雄位置

pygame 中针对 键盘按键的捕获,有 两种 方式

  • 第一种方式 判断 event.type == pygame.KEYDOWN
  • 第二种方式
    1. 首先使用 pygame.key.get_pressed() 返回 所有按键元组
    2. 通过 键盘常量,判断元组中 某一个键是否被按下 —— 如果被按下,对应数值为 1

提问 这两种方式之间有什么区别呢?

  • 第一种方式
elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:print("向右移动...")
  • 第二种方式
# 返回所有按键的元组,如果某个键被按下,对应的值会是1
keys_pressed = pygame.key.get_pressed()
# 判断是否按下了方向键
if keys_pressed[pygame.K_RIGHT]:print("向右移动...")

结论

  • 第一种方式 event.type 用户 必须要抬起按键 才算一次 按键事件操作灵活性会大打折扣
  • 第二种方式 用户可以按住方向键不放,就能够实现持续向某一个方向移动了,操作灵活性更好

3.1 移动英雄位置

演练步骤

  1. Hero 类中重写 update 方法
    • 速度 speed英雄 rect.x 进行叠加
    • 不需要调用父类方法 —— 父类方法只是实现了单纯的垂直运动
  2. __event_handler 方法中根据 左右方向键 设置英雄的 速度
    • 向右 => speed = 2
    • 向左 => speed = -2
    • 其他 => speed = 0

代码演练

  • Hero 类,重写 update() 方法,根据速度水平移动 英雄的飞机
def update(self):# 飞机水平移动self.rect.x += self.speed
  • 调整键盘按键代码
# 获取用户按键
keys_pressed = pygame.key.get_pressed()if keys_pressed[pygame.K_RIGHT]:self.hero.speed = 2
elif keys_pressed[pygame.K_LEFT]:self.hero.speed = -2
else:self.hero.speed = 0

3.2 控制英雄运动边界

  • Hero 类的 update() 方法判断 英雄 是否超出 屏幕边界

在这里插入图片描述

  • right = x + width 利用 right 属性可以非常容易的针对右侧设置精灵位置

在这里插入图片描述

def update(self):# 飞机水平移动self.rect.x += self.speed# 判断屏幕边界if self.rect.left < 0:self.rect.left = 0if self.rect.right > SCREEN_RECT.right:self.rect.right = SCREEN_RECT.right

4. 发射子弹

需求回顾 —— 英雄需求

  1. 游戏启动后,英雄 出现在屏幕的 水平中间 位置,距离 屏幕底部 120 像素
  2. 英雄 每隔 0.5 秒发射一次子弹,每次 连发三枚子弹
  3. 英雄 默认不会移动,需要通过 左/右 方向键,控制 英雄 在水平方向移动

4.1 添加发射子弹事件

pygame定时器 使用套路非常固定:

  1. 定义 定时器常量 —— eventid
  2. 初始化方法 中,调用 set_timer 方法 设置定时器事件
  3. 游戏循环 中,监听定时器事件

代码实现

  • Hero 中定义 fire 方法
def fire(self):    print("发射子弹...")
  • plane_main.py 的顶部定义 发射子弹 事件常量
# 英雄发射子弹事件
HERO_FIRE_EVENT = pygame.USEREVENT + 1
  • __init__ 方法末尾中添加 发射子弹 事件
# 每隔 0.5 秒发射一次子弹
pygame.time.set_timer(HERO_FIRE_EVENT, 500)
  • __event_handler 方法中让英雄发射子弹
elif event.type == HERO_FIRE_EVENT:    self.hero.fire()

4.2 定义子弹类

需求回顾 —— 子弹需求

  1. 子弹英雄 的正上方发射 沿直线上方 飞行
  2. 飞出屏幕后,需要从 精灵组 中删除

Bullet —— 子弹

  • 初始化方法
    • 指定 子弹图片
    • 初始速度 = -2 —— 子弹需要向上方飞行
  • 重写 update() 方法
    • 判断 是否飞出屏幕,如果是,从 精灵组 删除

定义子弹类

  • plane_sprites 新建 Bullet 继承自 GameSprite
  • 重写 初始化方法,直接指定 图片名称,并且设置 初始速度
  • 重写 update() 方法,判断子弹 飞出屏幕从精灵组删除
class Bullet(GameSprite):    """子弹精灵"""        def __init__(self):                super().__init__("./images/bullet1.png", -2)     def update(self):            super().update()                # 判断是否超出屏幕,如果是,从精灵组删除        if self.rect.bottom < 0:            self.kill()

4.3 发射子弹

演练步骤

  1. Hero初始化方法 中创建 子弹精灵组 属性
  2. 修改 plane_main.py__update_sprites 方法,让 子弹精灵组 调用 updatedraw 方法
  3. 实现 fire() 方法
    • 创建子弹精灵
    • 设置初始位置 —— 在 英雄的正上方
    • 子弹 添加到精灵组

代码实现

  • 初始化方法
# 创建子弹的精灵组
self.bullets = pygame.sprite.Group()
  • 修改 fire() 方法
def fire(self):# 1. 创建子弹精灵   bullet = Bullet()       # 2. 设置精灵的位置    bullet.rect.bottom = self.rect.y - 20    bullet.rect.centerx = self.rect.centerx        # 3. 将精灵添加到精灵组    self.bullets.add(bullet)

一次发射三枚子弹

在这里插入图片描述

  • 修改 fire() 方法,一次发射三枚子弹
def fire(self):    for i in (1, 2, 3):        # 1. 创建子弹精灵        bullet = Bullet()                # 2. 设置精灵的位置        bullet.rect.bottom = self.rect.y - i * 20        bullet.rect.centerx = self.rect.centerx                # 3. 将精灵添加到精灵组        self.bullets.add(bullet)

七、碰撞检测

  • 了解碰撞检测方法
  • 碰撞实现

1. 了解碰撞检测方法

  • pygame 提供了 两个非常方便 的方法可以实现碰撞检测:

pygame.sprite.groupcollide()

  • 两个精灵组所有的精灵 的碰撞检测
groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_dict
  • 如果将 dokill 设置为 True,则 发生碰撞的精灵将被自动移除
  • collided 参数是用于 计算碰撞的回调函数
    • 如果没有指定,则每个精灵必须有一个 rect 属性

pygame.sprite.spritecollide()

  • 判断 某个精灵指定精灵组 中的精灵的碰撞
spritecollide(sprite, group, dokill, collided = None) -> Sprite_list
  • 如果将 dokill 设置为 True,则 指定精灵组发生碰撞的精灵将被自动移除
  • collided 参数是用于 计算碰撞的回调函数
    • 如果没有指定,则每个精灵必须有一个 rect 属性
  • 返回 精灵组 中跟 精灵 发生碰撞的 精灵列表

2. 碰撞实现

def __check_collide(self):# 1. 子弹摧毁敌机pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)# 2. 敌机撞毁英雄enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)# 判断列表时候有内容if len(enemies) > 0:# 让英雄牺牲self.hero.kill()# 结束游戏PlaneGame.__game_over()

此时我们整个游戏就完成了!!!


http://chatgpt.dhexx.cn/article/DfVGCO8b.shtml

相关文章

python和java哪个更有前景,python和java哪个更有前途

大家好&#xff0c;小编为大家解答python和java哪个好学,零基础的问题。很多人还不知道python和java哪个更容易入门&#xff0c;现在让我们一起来看看吧&#xff01; 进入编程行业是很多人的梦想&#xff0c;现在越来越多的人都想要通过培训的方式进入IT行业中&#xff0c;但是…

Python项目实战之《飞机大战游戏》

目录 一、Pygame库包简介 二、Pygame安装 三、项目开发思路 3.1前言 3.2飞机大战开发步骤 一、Pygame库包简介 Pygame是一个基于python的游戏开发库&#xff0c;它提供一系列的工具和接口&#xff0c;使开发人员能够轻松的创建各种类型的游戏&#xff0c;包括2D游戏和简单…

Java调用Python语言及第三方Python库

#pic_center 400x 系列文章&#xff1a; 文章目录 1、导入依赖 <!--Python&Java--><dependency><groupId>org.python</groupId><artifactId>jython-standalone</artifactId><version>2.7.2</version></dependency>…

Python 代码托管到码云平台,原来这么简单

什么是代码托管&#xff1f;代码托管又有什么好处&#xff1f; 场景1&#xff1a;我有2个电脑&#xff0c;公司一台&#xff0c;家里一台。我想在两台电脑上都进行同步开发。这时候我只要git push/pull一下就能够同步了&#xff0c;不再需要用U盘拷来拷去 场景2&#xff1a;我…

Python游戏开发-超级海盗!!!

开发环境配置 安装python环境后&#xff0c;下载pygame模块&#xff0c;使用如下命令 pip install pygame 注&#xff1a;该项目使用了一些新特性&#xff0c;使用3.10以上的版本 游戏项目介绍 游戏分为两个模块&#xff0c;分别是编辑模块和关卡模块&#xff0c;在编辑模…

chatgpt赋能python:Python编译成Java字节码:一个全新的可能性

Python编译成Java字节码&#xff1a;一个全新的可能性 Python作为一种高级编程语言&#xff0c;有其独特的优点和特点&#xff0c;被广泛应用于各个领域。然而&#xff0c;随着Python在企业级应用中的广泛应用&#xff0c;性能和安全等方面的问题也越来越凸显出来。这时&#…

鲲鹏法(一)python环境搭建

简单总结一下python的开发环境&#xff08;偏科学计算一些&#xff09;&#xff0c;Pycharm等之后再补了 python环境搭建 一.Python二.IPython三.Jupyter1.Jupyder QtConsole(了解即可)2.Jupyder Notebook3.Jupyder Lab4.单元类型5.编辑单元6.Markdown单元7.输出显示8.nbconver…

【预测模型-ELM预测】基于原子搜索算法优化极限学习机预测matlab代码

​1 简介 针对变压器故障的特征,结合变压器油中气体分析法以及三比值法.提出了基于原子搜索算法改进极限学习机的故障诊断方法.由于输入层与隐含层的权值和阈值是随机产生.传统的极限学习机可能会使隐含层节点过多,训练过程中容易产生过拟合现象.该方法运用原子搜索算法对极限…

ELMo模型解读

在反复的看了ELMo源码和参考网上各路大神的经验之后&#xff0c;终于对ELMo的架构有了比较清楚的认识。总结一下自己对ELMo的理解&#xff0c;其实还有很多细节没有搞清楚。 一.模型架构 下面是我画的一个架构简图&#xff0c;对于ELMo不管你输入的是词还是字符&#xff0c;它…

【预测模型】基于粒子群算法PSO优化极限学习机ELM实现数据预测matlab源码

1 模型 为了提高空气质量预测精度,提出一种基于粒子群算法优化极限学习机的空气质量预测模型.运用粒子群算法优化极限学习机的初始权值和偏置,在保证预测误差最小的情况下实现空气质量最优预测.选择平均绝对百分比误差,均方根误差和平均绝对误差作为评价指标,通过PSO-ELM和ELM…

多元分类预测 | Matlab麻雀算法(SSA)优化极限学习机(ELM)的分类预测,多特征输入模型。SSA-ELM分类预测模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 麻雀算法(SSA)优化极限学习机(ELM)的分类预测,多特征输入模型。SSA-ELM分类预测模型 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,程序可出分类效果图,迭代…

多元分类预测 | Matlab粒子群算法(PSO)优化极限学习机(ELM)的分类预测,多特征输入模型。PSO-ELM分类预测模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab粒子群算法(PSO)优化极限学习机(ELM)的分类预测,多特征输入模型。PSO-ELM分类预测模型 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,…

【预测模型-ELM分类】基于极限学习机ELM+OSELM+KELM+半监督SSELM+USELM实现数据集分类附matlab代码

1 内容介绍 极限学习机是由黄广斌等&#xff3b;13&#xff3d;提出的一种针对前馈神经网络设计的机器学习算法。该算法结构简单、计算速率快。ELM的关键在于找到输出和输出之间的映射空间。首先确定隐含层之间的连接权值w和隐含层神经元的偏置b。选择一个无限可微的函数作为隐…

多元分类预测 | Matlab鲸鱼算法(WOA)优化极限学习机(ELM)的分类预测,多特征输入模型。WOA-ELM分类预测模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab鲸鱼算法(WOA)优化极限学习机(ELM)的分类预测,多特征输入模型。WOA-ELM分类预测模型 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,程…

【ELM数据预测】基于matlab粒子群算法优化ELM数据预测(含前后对比)【含Matlab源码 449期】

✅博主简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;Matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;海神之光 &#x1f3c6;代码获取方式&#xff1a; 海神之光Matlab王者学习之路—代码获取方式 ⛳️座右铭&#xff1a;…

elmo模型详解

elmo模型结构 如下所示是elmo模型结构图&#xff1a; 在输入中可以采用worc2vec模型 训练的词向量。 其实总的来说&#xff0c;elmo模型就是若干bilstm的堆积&#xff0c;然后训练得到的&#xff0c; 对于某一个单词[公式]&#xff0c;一个L层的双向语言模型biLM由2L1个向量表…

多元分类预测 | Matlab灰狼算法(GWO)优化极限学习机(ELM)的分类预测,多特征输入模型。GWO-ELM分类预测模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | 灰狼算法(GWO)优化极限学习机(ELM)的分类预测,多特征输入模型。GWO-ELM分类预测模型 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,程序可出…

ELMo模型简介

word2vec是一种静态词嵌入方法&#xff0c;它不会随着上下文场景的变化而变化。但一词多义在现实中太常见了&#xff0c;因此这种静态嵌入的局限性在很多场景显得力不从心。而ELMo就是为解决这些问题提出的&#xff0c;它的提出意味着从词嵌入(Word Embedding)时代进入了语境词…

【ELM回归预测】基于matlab粒子群算法优化ELM回归预测【含Matlab源码 1722期】

✅博主简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;Matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;海神之光 &#x1f3c6;代码获取方式&#xff1a; 海神之光Matlab王者学习之路—代码获取方式 ⛳️座右铭&#xff1a;…

【预测模型】基于 Elm神经网络的电力负荷预测模型matlab源码

1. 算法概述 **\ ELM算法针对的问题是单隐层的前馈神经网络(single-hidden layer feedforward neural networks&#xff0c;SLFNs)&#xff0c;算法特点在于输入层到隐层的权重W和偏差B可以随机设定&#xff0c;隐层激励函数具有无限可微的特征即可(常用的有radial basis、sine…