Unity之闪电侠大战蓝毒兽

news2024/11/28 18:58:34

目录

🎨一、创建地形

🎮二、创建角色

🏃2.1 动画

🏃2.2 拖尾 

🏃2.3 角色控制 

​🏃2.4 技能释放

🏃2.5 准星

📱三、创建敌人

🐲3.1 选择模型

🐲3.2 敌人动画器 

🐲3.3 敌人脚本

💤四、杂谈


新年好啊大家,开工大吉,一起摸鱼!经过小编一个月摸鱼的努力,本篇给自己学到的知识做一个汇总和应用,效果如下动图所示:

小编加入了丑陋的蓝毒兽,并让它看起来不那么傻。它会追击、会进攻、还会死(doge.jpg)。

小编给了它十滴血,当我们控制闪电侠攻击它的时候会实时判断血量HP,HP小于等于0就会触发死亡动画。


当然也有很多不足之处,我们控制的角色没有加HP,蓝毒兽攻击角色是没有反应的,死了后还在地上滑动起来了。。。估计是爆炸后呲的它来回撞。有空的话小编还会慢慢完善,废话不多说,下面带大家实现这个实例。


一、创建地形

首先地形是小编自己绘制的,教程可以看下面这篇文章。 

Unity之地形的构建-CSDN博客文章浏览阅读1.1k次,点赞16次,收藏19次。PS:公司没活干,好无聊偷偷摸鱼学Unity,害怕自己学完之后忘记,写下这一篇博客https://blog.csdn.net/qq_48512649/article/details/135267070资源商店也有很多好的地形场景,大家可以用自己喜欢的来做。

二、创建角色

角色模型的创建和动作可以参考下面这篇文章。大家选一个自己喜欢的人物模型来做。。。小编当初做练习选的这个就拿来用了也没换,后悔死了,后面都懒得换了。

Unity之动画和角色控制_unity 角色控制-CSDN博客文章浏览阅读1k次,点赞24次,收藏19次。《绿洲大镖客之重生我是闪电侠》😋_unity 角色控制https://blog.csdn.net/qq_48512649/article/details/135775295

作为一个初学者偶然知道的这个模型素材网站,但是我还没用过(简单瞅了瞅里面有闪电侠的模型doge.jpg)爱给网_音效配乐_3D模型_视频素材_免费下载 


Player的标签设置为Player我们后面要用到:

2.1 动画

这里角色的动画器小编分了两个图层:

  1. Base Layer图层是 静止<——>跑步——>起跳——>空中静止——>落地动作,动作的转换参数小编用的BoolTrigger居多。

  2. 第二个图层用来释放技能的,这里小编设计了两个技能

这里讲一下,权重表示图层的权重,跑跳等动作权重(1)比技能权重(0.9)高,播放动画就会优先播放跑跳的动作。

因为释放技能我们只用手来播放动画,这里的遮罩wave, 释放技能时保证手部动作流畅(新建一个遮罩并保留手部为绿色即可,然后加到图层中)。


2.2 拖尾 

 同样在之前的博客闪电侠的拖尾我们是由拖尾组件TrailRenderer实现的,但是实现效果拖尾只出现在了角色脚下那部分。这和我们所熟悉的闪电侠不一样啊。

 为了把拖尾效果覆盖到全身小编就想到了一个很笨很笨的方法。

新建好多个空对象把它们放到角色身上,再把拖尾组件都挂到这些空对象上,这样拖尾效果就覆盖到全身了。(大佬有好的方案教教我o(╥﹏╥)o) 

来看下效果: 

2.3 角色控制 

接下来轮到脚本了,编写FPSMove脚本控制玩家移动和动画之间的转换:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//给玩家挂载 Character Controller 组件
public class FPSMove : MonoBehaviour
{
    private CharacterController cc;
    //移动速度
    public float moveSpeed;
    //跳跃速度
    public float jumpSpeed;
    //定义获得按键值的两个变量
    private float horizontalMove, verticalMove;
    private Vector3 dir;

    //手动实现重力
    public float gravity;
    private Vector3 velocity;
   
