Unity类银河恶魔城学习记录9-4 p92 Death of entity源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
此代码仅为较上一P有所改变的代码

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

PlayerStat
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PlayerStat : CharacterStats
{private Player player;protected override void Start(){player = GetComponent<Player>();base.Start();}public override void DoDamage(CharacterStats _targetStats){base.DoDamage(_targetStats);}protected override void TakeDamage(int _damage){base.TakeDamage(_damage);player.DamageEffect();}protected override void Die(){base.Die();player.Die();}
}

EnemyStat
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EnemyStat : CharacterStats
{private Enemy enemy;public override void DoDamage(CharacterStats _targetStats){base.DoDamage(_targetStats);}protected override void Die(){base.Die();enemy.Die();}protected override void Start(){enemy = GetComponent<Enemy>();base.Start();}protected override void TakeDamage(int _damage){base.TakeDamage(_damage);enemy.DamageEffect();}
}
Entity.cs
 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Entity : MonoBehaviour
{[Header("Knockback info")][SerializeField] protected Vector2 knockbackDirection;//被击打后的速度信息[SerializeField] protected float knockbackDuration;//被击打的时间protected bool isKnocked;//此值通过卡住SetVelocity函数的方式用来阻止当一个角色被攻击时,会乱动的情况[Header("Collision Info")]public Transform attackCheck;//transform类,代表的时物体的位置,用来控制攻击检测的位置public float attackCheckRadius;//检测半径[SerializeField] protected Transform groundCheck;//transform类,代表的时物体的位置,后面会来定位子组件的位置    [SerializeField] protected float groundCheckDistance;[SerializeField] protected Transform wallCheck;//transform类,代表的时物体的位置,后面会来定位子组件的位置    [SerializeField] protected float wallCheckDistance;[SerializeField] protected LayerMask whatIsGround;//LayerMask类,与Raycast配合,https://docs.unity3d.com/cn/current/ScriptReference/Physics.Raycast.html#region 定义Unity组件public SpriteRenderer sr { get; private set; }public Animator anim { get; private set; }//这样才能配合着拿到自己身上的animator的控制权public Rigidbody2D rb { get; private set; }//配合拿到身上的Rigidbody2D组件控制权public EntityFX fx { get; private set; }//拿到EntityFXpublic CharacterStats stats { get; private set; }public CapsuleCollider2D cd { get; private set; }#endregionpublic int facingDir { get; private set; } = 1;protected bool facingRight = true;//判断是否朝右protected virtual void Awake(){}protected virtual void Start(){anim = GetComponentInChildren<Animator>();//拿到自己子组件身上的animator的控制权sr = GetComponentInChildren<SpriteRenderer>();fx = GetComponent<EntityFX>();拿到的组件上的EntityFX控制权rb = GetComponent<Rigidbody2D>();stats = GetComponent<CharacterStats>();cd = GetComponent<CapsuleCollider2D>();}protected virtual void Update(){}protected virtual void Exit(){}public virtual void DamageEffect(){fx.StartCoroutine("FlashFX");//IEnumertor本质就是将一个函数分块执行,只有满足某些条件才能执行下一段代码,此函数有StartCoroutine调用//https://www.zhihu.com/tardis/bd/art/504607545?source_id=1001StartCoroutine("HitKnockback");//调用被击打后产生后退效果的函数Debug.Log(gameObject.name+"was damaged");}protected virtual IEnumerator HitKnockback(){isKnocked = true;//此值通过卡住SetVelocity函数的方式用来阻止当一个角色被攻击时,会乱动的情况rb.velocity = new Vector2(knockbackDirection.x * -facingDir, knockbackDirection.y);yield return new WaitForSeconds(knockbackDuration);isKnocked = false;}//被击打后产生后退效果的函数#region 速度函数Velocitypublic virtual void SetZeroVelocity(){if(isKnocked){return;}rb.velocity = new Vector2(0, 0);}//设置速度为0函数public virtual void SetVelocity(float _xVelocity, float _yVelocity){if(isKnocked)return;此值通过卡住SetVelocity函数的方式用来阻止当一个角色被攻击时,会乱动的情况rb.velocity = new Vector2(_xVelocity, _yVelocity);//将rb的velocity属性设置为对应的想要的二维向量。因为2D游戏的速度就是二维向量FlipController(_xVelocity);//在其他设置速度的时候调用翻转控制器}//控制速度的函数,此函数在其他State中可能会使用,但仅能通过player.SeVelocity调用#endregion#region 翻转函数Flippublic virtual void Flip(){facingDir = facingDir * -1;facingRight = !facingRight;transform.Rotate(0, 180, 0);//旋转函数,transform不需要额外定义,因为他是自带的}//翻转函数public virtual void FlipController(float _x)//目前设置x,目的时能在空中时也能转身{if (_x > 0 && !facingRight)//当速度大于0且没有朝右时,翻转{Flip();}else if (_x < 0 && facingRight){Flip();}}#endregion#region 碰撞函数Collisionpublic virtual bool IsGroundDetected(){return Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsGround);}//通过RayCast检测是否挨着地面,https://docs.unity3d.com/cn/current/ScriptReference/Physics2D.Raycast.html//xxxxxxxx()   => xxxxxxxx  == xxxxxxxxxx() return xxxxxxxxx;public virtual bool IsWallDetected(){return Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, wallCheckDistance, whatIsGround);}//通过RayCast检测是否挨着地面,https://docs.unity3d.com/cn/current/ScriptReference/Physics2D.Raycast.html//xxxxxxxx()   => xxxxxxxx  == xxxxxxxxxx() return xxxxxxxxx;protected virtual void OnDrawGizmos(){Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));//绘制一条从 from(前面的) 开始到 to(后面的) 的线。Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance, wallCheck.position.y));//绘制一条从 from(前面的) 开始到 to(后面的) 的线。Gizmos.DrawWireSphere(attackCheck.position, attackCheckRadius);//https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Gizmos.DrawWireSphere.html//绘制具有中心和半径的线框球体。}//画图函数#endregionpublic void MakeTransprent(bool isClear){if (isClear)sr.color = Color.clear;elsesr.color = Color.white;}public virtual void Die(){}
}
Player.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;public class Player : Entity
{[Header("Attack Details")]public Vector2[] attackMovement;//每个攻击时获得的速度组public float counterAttackDuration = .2f;public bool isBusy{ get; private set; }//防止在攻击间隔中进入move//[Header("Move Info")]public float moveSpeed;//定义速度,与xInput相乘控制速度的大小public float jumpForce;public float swordReturnImpact;//在player里设置swordReturnImpact作为击退的参数[Header("Dash Info")][SerializeField] private float dashCooldown;private float dashUsageTimer;//为dash设置冷却时间,在一定时间内不能连续使用public float dashSpeed;//冲刺速度public float dashDuration;//持续时间public float dashDir { get; private set; }#region 定义Statespublic PlayerStateMachine stateMachine { get; private set; }public PlayerIdleState idleState { get; private set; }public PlayerMoveState moveState { get; private set; }public PlayerJumpState jumpState { get; private set; }public PlayerAirState airState { get; private set; }public PlayerDashState dashState { get; private set; }public PlayerWallSlideState wallSlide { get; private set; }public PlayerWallJumpState wallJump { get; private set; }public PlayerDeadState deadState { get; private set; }public PlayerPrimaryAttackState primaryAttack { get; private set; }public PlayerCounterAttackState counterAttack { get; private set; }public PlayerAimSwordState aimSword { get; private set; }public PlayerCatchSwordState catchSword { get; private set; }public PlayerBlackholeState blackhole { get; private set; }public SkillManager skill { get; private set; }public GameObject sword{ get; private set; }//声明sword#endregionprotected override void Awake(){base.Awake();stateMachine = new PlayerStateMachine();//通过构造函数,在构造时传递信息idleState = new PlayerIdleState(this, stateMachine, "Idle");moveState = new PlayerMoveState(this, stateMachine, "Move");jumpState = new PlayerJumpState(this, stateMachine, "Jump");airState = new PlayerAirState(this, stateMachine, "Jump");dashState = new PlayerDashState(this, stateMachine, "Dash");wallSlide = new PlayerWallSlideState(this, stateMachine, "WallSlide");wallJump = new PlayerWallJumpState(this, stateMachine, "Jump");//wallJump也是Jump动画deadState = new PlayerDeadState(this, stateMachine, "Die");primaryAttack = new PlayerPrimaryAttackState(this, stateMachine, "Attack");counterAttack = new PlayerCounterAttackState(this, stateMachine, "CounterAttack");aimSword = new PlayerAimSwordState(this,stateMachine, "AimSword");catchSword = new PlayerCatchSwordState(this, stateMachine, "CatchSword");blackhole = new PlayerBlackholeState(this, stateMachine, "Jump");//this 就是 Player这个类本身}//Awake初始化所以State,为所有State传入各自独有的参数,及animBool,以判断是否调用此动画(与animatoin配合完成)protected override void Start(){base.Start();stateMachine.Initialize(idleState);skill = SkillManager.instance;}protected override void Update()//在mano中update会自动刷新但其他没有mano的不会故,需要在这个updata中调用其他脚本中的函数stateMachine.currentState.update以实现 //stateMachine中的update{base.Update();stateMachine.currentState.Update();//反复调用CurrentState的Update函数CheckForDashInput();if(Input.GetKeyDown(KeyCode.F)){skill.crystal.CanUseSkill();}}public void AssignNewSword(GameObject _newSword)//保持创造的sword实例的函数{sword = _newSword;}public void CatchTheSword()//通过player的CatchTheSword进入,及当剑消失的瞬间进入{stateMachine.ChangeState(catchSword);Destroy(sword);}public IEnumerator BusyFor(float _seconds)//https://www.zhihu.com/tardis/bd/art/504607545?source_id=1001{isBusy = true;yield return new WaitForSeconds(_seconds);isBusy = false;}//p39 4.防止在攻击间隔中进入move,通过设置busy值,在使用某些状态时,使其为busy为true,抑制其进入其他state//IEnumertor本质就是将一个函数分块执行,只有满足某些条件才能执行下一段代码,此函数有StartCoroutine调用public void AnimationTrigger() => stateMachine.currentState.AnimationFinishTrigger();//从当前状态拿到AnimationTrigger进行调用的函数public void CheckForDashInput(){if (IsWallDetected()){return;}//修复在wallslide可以dash的BUGif (Input.GetKeyDown(KeyCode.LeftShift) && skill.dash.CanUseSkill())//将DashTimer<0 的判断 改成DashSkill里的判断{dashDir = Input.GetAxisRaw("Horizontal");//设置一个值,可以将dash的方向改为你想要的方向而不是你的朝向if (dashDir == 0){dashDir = facingDir;//只有当玩家没有控制方向时才使用默认朝向}stateMachine.ChangeState(dashState);}}//将Dash切换设置成一个函数,使其在所以情况下都能使用public override void Die(){base.Die();stateMachine.ChangeState(deadState);}
}
PlayerDeadState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PlayerDeadState : PlayerState
{public PlayerDeadState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName){}public override void AnimationFinishTrigger(){base.AnimationFinishTrigger();}public override void Enter(){base.Enter();}public override void Exit(){base.Exit();}public override void Update(){base.Update();player.SetZeroVelocity();}
}

