信号处理之插值、抽取与多项滤波
信号处理之插值、抽取与多项滤波
一、问题背景
插值(Interpolation)与抽取(Decimation)是数字信号处理中采样率转换的核心操作:
- 插值:在信号中插入新样本以提高采样率( L L L倍)
- 抽取:按比例 M M M降低采样率(需防混叠)
多项滤波通过多相分解优化计算效率,实现高效的多速率处理。
二、数学原理
1. 插值过程
- 数学模型:插值因子 L L L,插值后信号为:
x up [ n ] = { x [ n / L ] , n / L ∈ Z 0 , 其他 x_{\text{up}}[n] = \begin{cases} x[n/L], & n/L \in \mathbb{Z} \\ 0, & \text{其他} \end{cases} xup[n]={x[n/L],0,n/L∈Z其他 - 低通滤波:消除镜像频率分量,传递函数为 H ( z ) H(z) H(z)
2. 抽取过程
- 数学模型:抽取因子 M M M,抽取前需滤波防混叠:
y [ n ] = ∑ k = − ∞ ∞ h [ k ] ⋅ x [ n M − k ] y[n] = \sum_{k=-\infty}^{\infty} h[k] \cdot x[nM -k] y[n]=k=−∞∑∞h[k]⋅x[nM−k]
3. 多相分解(核心)
将滤波器 H ( z ) H(z) H(z)分解为 L L L个(插值)或 M M M个(抽取)子滤波器:
H ( z ) = ∑ r = 0 L − 1 z − r E r ( z L ) H(z) = \sum_{r=0}^{L-1} z^{-r} E_r(z^L) H(z)=r=0∑L−1z−rEr(zL)
其中 E r ( z ) E_r(z) Er(z)为多相分量,对应不同相位延迟的子滤波器。
4、基本操作
-
插值与抽取的基本操作
-
插值(Interpolation):将信号采样率提高 L L L倍,分为两步:
- 插零:在原始信号 x ( n ) x(n) x(n)的相邻采样点间插入 L − 1 L-1 L−1个零值,得到 x ′ ( m ) x'(m) x′(m)。
- 滤波:通过低通滤波器 h int ( k ) h_{\text{int}}(k) hint(k)消除镜像频谱,补偿幅度损失。数学表达式为:
y int ( m ) = L ⋅ ∑ k x ′ ( k ) h int ( m − k ) y_{\text{int}}(m) = L \cdot \sum_{k} x'(k) h_{\text{int}}(m - k) yint(m)=L⋅k∑x′(k)hint(m−k)
其中增益因子 L L L用于恢复插值后信号的幅度。
-
抽取(Decimation):将信号采样率降低 D D D倍,分为两步:
- 抗混叠滤波:通过低通滤波器 h dec ( k ) h_{\text{dec}}(k) hdec(k)限制信号带宽,避免混叠。
- 抽取:保留每 D D D个采样点中的一个,输出 y dec ( n ) = ∑ k x ( k ) h dec ( n D − k ) y_{\text{dec}}(n) = \sum_{k} x(k) h_{\text{dec}}(nD - k) ydec(n)=∑kx(k)hdec(nD−k)。
-
-
多级滤波设计
-
CIC滤波器(级联积分梳状滤波器):常用于高效抽取,传输函数为:
H CIC ( z ) = ( 1 − z − D 1 − z − 1 ) L H_{\text{CIC}}(z) = \left( \frac{1 - z^{-D}}{1 - z^{-1}} \right)^L HCIC(z)=(1−z−11−z−D)L
其中 L L L为级数, D D D为抽取因子。CIC无需乘法运算,适合高速处理,但通带衰减较大,需后接补偿滤波器(如CFIR)。 -
半带滤波器(HB):适用于2倍抽取/插值,通带截止频率为 π / 2 \pi/2 π/2,半数系数为零,计算效率高。
-
-
频域分析
- 插值后信号频谱会压缩为原始带宽的 1 / L 1/L 1/L,并产生 L − 1 L-1 L−1个镜像,需通过低通滤波器(截止频率 π / L \pi/L π/L)抑制镜像。
- 抽取前需将信号带宽限制在 π / D \pi/D π/D内,否则会导致频谱混叠。
二、实现方法
-
插值抽取流程
- 插值实现步骤:
- 插入 L − 1 L-1 L−1个零值;
- 通过低通滤波器平滑信号;
- 乘以增益 L L L恢复幅度。
- 抽取实现步骤:
- 设计抗混叠滤波器;
- 滤波后按因子 D D D降采样。
- 插值实现步骤:
-
多级滤波优化
- CIC + CFIR组合:
- 第一级使用CIC进行粗抽取,降低数据速率;
- 第二级用CFIR补偿CIC的通带衰减。
- 多相滤波结构:
将滤波器分解为 L L L个子滤波器,并行处理插零后的信号,大幅减少计算量。
- CIC + CFIR组合:
-
代码示例(CIC滤波器实现)
def cic_filter(input_signal, D, L):# 积分器部分integral = np.cumsum(input_signal)# 梳状滤波器部分delay = np.zeros_like(integral)delay[D:] = integral[:-D]comb = integral - delay# 级联L次output = comb.copy()for _ in range(L-1):output = np.cumsum(output)delay = np.zeros_like(output)delay[D:] = output[:-D]output = output - delayreturn output[::D] # 抽取
三、多项滤波实现
1. 插值+滤波的高效结构
- 传统方法:上采样后滤波,计算效率低(含大量零乘)
- 多相优化:
- 将滤波器分解为 L L L个多相分支 E 0 ( z ) , E 1 ( z ) , . . . , E L − 1 ( z ) E_0(z), E_1(z), ..., E_{L-1}(z) E0(z),E1(z),...,EL−1(z)
- 输入信号直接进入对应分支,并行计算后交替输出
- 计算量降低为原来的 1 / L 1/L 1/L
2. 抽取+滤波的高效结构
- 传统方法:先滤波后下采样,计算冗余
- 多相优化:
- 分解滤波器为 M M M个分支 E 0 ( z ) , E 1 ( z ) , . . . , E M − 1 ( z ) E_0(z), E_1(z), ..., E_{M-1}(z) E0(z),E1(z),...,EM−1(z)
- 输入信号分块后分别通过分支,再下采样合并
- 计算量降低为原来的 1 / M 1/M 1/M
3. 插值抽取联合实现
当需要同时进行 L L L倍插值和 M M M倍抽取时:
- 级联结构:先插值后抽取,但需满足 gcd ( L , M ) = 1 \gcd(L,M)=1 gcd(L,M)=1避免重复采样
- 多相联合优化:直接设计分数倍采样率转换滤波器,避免冗余计算
四、多项滤波关键公式推导
多相分解表达式
滤波器冲激响应 h [ n ] h[n] h[n]分解为:
h [ n ] = ∑ r = 0 L − 1 e r [ m ] ⋅ δ [ n − r − m L ] h[n] = \sum_{r=0}^{L-1} e_r[m] \cdot \delta[n - r - mL] h[n]=r=0∑L−1er[m]⋅δ[n−r−mL]
其中 e r [ m ] = h [ r + m L ] e_r[m] = h[r + mL] er[m]=h[r+mL],对应第 r r r个多相分支。
插值滤波输出
y [ n ] = ∑ r = 0 L − 1 e r [ m ] ⋅ x [ ⌊ n L ⌋ − m ] y[n] = \sum_{r=0}^{L-1} e_r[m] \cdot x\left[\left\lfloor \frac{n}{L} \right\rfloor - m \right] y[n]=r=0∑L−1er[m]⋅x[⌊Ln⌋−m]
五、多项滤波实现步骤
- 设计原型低通滤波器:满足插值/抽取的频响要求(如截止频率 π / max ( L , M ) \pi/\max(L,M) π/max(L,M))
- 多相分解:按 L L L或 M M M分解为子滤波器
- 并行滤波:输入信号分块送入多相分支
- 合并输出:插值时交替拼接结果,抽取时下采样合并
六、多项滤波应用场景
- 软件无线电(SDR)中的采样率转换
- 音频处理(如44.1kHz↔48kHz转换)
- 图像超分辨率与压缩
七、多项滤波MATLAB示例代码
% 设计插值多相滤波器
L = 4; % 插值因子
h = fir1(60, 1/L); % 原型低通滤波器
poly_phases = reshape(h, L, []); % 多相分解% 输入信号
x = randn(1,100); % 多相插值实现
output = zeros(1, L*length(x));
for i = 1:Loutput(i:L:end) = filter(poly_phases(i,:), 1, x);
end
总结:插值抽取的多项滤波通过多相分解,将计算复杂度从 O ( N ) O(N) O(N)降至 O ( N / L ) O(N/L) O(N/L)或 O ( N / M ) O(N/M) O(N/M),是实时信号处理系统的核心优化技术。附上其学习研究思维导图:
相关文章:
信号处理之插值、抽取与多项滤波
信号处理之插值、抽取与多项滤波 一、问题背景 插值(Interpolation)与抽取(Decimation)是数字信号处理中采样率转换的核心操作: 插值:在信号中插入新样本以提高采样率( L L L倍)抽取:按比例 M M M降低采样率…...
关于WPS的Excel点击单元格打开别的文档的两种方法的探究
问题需求 目录和文件结构如下: E:\Dir_Level1 │ Level1.txt │ └─Dir_Level2│ Level2.txt│ master.xlsx│└─Dir_Level3Level3.txt现在要在master.xlsx点击单元格进而访问Level1.txt、Level2.txt、Level3.txt这些文件。 方法一:“单元格右键…...
蓝桥 2109统计子矩阵
问题描述 给定一个NM 的矩阵 A, 请你统计有多少个子矩阵 (最小 11, 最大 NM) 满足子矩阵中所有数的和不超过给定的整数 K ? 输入格式 第一行包含三个整数 N,M 和 K. 之后 NN 行每行包含 M 个整数, 代表矩阵 A. 输出格式 一个整数代表答案。 样例输入 3 4 10 1 2 3 4 5…...
AF3 make_fixed_size函数解读
AlphaFold3 data_transforms 模块的 make_fixed_size 函数的作用是将输入的蛋白质特征字典 protein 中的各个特征张量调整为固定大小。这是为了确保在批量处理时,所有特征张量的形状一致,从而避免形状不匹配的问题。 源代码: import itertools import torch from src.con…...
前端模块管理新思路:如何使用 Import Maps
前言 前端开发中,我们常常需要使用各种库和模块来构建功能丰富的应用。在传统方式中,管理这些库和模块的引用可能会有些繁琐。 幸运的是,Import Maps 的出现为我们提供了一种更简洁和高效的解决方案。今天我们就来聊聊如何使用 Import Maps。…...
交换机、路由器、网关、MAC地址——从入门到实战
你是否好奇,当你在手机上点击一个网页链接时,数据是如何从你的设备“飞”到千里之外的服务器并返回的?背后离不开交换机、路由器、网关和MAC地址的默契配合。本文用通俗语言实战场景,带你彻底搞懂这些网络核心组件,从此…...
【江协科技STM32】ADC数模转换器-学习笔记
ADC简介 ADC(Analog-Digital Converter)模拟-数字转换器ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁,ADC是一种将连续的模拟信号转换为离散的数字信号的设备或模块12位逐次逼近型…...
LanceDB快速入门之基本操作与API一览
LanceDB可以以多种方式运行 可以嵌入到现有后端(如您的 Django、Flask、Node.js 或 FastAPI 应用程序)中直接从如 Jupyter 笔记本等客户端应用程序中用于分析工作负载部署为远程无服务器数据库 安装 Python: pip install lancedbTypeScrip…...
Spring Boot 整合 Redis
以下是 Spring Boot 整合 Redis 的指南,涵盖配置、基本操作、高级用法及常见问题解决。 1. 添加依赖 在 pom.xml 中添加 Spring Data Redis 和连接池依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId&…...
七层协议攻防实战:从HTTP慢速攻击到DNS隧道检测
一、七层协议攻击类型与特征 攻击类型协议特征HTTP慢速攻击HTTP低速率发送不完整请求DNS隧道DNS异常长域名、高频率TXT查询API滥用攻击HTTP高频调用关键接口(如短信发送)WebSocket洪水WebSocket海量小消息耗尽服务器资源 二、HTTP协议深度防护 1. 慢速…...
Java CAS(Compare-And-Swap)概念及原理
Java CAS(Compare-And-Swap)概念及原理 1. CAS的基本概念 CAS(Compare-And-Swap)是一种无锁编程的核心技术,用于实现多线程环境下的原子操作。其核心思想是: “先比较,再交换”。具体操作包含…...
内存检测工具——Qt Creator
前言 检测内存错误的工具,有很多个,我今天粗浅的学了一下可在Qt上使用的工具们: Dr.Memory 工具之前我曾在关注的博主上看到相关的博客:C(Qt)软件调试---内存调试器Dr.Memory(21)_dr. memory-CSDN博客 今…...
Ubuntu切换lowlatency内核
文章目录 一. 前言二. 开发环境三. 具体操作 一. 前言 低延迟内核(Lowlatency Kernel) 旨在为需要低延迟响应的应用程序设计的内核版本。Linux-lowlatency特别适合音频处理、实时计算、游戏和其他需要及时响应的实时任务。其主要特点是优化了中断处理、调…...
侯捷 C++ 课程学习笔记:STL标准库与泛型编程
STL 体系结构基础介绍 STL 六大部件: 容器(Containers) 分配器(Allocators) …...
Java 大视界 -- Java 大数据在智能安防视频摘要与检索技术中的应用(128)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
19874并查集
19874并查集 ⭐️难度:中等 🌟考点:并查集、数据结构 📖 📚 import java.util.*;public class Main {static int N 100010;static int[] a new int[N];static int[] p new int[N];static int n;static int m;st…...
ABC 376
目录 D. Cycle D. Cycle(改) E. Max Sum D. Cycle 这道题就是个 01 最短路,直接从 1 开始 bfs 看能不能回到 1 #include<bits/stdc.h> #define int long long using namespace std; const int N 2e5 5, INF 1e18;struct node {int …...
win32汇编环境,对 WM_MOUSEMOVE 消息的理解
;运行效果 ;win32汇编环境,对 WM_MOUSEMOVE 消息的理解 ;理解在 WM_MOUSEMOVE 消息发生时,同时来的wParam和lParam值的含义,并取出各自的值进行运用。从这例子也可以更好的理解windows的消息机制. ;WM_MOUSEMOVE消息就是当鼠标移动时,发送给窗…...
第27周JavaSpringboot电商进阶开发 2.常用功能进阶
电商常用功能进阶 - 课程笔记整理 Excel解析与处理 一、课程内容概述 本小节开始进入电商常用功能进阶部分,主要讲解以下内容: Excel的解析和处理商品图片的处理Valid注解对列表的验证订单数变化趋势图Spring Boot高级功能 二、Excel解析与处理的背…...
网络安全基础知识:从零开始了解网络安全
### 网络安全基础知识:从零开始了解网络安全 欢迎来到《零基础入门到独立参加网络安全比赛》系列教程的第一篇!在这篇文章中,我们将从最基础的概念开始,深入探讨网络安全的定义、重要性、常见的网络攻击类型,以及网络…...
【A2DP】蓝牙A2DP协议剖析:从架构到规范
目录 一、A2DP 协议架构 1.1 A2DP 协议栈结构组成 1.2 协议栈各部分的关系与作用 二、设备配置与角色定义(Configurations and roles ) 2.1 角色定义 2.2 配置示例与角色体现 三、用户需求与场景 3.1 用户需求与场景 3.2 协议限制 3.3 协议要求…...
python力扣15. 三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示例 1&am…...
Linux之系统文件目录理解
1.boot/ 存储启动系统的相关文件的 2.swap/ 虚拟内存 3.dev/ 用于存放设备文件(device files)。这些文件是操作系统与硬件设备之间的接口,允许用户和程序通过文件操作的方式访问硬件资源 字符设备(Character Devices…...
uvm_transaction, uvm_seq_item, uvm_object, uvm_component的关系
uvm_object ├── uvm_component (验证环境中的静态组件) └── uvm_transaction└── uvm_sequence_item (用于sequence-driver交互的事务) 2. 核心类的作用与区别 (1) uvm_object 定位:所有UVM类的基类。 功能: 提供基础的对象操作&…...
Reflect.get和target[key]有何不同?
主要区别在this指向不同,下面输出张三还是李四?: const person{name:张三,get FullName(){return this.name;},};let personProxynew Proxy(person,{get(target,key){return Reflect.get(target,key)//或者return target[key]}});const p1{__proto__:pe…...
K8s 1.27.1 实战系列(十)PV PVC
一、核心概念与关系 1、PV(Persistent Volume) PV 是集群中的持久化存储资源,由管理员预先创建并配置,独立于 Pod 生命周期。它抽象了底层存储(如 NFS、云存储等),定义存储容量、访问模式(如 ReadWriteOnce)、回收策略(Retain/Delete/Recycle)等属性。例如,一…...
JQuery
1.jquery介绍 jQuery是目前使用最广泛的javascript函数库。据统计,全世界排名前100万的网站,有46%使用jQuery,远远超过其他库。微软公司甚至把jQuery作为他们的官方库。 jQuery的版本分为1.x系列和2.x、3.x系列,1.x系列兼容低版…...
「AI 加持的高效架构」高并发场景下的服务器成本优化
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...
html css 笔记
01_浏览器相关知识 五大主流浏览器: Chrome Safari IE Firefox Opera (拥有自己的内核) 四大内核: webkit Trident Gecko blink. 02_网页相关知识 构成 网址 网站 网页 网页标准: 结构 表现 行为 分别对应 HTML CSS JavaScript 03_HTML简介 H…...
通义万相 2.1:AIGC 领域的 “王炸” 组合如何颠覆创作生态?
引言 在数字化和人工智能的飞速发展中,AIGC(AI生成内容)技术已经成为推动创作、设计和内容生成领域创新的核心力量。而当通义万相2.1与蓝耘智算平台强强联手,这一“王炸”组合不仅提升了AIGC的效率,还为创作生态带来了…...
Math.NET Numerics 库怎么装
你提到的缺少的库是 Math.NET Numerics。 关于 Math.NET Numerics Math.NET Numerics 是一个用于 .NET 平台的开源数学库,提供了以下功能: 线性代数(矩阵运算、求解线性方程组等)。数值计算(积分、微分、优化等&…...
NPM安装与配置全流程详解(2025最新版)
写目录 一、环境准备与Node.js安装1. 下载Node.js(含NPM)2. 验证安装 二、NPM核心配置优化1. 全局模块与缓存路径设置2. 镜像加速3. 代理配置(企业网络适用) 三、NPM基础操作指南1. 项目初始化2. 包管理命令3. 依赖锁定与版本管理…...
python-52-基于Langchain和Faiss实现向量存储和检索的技术原理
文章目录 1 文本加载与预处理1.1 计算文本的MD5哈希值1.2 加载文本并计算哈希2 初始化向量存储2.1 基于Ollama的嵌入模型2.2 获取code和id的对应关系2.3 清空索引向量2.4 基于HuggingFaceEmbeddings的嵌入模型2.4.1 将模型下载到本地2.4.2 使用方式3 添加新文本3.1 处理新文本并…...
游戏引擎学习第140天
回顾并为今天的内容做准备 目前代码的进展到了声音混音的部分。昨天我详细解释了声音的处理方式,声音在技术上是一个非常特别的存在,但在游戏中进行声音混音的需求其实相对简单明了,所以今天的任务应该不会太具挑战性。 今天我们会编写一个…...
Jetpack Navigation 实战:Fragment 和 Activity 的交互与导航
在 Android 开发中,使用 Jetpack Navigation 组件可以方便地管理 Fragment 和 Activity 之间的导航。以下是如何使用 Jetpack Navigation 实现 Fragment 之间、Activity 之间以及 Activity 与 Fragment 之间跳转的实战示例。 1. 添加依赖 首先,在 build.…...
Linux中的基本指令(上)
目录 ls指令 判断linux中文件 pwd指令 认识路径 编辑 绝对路径/相对路径 cd指令 简要理解用户 理解家目录 echo指令和printf指令 touch指令 mkdir指令 cat指令 tree指令 rmdir指令和rm指令 man指令 cp指令 which指令 alias 指令 date指令 cal指令 理解…...
多用户网页在线聊天室(测试报告)
文章目录 多用户网页在线聊天室一,项目概括1.1 项目名称1.2 测试时间1.3 项目背景1.3 编写目的 二,测试计划2.1 测试环境与配置2.2 测试用例2.3实际执行用例2.3.1登录2.3.2聊天消息列表展示2.3.3聊天消息详情页展示2.3.4联系人页展示2.3.5信息的编辑与发…...
字节青训营后端方向的个人总结(2025年3月4日)
字节青训营的结营总结(25寒假) ——致青训营队友的一封信 明天就是大项目结项的日子了,不知道大家在这方面学习、精进了多少,也许有的朋友收获颇多并且已经完成了项目,我个人对此表示由衷的恭喜和祝贺。 当初自告奋…...
VX iOS分析随记
断SVC的时候看调用栈,发现里面一个特别大的ollvm函数。vx版本8054 * thread #36, queue com.apple.root.default-qos, stop reason breakpoint 4.1 frame #0: 0x0000000111ad6124 WeChat___lldb_unnamed_symbol1315083 20 WeChat___lldb_unnamed_symbol13150…...
docker 小记
一、卸载 查看当前版本 docker -v2. 如果有,先停止docker systemctl stop docker如果是yum安装,卸载方式为 #已防版本冲突,直接卸载 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-lat…...
AI代码编程辅助工具
现在AI火的一塌糊涂,作为技术应该更应该关注当前AI对编程行业的影响。 分享下当前网络上最火的网络编程辅助工具。 以下是个人搜集到的可以对编程起辅助作用的工具: 2025年最佳AI编程辅助工具 1. GitHub Copilot 这个工具也许你已经在使用了࿰…...
使用 kubectl cp 命令可以在 Kubernetes Pod 和本地主机之间拷贝文件或文件夹
使用 kubectl cp 命令可以在 Kubernetes Pod 和本地主机之间拷贝文件或文件夹 kubectl cp <namespace>/<pod-name>:<pod-path> <local-path> # 从 Pod 拷贝到本地 kubectl cp <local-path> <namespace>/<pod-name>:<pod-path&g…...
【eNSP实战】交换机配置端口隔离
交换机端口隔离可以实现在同一个VLAN内对端口进行逻辑隔离,端口隔离分为L2层隔离和L3层隔离,这里只进行L2层隔离演示。 拓扑图 路由器AR1配置GE 0/0/1配置IP,其余PC主机各自配置IP和网关。 现将PC1到PC4四个主机全部进行L2层隔离,…...
动态规划-第2篇
前言:在上一篇文章中,我们了解了动态规划的基本概念和解决问题的基本思路。通过分解问题、存储子问题的解,动态规划为我们提供了高效的解决方案。然而,动态规划并不是一成不变的,它有很多不同的技巧和变种,…...
数据库查问题常用OS命令汇总
1、内存使用情况查看 top //查看活跃进程占用情况 free -mh //查看操作系统当前可用内存 2、cpu使用情况 lscpu //查看os cpu情况 sar -u -f sar文件名 -s hh:mm:ss -e hh:mm:ss //查看对应日期的历史cpu情况 top //查看当前活跃进程使用cpu情况 3、io情况 iostat …...
基于springboot住院管理系统(源码+lw+部署文档+讲解),源码可白嫖!
摘要 随着世界经济信息化、全球化的到来和电子商务的飞速发展,推动了很多行业的改革。若想达到安全,快捷的目的,就需要拥有信息化的组织和管理模式,建立一套合理、畅通、高效的线上管理系统。当前的住院管理存在管理效率低下&…...
《用Python+PyGame开发双人生存游戏!源码解析+完整开发思路分享》
导语 "你是否想过用Python开发一款可玩性高的双人合作游戏?本文将分享如何从零开始实现一款类《吸血鬼幸存者》的生存射击游戏!包含完整源码解析、角色系统设计、敌人AI逻辑等核心技术点,文末提供完整代码包下载!" 哈…...
【ES6】在ES6中自定义数组
在ES6中是允许自定义类扩展基础类型的,因为这些基础类型是有构造函数的,在JS中类就是函数。 // 自定义数组 class myArray extends Array {constructor() {super();} }let arr new myArray();arr.push(1);console.log(arr);重写Array的原生方法 ES6的…...
软件开发项目有哪些风险
软件开发项目风险主要包括 需求不明确、技术实现难度大、进度延误、成本超支、质量问题。其中,需求不明确可能导致功能设计反复修改;技术实现难度大会使开发过程中不断遇到未知挑战;进度延误常常因资源配置不足或变更频繁而发生;成…...
47.HarmonyOS NEXT 登录模块开发教程(二):一键登录页面实现
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! HarmonyOS NEXT 登录模块开发教程(二):一键登录页面实现 文章目录 HarmonyOS NEXT 登录模块开发教程࿰…...