    //创建空对象放到玩家最底部用来检测碰没碰到地面,把空对象挂上来
    //检测点的中心位置
    public Transform groundCheck;  
    //检测点的半径
    public float checkRadius;
    //需要检测的图层
    public LayerMask groundLayer;
    //布尔值存储Physics.CheckSphere的返回值
    public bool isGround;
    
    //定义动画变量
    private Animator animator;
    
    private void Start()
    { 
        //获取角色控制组件
        cc = GetComponent<CharacterController>();
        //获取动画组件
        animator = GetComponent<Animator>();
    }

    private void Update()
    {
        //检测玩家是否在地面上,如果定义的球体和物体发生碰撞返回true
        isGround = Physics.CheckSphere(groundCheck.position, checkRadius, groundLayer);
        if (isGround && velocity.y < 0)
        {
            velocity.y = -2f;
        }

        //获得移动按键的值
        horizontalMove = Input.GetAxis("Horizontal") * moveSpeed;
        verticalMove   = Input.GetAxis("Vertical") * moveSpeed;
        dir = transform.forward * verticalMove + transform.right * horizontalMove;
        //实现移动
        cc.Move(dir * Time.deltaTime);
          
        //每秒减去重力的值不断下降,手动实现重力
        velocity.y -= gravity * Time.deltaTime;
        cc.Move(velocity * Time.deltaTime);
          
        //判断是否按下跳跃键
        if (Input.GetButtonDown("Jump") && isGround) 
        {
            //给玩家一个向上的速度
            velocity.y = jumpSpeed;
            //播放跳跃动画
            animator.SetTrigger("Jump");
        }
        isGroundTest();
        
        //如果向量不等于空就证明我们按了方向键了
        if (dir != Vector3.zero)
        {
            //播放跑步动画
            animator.SetBool("IsRun",true);
        }
        //没有按方向键
        else
        {
            //播放站立动画
            animator.SetBool("IsRun",false);
        }
    }

    private void isGroundTest()
    {
        if (isGround == false)
        {
            //播放落地动画
            animator.SetBool("down",true);
        }
        else if (isGround == true)
        {
            //播放落地动画
            animator.SetBool("down",false);
        }
    }
}

 老样子空对象GroundCheck放在角色脚底用来检测角色碰没碰到地面,把地形的图层设置为Ground

2.4 技能释放

技能的模型和发生碰撞后爆炸的原理大家可以根据下面文章回顾一下,小编技能用的模型也是在这里面挑选的:

Unity之物理系统_unity 物理系统-CSDN博客文章浏览阅读1.2k次,点赞21次,收藏20次。专栏的上一篇角色控制器控制角色移动跳崖,这一篇来说说Unity的物理系统。本篇小编还要带大家做一个碰撞检测效果实例,先放效果图:流星撞击地面产生爆炸效果。_unity 物理系统https://blog.csdn.net/qq_48512649/article/details/135600857

编写Gun脚本来控制技能的生成并挂到角色身上:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gun : MonoBehaviour
{
    //子弹预设体序列化
    [SerializeField]
    private GameObject bulletPrefab;
    
    //游戏对象子弹发射点
    [SerializeField]
    private GameObject bulletPoint;
    
    //子弹速度
    [SerializeField] 
    private float bulletSpeed = 1200;
    
    //定义动画变量
    private Animator animator;
    
    [SerializeField] 
    //获取技能对象
    private GameObject RotatorPS2;

    [SerializeField] 
    private GameObject PS2Point;
    
    // Start is called before the first frame update
    void Start()
    {
        //获取动画组件
        animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        //判断是否按下技能键
        if (Input.GetButtonDown("Fire1"))
        {
            //播放跳跃动画
            animator.SetTrigger("wave");
            PlayerFireEffectTest();
        }

        //判断是否按下技能键
        if (Input.GetButtonDown("Fire2"))
        {
            //播放技能动画
            PlayerFireEffect();
            //播放技能动画
            animator.SetTrigger("pickUp");
        }
    }
    
    //播放技能特效
    public void PlayerFireEffect()
    {
        Debug.Log("shoot!!!!");
        //生成一个子弹实例,每点击射击一次则生成一枚子弹
        GameObject bullet = Instantiate(RotatorPS2, bulletPoint.transform.position, transform.rotation);
        //启动特效
        bullet.SetActive(true);
        //给子弹一个向前的力
        bullet.GetComponent<Rigidbody>().AddForce(transform.forward * bulletSpeed);
        //8秒关闭
        //Invoke("UnEffect", 8f);
        Destroy(bullet,8);
    }

    public void PlayerFireEffectTest()
    {
        //生成一个子弹实例,每点击射击一次则生成一枚子弹
        GameObject bullet = Instantiate(bulletPrefab, PS2Point.transform.position, transform.rotation);
        //启动特效
        bullet.SetActive(true);
        //给子弹一个向前的力
        bullet.GetComponent<Rigidbody>().AddForce(transform.forward * bulletSpeed);
    }

    // 取消播放技能特效
    private void UnEffect()
    {
        RotatorPS2.SetActive(false);
    }
}