Enemy.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;public class Enemy : Entity
{[SerializeField] protected LayerMask whatIsPlayer;[Header("Stun Info")]public float stunnedDuration;//stunned持续时间public Vector2 stunnedDirection;//stunned改变后的速度protected bool canBeStunned;//判断是否可以被反击[SerializeField] protected GameObject counterImage;//一个代表着是否可以被反击的信号[Header("Move Info")]public float moveSpeed;public float idleTime;public float battleTime;//多久能从battle状态中退出来private float defaultMoveSpeed;[Header("Attack Info")]public float attackDistance;public float attackCooldown;//攻击冷却[HideInInspector] public float lastTimeAttacked;//最后一次攻击的时间#region 类public EnemyStateMachine stateMachine { get; private set; }public string lastingAnimBoolName{ get; private set; }public virtual void AssignLastAnimName(string _animBoolName){lastingAnimBoolName = _animBoolName;}#endregionprotected override void Awake(){base.Awake();stateMachine = new EnemyStateMachine();defaultMoveSpeed = moveSpeed;}protected override void Start(){base.Start();}protected override void Update(){base.Update();stateMachine.currentState.Update();//Debug.Log(IsPlayerDetected().collider.gameObject.name + "I see");//这串代码会报错,可能使版本的物体,因为在没有找到Player的时候物体是空的,NULL,你想让他在控制台上显示就报错了}public virtual void FreezeTime(bool _timeFrozen){if(_timeFrozen){moveSpeed = 0;anim.speed = 0;}else{moveSpeed = defaultMoveSpeed;anim.speed = 1;}}protected virtual IEnumerator FreezeTimeFor(float _seconds){FreezeTime(true);yield return new WaitForSeconds(_seconds);FreezeTime(false);}#region Counter Attack Windowpublic virtual void OpenCounterAttackWindow()//打开可以反击的信号的函数{canBeStunned = true;counterImage.SetActive(true);}public virtual void CloseCounterAttackWindow()//关闭可以反击的信号的函数{canBeStunned = false;counterImage.SetActive(false);}#endregionpublic virtual bool CanBeStunned()//这里的主要目的是完成在被反击过后能立刻关闭提示窗口{if (canBeStunned){CloseCounterAttackWindow();return true;}return false;}public virtual void AnimationFinishTrigger() => stateMachine.currentState.AnimationFinishTrigger();//动画完成时调用的函数,与Player相同public virtual RaycastHit2D IsPlayerDetected() => Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, 7, whatIsPlayer);//用于从射线投射获取信息的结构。//该函数的返回值可以变,可以只返回bool,也可以是碰到的结构protected override void OnDrawGizmos(){base.OnDrawGizmos();Gizmos.color = Color.yellow;//把线改成黄色Gizmos.DrawLine(transform.position, new Vector3(transform.position.x + attackDistance * facingDir, transform.position.y));//用来判别是否进入attackState的线}}

Enemy_Skeleton.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EnemyState
{protected Enemy enemyBase;protected EnemyStateMachine stateMachine;protected Rigidbody2D rb;//小简化protected bool triggerCalled;private string animBoolName;protected float stateTimer;public EnemyState(Enemy _enemyBase, EnemyStateMachine _stateMachine, string _animBoolName){this.enemyBase = _enemyBase;this.stateMachine = _stateMachine;this.animBoolName = _animBoolName;}public virtual void Enter(){triggerCalled = false;enemyBase.anim.SetBool(animBoolName, true);rb = enemyBase.rb;//小简化}public virtual void Update(){stateTimer -= Time.deltaTime;}public virtual void Exit(){enemyBase.anim.SetBool(animBoolName, false);enemyBase.AssignLastAnimName(animBoolName);}//动画完成时调用的函数,与Player相同public virtual void AnimationFinishTrigger(){triggerCalled = true;}
}

EnemyState.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditorInternal;
using UnityEngine;public class Enemy_Skeleton : Enemy
{#region 类Statepublic SkeletonIdleState idleState { get; private set; }public SkeletonMoveState moveState { get; private set; }public SkeletonBattleState battleState { get; private set; }public SkeletonAttackState attackState { get; private set; }public SkeletonStunnedState stunnedState { get; private set; }public SkeletonDeadState deadState { get; private set; }#endregionprotected override void Awake(){base.Awake();idleState = new SkeletonIdleState(this, stateMachine, "Idle", this);moveState = new SkeletonMoveState(this,stateMachine, "Move", this);battleState = new SkeletonBattleState(this, stateMachine, "Move", this);attackState = new SkeletonAttackState(this, stateMachine, "Attack", this);stunnedState = new SkeletonStunnedState(this, stateMachine, "Stunned", this);deadState = new SkeletonDeadState(this, stateMachine, "Idle", this);}protected override void Start(){base.Start();stateMachine.Initialize(idleState);}protected override void Update(){base.Update();}public override bool CanBeStunned(){if (base.CanBeStunned())//在这里重写主要是因为只有在Skeleton里面才能调用stunnedState{stateMachine.ChangeState(stunnedState);return true;}return false;}//重写后不仅能达成在完成被反击后关闭提示窗口,还能转换为stunnedStatepublic override void Die(){base.Die();stateMachine.ChangeState(deadState);}
}
SkeletonDeadState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SkeletonDeadState : EnemyState
{private Enemy_Skeleton enemy;public SkeletonDeadState(Enemy _enemyBase, EnemyStateMachine _stateMachine, string _animBoolName,Enemy_Skeleton _enemy) : base(_enemyBase, _stateMachine, _animBoolName){this.enemy = _enemy;}public override void Enter(){base.Enter();enemy.anim.SetBool(enemy.lastingAnimBoolName, true);enemy.anim.speed = 0;enemy.cd.enabled = false;stateTimer = .1f;}public override void Update(){base.Update();if (stateTimer > 0)rb.velocity = new Vector2(0, 10);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739646.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s 安全机制详解

目录 一、安全机制 三个主要安全机制 认证&#xff08;Authentication&#xff09;&#xff1a; 鉴权&#xff08;Authorization&#xff09;&#xff1a; 准入控制&#xff08;Admission Control&#xff09;&#xff1a; 二、 认证 认证方式 对比总结 认证机制框架和相关组件…

小程序学习 1

pages/goods/search/home.wxml首页功能设定 1. loading入场 2. 下拉刷新 3. 搜索栏 4. 分类切换 5. 商品列表 6. 规格弹层 7. 加载更多 <view style"text-align: center; color: #b9b9b9" wx:if"{{pageLoading}}"><t-loading theme"circula…

Java中的常见类“Math”(一)用法详解

Java 中的 Math 类包含了许多数学函数&#xff0c;可以进行各种数学计算。Math 类是 Java 标准库的一部分&#xff0c;不需要额外引入即可使用。它包含在 java.lang 包中&#xff0c;而 java.lang 包中的类会自动导入到每个 Java 源文件中&#xff0c;所以在编写 Java 程序时无…

uView Swiper 轮播图

该组件一般用于导航轮播&#xff0c;广告展示等场景,可开箱即用&#xff0c;具有如下特点&#xff1a; 自定义指示器模式&#xff0c;可配置指示器样式3D轮播图效果&#xff0c;满足不同的开发需求可配置显示标题&#xff0c;涵盖不同的应用场景具有设置加载状态和嵌入视频的能…

月份的天数

目录 题目描述 输入格式 输出格式 输入输出样例 说明/提示 题目描述 输入年份和月份&#xff0c;输出这一年的这一月有多少天。需要考虑闰年。 输入格式 输入两个正整数&#xff0c;分别表示年份 y 和月数 m&#xff0c;以空格隔开。 输出格式 输出一行一个正整数&…

【单调队列】

滑动窗口 给定一个大小为 n≤10^6 的数组。 有一个大小为 k 的滑动窗口&#xff0c;它从数组的最左边移动到最右边。 你只能在窗口中看到 k 个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子&#xff1a; 该数组为 [1 3 -1 -3 5 3 6 7]&#xff0c;k 为 3。 窗口…

利用ffmpeg对两个音频文件进行混音处理

前言 最近&#xff0c;拿到了一个语音识别程序&#xff0c;想测试一下它识别的准确性。原本程序有一段自己的测试音频&#xff0c;准确性还可以&#xff0c;但是&#xff0c;自己想增加一下测试素材的复杂性。想到了在原本的测试音频中引入干扰数据&#xff08;噪点&#xff…

python中的**可以表示什么??

在Python中&#xff0c;** 有两个主要的用途&#xff1a; 作为幂运算符&#xff1a;a ** b 表示a的b次方。例如&#xff0c;2 ** 3 会返回 8&#xff0c;因为2的3次方等于8。 在函数调用或定义时作为关键字参数的解包&#xff1a; 当你有一个字典&#xff0c;并且你想将这个字…

C++从零开始(day44)——二叉搜索树

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前&#xff0c;我学了一点点C语言还有简单的数据结构&#xff0c;如果有小伙伴想和我一起学习的&#xff0c;可以私信我交流分享学习资料 那么开启正题 今天分享的是关于二叉搜索树的知识点 1.二叉搜索树概念 二叉搜…

python+realsense

单目相机(RGB影像):分辨率&#xff1a;320180,320240,424240,640360,640480,848480,960540,1280720,19201080&#xff1b;帧率&#xff1a;6,15,30,60 按照博文Python实战之Realsense_realsense python-CSDN博客的代码显示如下&#xff08;我更改了分辨率和帧率&#xff0c;大…

java八股文 笔记(持续更新中~)

1 Redis 2Mysql 3JVM 4java基础底层 5 spring 6 微服务 7.......(持续更新) One:Redis篇 1.穿透 2&#xff1a;击穿 3&#xff1a;雪崩 3 33 4:双写一致 5.持久化

【网站项目】012医院住院管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

内网穿透的应用-如何在Linux系统Docker安装JSON Crack并实现远程访问本地数据

文章目录 1. 在Linux上使用Docker安装JSONCrack2. 安装Cpolar内网穿透工具3. 配置JSON Crack界面公网地址4. 远程访问 JSONCrack 界面5. 固定 JSONCrack公网地址 JSON Crack 是一款免费的开源数据可视化应用程序&#xff0c;能够将 JSON、YAML、XML、CSV 等数据格式可视化为交互…

mysql中 多表查询介绍

在 MySQL 中&#xff0c;多表查询是 SQL 语句的重要组成部分&#xff0c;用于从两个或多个表中检索数据。多表查询可以帮助我们更灵活地处理复杂的数据关系&#xff0c;并从中获取所需的信息。以下是 MySQL 中常见的多表查询及其特点、区别和应用场景。 常见多表查询 1. **内连…

《量子计算:下一个大风口,还是一个热炒概念?》

引言 量子计算,作为一项颠覆性的技术,一直以来备受关注。它被认为是未来计算领域的一次革命,可能改变我们对计算能力和数据处理的理解。然而,随着技术的不断进步和商业应用的探索,人们开始思考,量子计算到底是一个即将到来的大风口,还是一个被过度炒作的概念? 量子计…

归并排序 刷题笔记

归并排序的写法 归并排序 分治双指针 1.定义一个mid if(l>r)return ; 2.分治 sort(q,l,mid); sort(q,mid1,r); 3. 双指针 int il,jmid,k0; 将双序列扫入 缓存数组 条件 while(i<mid&&j<r) 两个数列比较大小 小的一方 进入缓存数组 4. 扫尾 while(…

基于USB数据采集器的电能质量监测系统

目录 摘要 1 Abstract 3 第一章 引言 5 1.1 研究背景 5 1.2 研究现状 5 1.3 研究工作 6 第二章 电能质量及其分析方法 8 2.1 电能质量定义 8 2.2 电力系统频率偏差 8 2.3 供电电压允许偏差 10 2.4 公用电网谐波 12 2.5 电压波动和闪变 13 2.6 三相电压不平衡度 15 2.7 常见的电…

[嵌入式AI从0开始到入土]16_ffmpeg_ascend编译安装及性能测试

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注&#xff1a;等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间&#xff0c;后期会考虑出视频教程&#xff0c;务必催更&#xff0c;以防我变身鸽王。 第1期 昇腾Altas 200 DK上手 第2期 下载昇腾案例并运行 第3期 官…

前端精准测试调用链路分析

精准测试在评估需求的测试范围时&#xff0c;需要评估一下代码的影响范围&#xff0c;这个范围有两部分&#xff1a;一是需求直接修改的代码&#xff1b;二是修改代码影响到的功能模块。代码影响到的功能一般是通过调用链路分析来实现的&#xff0c;java和kotlin代码可以由java…