其中FirePointPS2Point是一二技能的发射点,把你喜欢的技能特效挂在Gun脚本上,小编这里放了Magic fire2RotatorPS2,别忘了给技能特效加刚体和碰撞组件。

 有了技能还不够,技能发射后碰到物体产生爆炸效果,编写fire脚本挂载到你所选的技能特效预设体上。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Fire : MonoBehaviour
{
    [SerializeField]
    //创建一个爆炸的预设体
    private GameObject Explosion;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    //监听发生碰撞: 只监听发生碰撞的一瞬间
    private void OnCollisionEnter(Collision collision)  //参数 collision 就是你碰撞到的物体的碰撞信息
    {
        //创建一个爆炸物体
        GameObject explosion =Instantiate(Explosion, transform.position, Quaternion.identity);   //参数: 预设体,爆炸位置是自身火焰位置,不旋转
        //销毁自身(流星): 流星撞击地面爆炸物产生流星销毁
        Destroy(gameObject);
        explosion.SetActive(true);
        //获取碰撞到物体看一下参数collision —— 打印一下物体名称,这里打印的是地面的名称
        Debug.Log("撞到了"+collision.gameObject.name);
        
        //实用小技巧
        //给地面一个图层"Ground"   collision.collider.tag == "Ground"   可以判断物体是否踩在地面上
    }
    
    //结束碰撞检测方法
    private void OnCollisionExit(Collision other)
    {
        //collision.collider.tag == "Ground"  判断物体是否离开地面
    }
    
    //监听触发检测
    private void OnTriggerEnter(Collider other)
    {
        
    }
}

比如我这里选的RotatorPS2特效 ,我把fire脚本挂到它身上,ExplosionVariant是爆炸特效。

技能撞倒物体消失产生爆炸效果,爆炸后也会消失,编写 ExplosionTest 脚本挂到爆炸特效上来实现这一功能。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ExplosionTest : MonoBehaviour
{
    float timer = 0;
    // Start is called before the first frame update
    void Start()
    {
        
    }
 
    // Update is called once per frame
    void Update()
    {
        Debug.Log("============这里是explosion");
        //如果时间大于一秒就销毁爆炸物
        timer += Time.deltaTime;
        if (timer > 1)
        {
            Destroy(gameObject);
        }
    }
}

2.5 准星

小编盗用自己的图片来加准星(doge.jpg)

新建一个图像,然后根据下图的数据设置好,还可以选择自己喜欢的颜色,这样准星就设置好了。

 到这里玩家的功能差不多都实现了,下面我们来实现丑陋的蓝毒兽。

三、创建敌人

3.1 选择模型

首先我们去资源商店淘一下敌人的免费模型,毕竟小编很穷o(╥﹏╥)o。搜索monster点击免费资源就会找到下面这个,这个居然是1月26号发布的,当然也有很多其他的优秀资源看个人喜好选择。


在选模型的过程中还闹过笑话,之前选了一个类似大猩猩的模型下半身陷进去了眼睛却还是在原来的位置(这是加了寻路组件之后才这样的),然后在寻路组件的作用下保持这个姿势向我靠近。。。后来也没改过来

 3.2 敌人动画器 

 动画器这里小编编辑的有静止、跑步、攻击、死亡。attack1和attack2小编直接连一块了就,形成一个连击。


至于这里的run和run0,我不知道是模型还是哪出问题了跑步的动画循环播放不了只播放一遍,所以我又又想出了一个很笨很笨的方法让俩跑步动画来回切换达到循环的效果。。。大家不要笑话我。

关于导航网格Nav Mesh Agent组件的使用大家可以回顾这篇文章,使用Nav Mesh Agent组件记得烘焙地形,这里我们用作敌人的寻路功能。

Unity之射线检测和导航系统-CSDN博客文章浏览阅读558次,点赞5次,收藏7次。不知道大家有没有玩过红色警戒 —— 一款即时战略游戏,和罪恶都市一样小编小学的时候就开始玩了,这款游戏控制单位角色移动是通过鼠标的点击来实现。同样的操作方法还有英雄联盟等很多游戏,那本篇文章小编就通过简单小实例来讲解这种操作在Unity中是如何实现的。小编先展示一下实例的演示动图:红色球体表示我们控制的角色,鼠标左键点击小球就会到相应的坐标位置并打印坐标。https://blog.csdn.net/qq_48512649/article/details/135674470这是蓝毒兽挂载的组件大家参考一下:

3.3 敌人脚本

好了接下来我们让丑陋的蓝毒兽变得聪明一点,创建脚本AI挂载到蓝毒兽上:


这里用枚举的方式来描述蓝毒兽的状态。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

//状态
public enum EnemyState
{
    idle,   //静止状态
    run,    //逃跑状态
    attack, //攻击状态
    die     //死亡状态
}

public class AI : MonoBehaviour
{
    //状态
    public EnemyState CurrentState = EnemyState.idle;
    //动画控制器
    private Animator animator;
    //玩家
    private Transform player;
    //导航
    private NavMeshAgent agent;
    //怪兽血量
    private int hp = 10;
    // Start is called before the first frame update
    void Start()
    {
        //获取动画组件
        animator = GetComponent<Animator>();
        agent = GetComponent<NavMeshAgent>();
        player = GameObject.FindWithTag("Player").transform;
    }

    // Update is called once per frame
    void Update()
    {
        float distance = Vector3.Distance(player.position, transform.position);
        //判断状态
        switch (CurrentState)
        {
            case EnemyState.idle:
                idle(distance);
                break;
            case EnemyState.run:
                run(distance);
                break;
            case EnemyState.attack:
                attack(distance);
                break;
            case EnemyState.die:
                die();
                break;
        }
    }

    void idle(float distance)
    {
        //站立状态,如果和玩家距离为5到200米变为跑步
        if (distance >= 5 && distance <= 200)
        {
            CurrentState = EnemyState.run;
        }
        //播放站立动画
        animator.SetBool("IsRun", false);        
        //导航停止
        agent.isStopped = true;
    }
    
    void run(float distance)
    {
        //如果离玩家大于200米,则变为站立
        if (distance >= 200)
        {
            CurrentState = EnemyState.idle;
        }else if (distance < 9)
        {
            CurrentState = EnemyState.attack;
        }
        //播放跑步动画
        animator.SetBool("IsRun", true); 
        animator.SetTrigger("Run1");
        animator.SetTrigger("Run2");
        //导航开始
        agent.isStopped = false;
        agent.SetDestination(player.position);
    }

    void attack(float distance)
    {
        //如果离玩家大于10米,则变为站立
        if (distance >= 10)
        {
            CurrentState = EnemyState.run;
        }
        //播放攻击动画
        animator.SetTrigger("Attack");
    }

    void die()
    {
        //播放死亡动画
        animator.SetTrigger("die");
    }
    
    //监听碰撞检测
    private void OnCollisionEnter(Collision collision)
    {
        //判断是否碰到技能
        if (collision.collider.tag == "Skill")
        {
            //血量减少
            hp--;
            //如果血量少于等于0,敌人死亡
            if (hp <= 0)
            {
                Debug.Log("==========HP:" + hp);
                CurrentState = EnemyState.die;
                //Destroy(gameObject);
            }
        }
    }
}

四、杂谈

实例教程到这里就先结束了,八千多字比我毕业论文字数都多(doge.jpg)。继续扩展的话可以像很多游戏一样设置一个出生点,不断有丑陋的蓝毒兽实例被创建;还可以给我们玩家也加上血条,被攻击也会有击退反应;有想法之后可以进行针对性学习。(小编下一步想学游戏联机)

自己写的游戏想怎么来就怎么来,拜拜┏(^0^)┛

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

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

相关文章

GitLab安装配置

一、GitLab的简介 GitLab是开源的代码托管平台&#xff0c;提供版本控制功能、代码审查、持续集成等工具&#xff0c;帮助团队协作开发软件项目。用户可以创建仓库存储代码&#xff0c;管理问题追踪&#xff0c;部署自动化流程等。 二、GitLab的安装 1、Rocky_Linux 下载安装 …

使用RK3588开发板使用 SFTP 互传-windows与开发板互传

MobaXterm 软件网盘下载路径&#xff1a;“iTOP-3588 开发板\02_【iTOP-RK3588 开发板】开发资料\04_iTOP-3588 开发板所需 PC 软件&#xff08;工具&#xff09;\02-MobaXterm”。 打开 MobaXterm 创建一个 SFTP 会话&#xff0c;如下图所示&#xff1a; 输入密码 topeet 进入…

《UE5_C++多人TPS完整教程》学习笔记19 ——《P20 我们子系统的回调函数(Callbacks to Our Subsystem)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P20 我们子系统的回调函数&#xff08;Callbacks to Our Subsystem&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&…

外汇天眼:小白开始实盘之前,必须知道的7件事

在进行外汇交易时&#xff0c;保持松弛的心态和学习外汇知识是一件很重要的事情&#xff0c;但对于缺乏交易经验的交易小白来说&#xff0c;想保持松弛的心态和学习外汇知识比较困难&#xff0c;考虑到这一点&#xff0c;天眼给大家总结了7件在交易前必须知道的事情。 1、实现财…

基于PSO优化的GRU多输入分类(Matlab)粒子群优化门控循环单元神经网络分类预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分程序&#xff1a; 四、完整代码数据分享下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台…

167基于matlab的根据《液体动静压轴承》编写的有回油槽径向静压轴承的程序

基于matlab的根据《液体动静压轴承》编写的有回油槽径向静压轴承的程序&#xff0c;可显示承载能力、压强、刚度及温升等图谱.程序已调通&#xff0c;可直接运行。 167 显示承载能力、压强、刚度及温升 (xiaohongshu.com)https://www.xiaohongshu.com/explore/65d212b200000000…

element 表单提交图片(表单上传图片)

文章目录 使用场景页面效果前端代码 使用场景 vue2 element 表单提交图片   1.点击【上传图片】按钮择本地图片&#xff08;只能选择一张图片&#xff09;后。   2.点击图片&#xff0c;支持放大查看。   3.点击【保存】按钮&#xff0c;提交表单。 页面效果 前端代码…

新版本HC物联网系统

代码开源在 HC物联网平台: HC物联网系统用于小区&#xff0c;园区等设备管理&#xff0c;包括门禁&#xff0c;道闸&#xff0c;监控&#xff0c;充电桩&#xff0c;智能水电表&#xff0c;梯控和门锁等设备 HC 物联网系统 HC物联网系统专注于小区和园区内的设备管理&#xf…

辽宁博学优晨教育:视频剪辑培训新篇章,开启你的创意之旅

在数字化时代&#xff0c;视频剪辑已成为一项炙手可热的技能。辽宁博学优晨教育深知市场需求&#xff0c;特别推出视频剪辑培训专业&#xff0c;为广大爱好者和专业人士提供了一个学习和交流的平台。在这里&#xff0c;我们不仅传授技术&#xff0c;更致力于激发你的创意潜能&a…

Unity ScreenPointToRay 获取到的坐标不准确

&#x1f47e;奇奇怪怪的 &#x1f959;问题描述&#x1f96a;解决方案&#x1f37f;验证代码 &#x1f959;问题描述 使用&#xff1a;Camera.main.ScreenPointToRay 将鼠标坐标转换成射线&#xff0c;然后通过&#xff1a;Physics.Raycast 获取到射线碰撞到的坐标&#xff0…

单反sd卡照片突然没有了?原因+解决方案

在使用单反相机拍摄时&#xff0c;SD卡作为存储媒介&#xff0c;承担着存储照片的重要角色。然而&#xff0c;有时候我们会遇到SD卡中的照片突然消失的情况&#xff0c;给拍摄工作带来很大的困扰。本文将深入剖析导致这一问题的原因&#xff0c;并提供相应的解决方案&#xff0…

SMART信息——你的固态硬盘实时体检报告

SMART&#xff0c;或者严谨地说&#xff1a;S.M.A.R.T (Self-Monitoring Analysis and Reporting Technology)&#xff0c;即“自我监测分析与报告技术”&#xff0c;在硬盘行业耳熟能详。无论是传统的机械硬盘&#xff0c;还是作为后起之秀的固态硬盘&#xff0c;它们都在使用…

C++面试宝典第28题:寻找丢失的数字

题目 给定一个包含n个整数的数组nums,其中nums[i]在区间[1, n]内。请找出所有在[1, n]范围内,但没有出现在nums中的数字,并以数组的形式返回结果。 示例1: 输入:nums = [4, 3, 2, 7, 8, 2, 3, 1] 输出:[5, 6] 示例2: 输入:nums = [1, 1] 输出:[2] 解析 初看这道题,…

【WEB环境】-LNTMP或LAMP结构搭建(记录)

一、手工安装搭建 1.1 LNTMP 【nginx:rpm安装】 安装根目录路径&#xff1a;/usr/local/nginx 启动&#xff1a;/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 停止kill -QUIT 2072 ./nginx -s stop /usr/local/nginx/sbin/nginx -s stop 重启…

FPGA之移位寄存器

SLICEM中的LUT可以配置为32位移位寄存器,而无需使用slice中可用的触发器。以这种方式使用,每个LUT 可以将串 行数据延迟 1 到 32 个时钟周期。移入D &#xff08;DI1 LUT 引脚&#xff09;和移出 Q31&#xff08;MC31 LUT 引脚&#xff09;线路将LUT级联&#xff0c;以形成更大…

物联网水域信息化:水质监测智慧云平台

行业背景 由于传统水务企业水质监测和管理技术不足&#xff0c;以及水源污染等问题&#xff0c;确保供水水质达标困难重重。 且传统水务行业信息化手段单一&#xff0c;缺乏对大数据等新技术的应用&#xff0c;一定程度上影响了水务工作的精细化和智能化程度。 系统特点 为…

Positive SSL 证书介绍

Positive SSL 是一种受欢迎的 SSL 证书&#xff0c;提供了卓越的安全性、性价比和品牌信任。以下是对 Positive SSL 在这些方面的简要介绍&#xff1a; 1. 安全性&#xff1a; Positive SSL 证书采用强大的加密技术&#xff0c;确保网站和用户之间的数据传输是安全的。它使用…

新版Java面试专题视频教程——准备篇、Redis篇

新版Java面试专题视频教程——准备篇、Redis篇 准备篇 准备篇-01-企业简历筛选规则准备篇-02-简历注意事项准备篇-03-应届生该如何找到合适的练手项目 Redis篇 01-redis开篇02-缓存穿透03-缓存击穿04-缓存雪崩05-双写一致性…

Python算法100例-1.8 冒泡排序

完整源代码项目地址&#xff0c;关注博主私信’源代码’后可获取 1.问题描述2.问题分析3.算法设计4.完整的程序5.问题拓展 1&#xff0e;问题描述 对N个整数&#xff08;数据由键盘输入&#xff09;进行升序排列。 2&#xff0e;问题分析 对于N个类型相同的数&#xff0c;…

波特率和(FSK)调制速率的关系

最近在学习基于STM32的FSK解调&#xff0c;刚开始一直对波特率和FSK调制速率两者的概念有些混淆&#xff0c;于是出一篇帖子进行总结。 在百度百科中查到&#xff1a; 调制速率定义 在电子通信领域&#xff0c;调制速率&#xff0c;指的是信号被调制以后在单位时间内的变化&am…