【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)

最终效果

在这里插入图片描述

文章目录

  • 最终效果
  • 前言
  • 素材下载
  • 简单搭建环境
  • 控制小鸟
    • 生成弹簧
  • 限制小鸟的控制范围
  • 弹簧线的显示隐藏
  • 飞行
  • 新增木头
  • 木头销毁
  • 不同血量的木头状态
  • 配置更多物品
  • 爆炸效果
  • 创建敌人的小猪
  • 创建多个小鸟循环
  • 游戏结束
  • 相机跟随
  • 加分特效
  • 不同定义技能的鸟
    • 加速鸟
    • 回旋鸟
    • 爆炸鸟
    • 效果
  • 轨迹预测
  • 一些UI界面的制作
    • 暂停
    • 游戏结束界面
    • 加载界面
    • 菜单界面
    • 关卡选择界面
  • 关卡数据配置
  • 音效
  • 拖尾效果
  • 完结
  • 最终效果视频演示
  • 源码
  • 结束语

前言

欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第29篇中,我们将探索如何用unity复刻经典游戏《愤怒的小鸟》,我会附带项目源码,以便你更好理解它。

素材下载

链接:https://pan.baidu.com/s/1hBbnRkGuf44jsQQBZSn96g?pwd=h73r
提取码:h73r

简单搭建环境

修改图片配置并切图,修改最大尺寸是为了让图片放大不那么模糊
在这里插入图片描述

背景图片和地面草地可能不够长,可以修改绘制模式改成平铺,修改宽度
在这里插入图片描述

控制小鸟

新增Bird,控制小鸟跟随鼠标移动

public enum BirdState
{Waiting,//等待BeforeShoot,//发射前AfterShoot//发射后
}public class Bird : MonoBehaviour
{public BirdState state = BirdState.BeforeShoot;private bool isMouseDown = false; //是否按下void Update(){switch (state){case BirdState.Waiting:break;case BirdState.BeforeShoot:MoveControl();break;case BirdState.AfterShoot:break;default:break;}}//按下触发事件private void OnMouseDown(){if (state == BirdState.BeforeShoot){isMouseDown = true;}}//抬起触发事件private void OnMouseUp(){if (state == BirdState.BeforeShoot){isMouseDown = false;}}//跟随鼠标private void MoveControl(){if (isMouseDown) transform.position = GetMousePosition();}//屏幕坐标转世界坐标private Vector3 GetMousePosition(){Vector3 position = Camera.main.ScreenToWorldPoint(Input.mousePosition);return new Vector2(position.x, position.y);}
}

配置,记得给小鸟加上碰撞体
在这里插入图片描述
效果
在这里插入图片描述

生成弹簧

新增Slingshot代码,控制弹簧得生成

public class Slingshot : MonoBehaviour
{public static Slingshot Instance;public LineRenderer leftLineRenderer;public LineRenderer rightLineRenderer;public Transform leftPoint;public Transform rightPoint;// private Transform centerPoint;private bool isDrawing = false;//是否画线private Transform birdTransform;//鸟private void Awake() {Instance = this;}private void Update(){if (isDrawing){Draw();}}public void StartDraw(Transform birdTransform){isDrawing = true;this.birdTransform = birdTransform;}public void EndDraw(){isDrawing = false;}public void Draw(){leftLineRenderer.SetPosition(0, birdTransform.position);leftLineRenderer.SetPosition(1, leftPoint.position);rightLineRenderer.SetPosition(0, birdTransform.position);rightLineRenderer.SetPosition(1, rightPoint.position);}
}

配置
在这里插入图片描述
效果
在这里插入图片描述
可以看到现在线得终点是在鸟的中位置,我们希望在鸟的后面位置生成
修改代码,按碰撞器的半径进行偏移

public void Draw()
{Vector2 birdPosition = birdTransform.position + birdTransform.GetComponent<CircleCollider2D>().radius *  (birdTransform.position-transform.position).normalized;leftLineRenderer.SetPosition(0, birdPosition);leftLineRenderer.SetPosition(1, leftPoint.position);rightLineRenderer.SetPosition(0, birdPosition);rightLineRenderer.SetPosition(1, rightPoint.position);
}

效果
在这里插入图片描述

限制小鸟的控制范围

修改Bird

public float maxDistance = 1.5f;//限制拉动距离//屏幕坐标转世界坐标
private Vector3 GetMousePosition()
{Vector3 position = Camera.main.ScreenToWorldPoint(Input.mousePosition);position.z = 0;// 获取弹弓的中心位置Vector3 centerPosition = Slingshot.Instance.gameObject.transform.position;//计算鼠标指向的方向Vector3 mouseDir = position - centerPosition;//计算鼠标指向的距离float distance = mouseDir.magnitude;// 如果距离超过最大距离,则限制在最大距离范围内if(distance > maxDistance){position = mouseDir.normalized * maxDistance + centerPosition;}return position;
}

效果
在这里插入图片描述

弹簧线的显示隐藏

修改Slingshot

private void Awake()
{Instance = this;HideLine();
}public void StartDraw(Transform birdTransform)
{isDrawing = true;this.birdTransform = birdTransform;ShowLine();
}public void EndDraw()
{isDrawing = false;HideLine();
}
void HideLine()
{leftLineRenderer.enabled = false;rightLineRenderer.enabled = false;
}void ShowLine()
{leftLineRenderer.enabled = true;rightLineRenderer.enabled = true;
}

效果
在这里插入图片描述

飞行

给鸟添加刚体,默认为静态
在这里插入图片描述
修改Slingshot,配置射击点

public Transform shootPoint;

配置
在这里插入图片描述
修改Bird

public float flySpeed;//飞行速度//抬起触发事件
private void OnMouseUp()
{if (state == BirdState.BeforeShoot){isMouseDown = false;Slingshot.Instance.EndDraw();Fly();}
}void Fly(){rb.bodyType = RigidbodyType2D.Dynamic;//按拉的距离给定飞行速度Vector3 mouseDir = Slingshot.Instance.shootPoint.position - transform.position;rb.velocity = mouseDir.magnitude / maxDistance * flySpeed * mouseDir.normalized;state = BirdState.AfterShoot;
}

配置
在这里插入图片描述
效果
在这里插入图片描述

新增木头

添加刚体和碰撞体
在这里插入图片描述

木头销毁

新增Destructiable,控制木头销毁

public class Destructiable : MonoBehaviour
{public int maxHP = 100;// 最大生命值private int currentHP;// 当前生命值private void Start(){currentHP = maxHP;}private void OnCollisionEnter2D(Collision2D collision){// 获取当前碰撞的相对速度Vector2 relativeVelocity = collision.relativeVelocity;// 计算相对速度的大小(标量值)float impactForce = relativeVelocity.magnitude;// 根据相对速度大小计算伤害值,并减少当前生命值currentHP -= (int)(impactForce * 5);if (currentHP <= 0)Destroy(gameObject);}
}

效果
在这里插入图片描述

不同血量的木头状态

修改Destructiable,控制不同血量显示不同阶段的图片

public List<Sprite> spriteList;//不同阶段的图片
private SpriteRenderer spriteRenderer;spriteRenderer = GetComponent<SpriteRenderer>();private void OnCollisionEnter2D(Collision2D collision)
{// 获取当前碰撞的相对速度Vector2 relativeVelocity = collision.relativeVelocity;// 计算相对速度的大小(标量值)float impactForce = relativeVelocity.magnitude;// 根据相对速度大小计算伤害值,并减少当前生命值currentHP -= (int)(impactForce * 5);if (currentHP <= 0){Destroy(gameObject);}else{//计算剩余生命值的比例float healthRatio = (float)currentHP / maxHP;//计算阶段索引int index = (int)((1 - healthRatio) * spriteList.Count) - 1;if (index != -1) spriteRenderer.sprite = spriteList[index];}}

配置
在这里插入图片描述

效果
在这里插入图片描述

配置更多物品

通过跳转血量,实现易碎的冰块和坚固的砖块
在这里插入图片描述

爆炸效果

在这里插入图片描述
配置
在这里插入图片描述
修改Destructiable,物体销毁时调用

//爆炸特效
GameObject prefabs = Resources.Load("Prefabs/VFX/爆炸烟雾特效") as GameObject;
GameObject go = Instantiate(prefabs, transform.position, Quaternion.identity);
Destroy(go, 1f);

效果
在这里插入图片描述

创建敌人的小猪

新增脚本pig,继承Destructiable

public class Pig : Destructiable {}

配置
在这里插入图片描述
效果
在这里插入图片描述

创建多个小鸟循环

修改Bird,

public enum BirdState
{Waiting,//等待BeforeShoot,//发射前AfterShoot,//发射后WaitToDie//死亡
}void Update()
{switch (state){case BirdState.Waiting:break;case BirdState.BeforeShoot:MoveControl();break;case BirdState.AfterShoot:StopControl();break;case BirdState.WaitToDie:break;default:break;}
}void StopControl(){if(rb.velocity.magnitude < 0.1f){state = BirdState.WaitToDie;Invoke("LoadNextBird", 1f);}
}//加载下一只鸟
protected void LoadNextBird(){Destroy(gameObject);//爆炸特效GameObject prefabs = Resources.Load("Prefabs/VFX/爆炸烟雾特效") as GameObject;GameObject go = Instantiate(prefabs, transform.position, Quaternion.identity);Destroy(go, 1f);GameManager.Instance.LoadNextBird();
}//设置开始小鸟
public void SetStart(Vector3 position){state = BirdState.BeforeShoot;transform.position = position;
}

新增GameManager,

public class GameManager : MonoBehaviour
{public static GameManager Instance { get; private set; }public Bird[] birdList;private int index = -1;private void Awake(){Instance = this;}private void Start(){//在当前场景中查找所有带Bird脚本的对象,不进行排序birdList = FindObjectsByType<Bird>(FindObjectsSortMode.None);LoadNextBird();}public void LoadNextBird(){index++;GameEnd();}public void OnPigDead(){pigTotalCount--;if (pigTotalCount <= 0){GameEnd();}}void GameEnd(){print("游戏结束");}
}

效果
在这里插入图片描述

游戏结束

修改GameManager,实现猪全部死亡或者鸟全部用完结束游戏

private int pigTotalCount;//剩余猪的数量private void Start()
{//在当前场景中查找所有带Bird脚本的对象,不进行排序birdList = FindObjectsByType<Bird>(FindObjectsSortMode.None);pigTotalCount = FindObjectsByType<Pig>(FindObjectsSortMode.None).Length;LoadNextBird();
}public void LoadNextBird()
{index++;if (index >= birdList.Length){GameEnd();}else{birdList[index].SetStart(Slingshot.Instance.shootPoint.transform.position);}
}public void OnPigDead()
{pigTotalCount--;if (pigTotalCount <= 0){GameEnd();}
}void GameEnd()
{print("游戏结束");
}

修改Destructiable

public virtual void Dead(){Destroy(gameObject);//爆炸特效GameObject prefabs = Resources.Load("Prefabs/VFX/爆炸烟雾特效") as GameObject;GameObject go = Instantiate(prefabs, transform.position, Quaternion.identity);Destroy(go, 1f);
}

修改Pig

public class Pig : Destructiable {public override void Dead(){base.Dead();GameManager.Instance.OnPigDead();}
}

效果
在这里插入图片描述

相机跟随

新增FollowTarget,控制相机跟随

public class FollowTarget : MonoBehaviour
{// 要跟随的对象private Transform target;// 跟随的平滑速度public float smoothSpeed = 2f;void Update(){// 确保目标不为空if (target != null){// 获取当前物体的位置Vector3 position = transform.position;// 将目标的 x 轴位置赋值给当前物体的位置position.x = target.position.x;position.x = Mathf.Clamp(position.x, 0, 20);//限制// 使用插值函数 Lerp 平滑移动当前物体到新位置transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * smoothSpeed);}}// 设置目标的方法,可以从外部调用此方法来设置跟随的目标public void SetTarget(Transform newTarget){// 将传入的 Transform 赋值给目标this.target = newTarget;}
}

修改GameManager调用

public void LoadNextBird()
{index++;if (index >= birdList.Length){GameEnd();}else{birdList[index].SetStart(Slingshot.Instance.shootPoint.transform.position);Camera.main.GetComponent<FollowTarget>().SetTarget(birdList[index].transform);//设置摄像机跟随目标}
}

配置
在这里插入图片描述

效果
在这里插入图片描述

加分特效

配置加分动画效果
在这里插入图片描述
新增ScoreManager

public class ScoreManager : MonoBehaviour
{public static ScoreManager Instance { get; private set; }// 预设体public GameObject scorePrefab;// 不同分数对应的精灵数组public Sprite[] score3000;public Sprite[] score5000;public Sprite[] score10000;// 字典,用于根据分数查找对应的精灵数组private Dictionary<int, Sprite[]> scoreDict;private void Awake(){Instance = this;}private void Start(){scoreDict = new Dictionary<int, Sprite[]>{{ 3000, score3000 },{ 5000, score5000 },{ 10000, score10000 }};}// 显示分数的方法public void ShowScore(Vector3 position, int score){// 实例化分数预设体GameObject scoreGo = Instantiate(scorePrefab, position, Quaternion.identity);// 根据分数获取对应的精灵数组Sprite[] scoreArray;if (scoreDict.TryGetValue(score, out scoreArray)){// 随机选择一个精灵int index = Random.Range(0, scoreArray.Length);Sprite sprite = scoreArray[index];// 设置SpriteRenderer的sprite属性scoreGo.GetComponent<SpriteRenderer>().sprite = sprite;}// 在1秒后销毁显示的分数对象Destroy(scoreGo, 1f);}
}

修改Pig调用

public class Pig : Destructiable {public int score = 3000;public override void Dead(){base.Dead();GameManager.Instance.OnPigDead();ScoreManager.Instance.ShowScore(transform.position, score);}
}

效果
在这里插入图片描述

不同定义技能的鸟

修改Bird,定义可重写的不同时段技能方法

bool isFlying;//是否飞行
bool isUserdSkill;//是否已使用技能//抬起触发事件
private void OnMouseUp()
{if (state == BirdState.BeforeShoot){isMouseDown = false;Slingshot.Instance.EndDraw();Fly();isFlying = true;}
}void Update()
{switch (state){case BirdState.Waiting:break;case BirdState.BeforeShoot:MoveControl();break;case BirdState.AfterShoot:StopControl();SkillControl();break;case BirdState.WaitToDie:break;default:break;}
}//使用技能
void SkillControl(){if(isUserdSkill) return;if(Input.GetMouseButtonDown(0)){isUserdSkill = true;if(isFlying == true){FlytingSkill();}FullTimeSkill();}
}//飞行技能
protected virtual void FlytingSkill(){}//全时段技能
protected virtual void FullTimeSkill(){}private void OnCollisionEnter2D(Collision2D other) {if(state == BirdState.AfterShoot){isFlying = false;}
}

加速鸟

//加速鸟
public class SpeedUpBird : Bird {protected override void FlytingSkill(){rb.velocity = rb.velocity * 2;}
}

在这里插入图片描述

回旋鸟

//回旋鸟
public class SlalomBird : Bird {protected override void FlytingSkill(){Vector2 velocity = rb.velocity;velocity.x = -velocity.x;rb.velocity = velocity;Vector3 scale = transform.localScale;scale.x = -scale.x;transform.localScale = scale;}
}

在这里插入图片描述

爆炸鸟

//爆炸鸟
public class BoomBird : Bird {public float boomRadius = 2.5f;//爆炸半径protected override void FullTimeSkill(){Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, boomRadius);foreach (Collider2D collider in colliders){Destructiable des = collider.GetComponent<Destructiable>();if(des != null) des.TakeDamage(Int32.MaxValue);}state = BirdState.WaitToDie;LoadNextBird();}
}

在这里插入图片描述

效果

在这里插入图片描述

轨迹预测

待续

一些UI界面的制作

下面给出一些界面的参考。你也可以按自己喜欢的样子制作

暂停

在这里插入图片描述

游戏结束界面

在这里插入图片描述

加载界面

在这里插入图片描述

菜单界面

在这里插入图片描述

关卡选择界面

在这里插入图片描述

关卡数据配置

在这里插入图片描述

在这里插入图片描述
-1为锁定 0为解锁
在这里插入图片描述

在这里插入图片描述

音效

可以参考这篇文章制作即可:【unity小技巧】Unity音乐和音效管理器

拖尾效果

待续

完结

其中还有一些细节这里就不多说了,自己按照喜欢去配置即可

最终效果视频演示

源码

整理好我会放上来

结束语

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

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

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

相关文章

小学生作文辅导杂志小学生作文辅导杂志社小学生作文辅导编辑部2024年第2期目录

写法导引 创意引航&#xff0c;笔墨生辉——小学语文习作教学中的创新思维训练 杜娟; 3-5 陶行知“小先生制”教育思想在小学作文练习中的应用探索 张淑勤; 6-8 新课程标准视域下小学语文习作教学策略探析 任真真; 9-11 即时作文&#xff1a;开辟小学习作教学的…

Spring Boot集成 Spring Retry 实现容错重试机制并附源码

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

MATLAB神经网络---激活层

非线性变换的目的 非线性变换的目的是为神经网络引入一些非线性特征&#xff0c;使其训练出一些符合各种曲线或各种特征的模型。 换句话来说&#xff0c;如果模型都是直线特征的话&#xff0c;它的泛化能力会不够好。 目录 深度学习层列表 - MATLAB & Simulink - MathWo…

初识MySQL数据库

目录 一、了解数据库 1.数据库的相关概念 2.数据库系统发展史 3.主流数据库产品 二、数据库分类 1.关系数据库 2.非关系型数据库 三、mysql的yum安装与源码编译安装 1.源码编译安装mysql 2.yum安装 mysql5.7 四、MySQL数据类型 1.常用的数据类型 五、查看数据库…

高性能8位单片机 CA51M151,1T 8051内核 / 内置12位ADC / 16 位PWM / 支持触摸 / 8K MTP

CA51M151 系列芯片是基于 1T 8051 内核的 8 位微控制器&#xff0c;不仅保留了传统 8051 芯片的基本特性&#xff0c;通常情况下运行速度比传统的 8051 芯片快 10 倍&#xff0c;性能更加优越。芯片内置 8 KB MTP 程序存储器&#xff0c;256Byte 内部RAM&#xff0c;512Byte 外…

持绪电商:开一家抖音网店大概多久才能做起来

在数字化浪潮的推动下&#xff0c;抖音不仅是年轻人喜爱的短视频平台&#xff0c;更成为电商的新阵地。不少创业者和品牌纷纷入驻&#xff0c;希望能借力抖音的流量红利实现快速成长。但开设一家抖音网店并使其蓬勃发展&#xff0c;并非一朝一夕之事&#xff0c;它需要策略、耐…

植物大战僵尸(杂交版)最新版V2.1来袭!

【新手指导】最新版v2.1来袭 1.闪退怎么办&#xff1f; 答:窗口模式可以解决大部分问题。输入法转换成英文也可以。最后一种办法管理员运行&#xff0c;再后台可运行&#xff0c;即便不是窗口也不会闪退&#xff0c;亲测有效 2.哪里下载&#xff1f; 答&#xff1a;夸克网盘htt…

【网络编程】套接字的多种可选项

可以看出&#xff0c;套接字可选项是分层的。IPPROTOIP层可选项是IP协议相关事项IPPROTO TCP层可选项是TCP协议相关的事项&#xff0c;SOLSOCKET层是套接字相关的通用可选项 getsockopt&&setsockopt #include <sys/socket.h> int getsockopt(int sock, int lev…

【JMeter接口测试工具】第二节.JMeter项目实战(下)【实战篇】

文章目录 前言一、接口弱压力测试二、高并发、高频率三、生成图形化报告总结 前言 一、接口弱压力测试 场景举例&#xff1a; 场景1:模拟半小时之内 1000 个用户访问服务器资源&#xff0c;要求平均响应时间在3000ms内&#xff0c;且错误率为0 实现步骤&#xff1a; 步骤一&am…

VirtualBox、Centos7下安装docker后pull镜像问题

Docker安装篇(CentOS7安装)_docker 安装 centos7-CSDN博客 首先&#xff0c;安装docker可以根据这篇文章进行安装&#xff0c;安装完之后&#xff0c;我们就需要去通过docker拉取相关的服务镜像&#xff0c;然后安装相应的服务容器&#xff0c;比如我们通过docker来安装mysql,…

什么是场外期权?场外期权有几种做法?

今天带你了解什么是场外期权&#xff1f;场外期权有几种做法&#xff1f;期权分为场内期权&#xff0c;场外期权。场内期权我们都知道&#xff0c;是在期货盘里购买的期权&#xff0c;但场外期权呢&#xff1f; 什么是场外期权&#xff1f; 场外期权是一种在交易所之外进行交易…

拿下SOTA!最强中文Embedding模型对标OpenAI,技术路线公开

国产大模型「日日新 5.0」已经在权威主流评测中鲨疯了。变强的背后原因竟是&#xff0c;来自商汤自研中文Embedding模型——Piccolo2。这是首个对标OpenAI向量长度的模型。 国产大模型最近在权威主流评测中「杀」疯了&#xff01; 商汤「日日新 5.0」在中文大模型测评基准Sup…

一键安全体检!亚信安全携手鼎捷软件推出企业安全体检活动 正式上线

亚信安全联合鼎捷软件股份有限公司&#xff08;以下简称“鼎捷软件”&#xff09;正式推出“一键安全体检”服务。亚信安全网络安全专家将携手鼎捷软件数据安全专家&#xff0c;围绕企业的数智安全状况&#xff0c;进行问题探索与治愈、新问题预测与预警&#xff0c;在全面筛查…

公司面试题总结(六)

31.说一说 webpack 的构建流程是什么&#xff1f; ⚫ 初始化流程&#xff1a; ◼ 从配置文件和 Shell 语句中读取与合并参数 ◼ 初始化需要使用的插件和配置插件等执行环境所需要的参数 ⚫ 编译构建流程&#xff1a; ◼ 从 Entry 发出&#xff0c;针对每个 Module 串行…

MySQL数据库初识

目录 一.数据库相关概述 1.数据库概念 数据&#xff08;Data&#xff09; 表 数据库系统 2.数据库系统发展史 当今主流数据库介绍 3.数据库分类 3.1.关系数据库 3.2.非关系型数据库 二.MySQL数据库安装 1.源码编译安装mysql 2.yum安装mysql 一.数据库相关概述 1.…

Clearedge3d EdgeWise 5.8 强大的自动化建模软件

EdgeWise是功能强大的建模软件&#xff0c;提供领先的建模功能和先进的技术&#xff0c;让您的整个过程更快更准确&#xff01;您可以获得使用自动特征提取和对象识别的 3D 建模&#xff0c;ClearEdge3D 自动建模和对象识别软件通过创建竣工文档和施工验证完成该过程。拓普康和…

Ajax的应用

1. Ajax Ajax是Asynchronous Javascript And XML&#xff08;异步JavaScript和XML&#xff09;的缩写。 Ajax技术描述了使用脚本操纵HTTP和Web服务器进行数据交换&#xff0c;在页面不刷新的情况下&#xff0c;实现页面的局部更新。 重点&#xff1a; Ajax 是一种在无需重新加…

气膜结构的使用寿命及其优势—轻空间

气膜结构以其独特的构造方式和显著的优势&#xff0c;在体育馆、展览馆、临时建筑等领域越来越受欢迎。尽管气膜结构的使用寿命与传统钢结构相比可能较短&#xff0c;但其在成本、建造速度、灵活性等方面的优势使其成为许多应用场景中的理想选择。本文将详细探讨气膜结构的使用…

如何基于Excel文件图形化从零建表并导入数据(以MySQL和SQLynx为例)

目录 1. 准备Excel数据 2. 导入Excel数据 a. 登录SQLynx b. 导入Excel文件 3. 验证数据 4. 使用和管理表 5. 总结 在实际的业务过程中&#xff0c;我们经常会有很多数据存储在Excel中&#xff0c;但在Excel中的数据分析不如使用SQL和数据库方便&#xff0c;数据量大些的…

location.href = ‘welcome.html‘;报错 - Completed 406 NOT_ACCEPTABLE

巧妙解决方案&#xff0c;使用服务端进行redirect即可 。 package com.aliyun.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping;Controller public class RedirectController {GetMapping("/r…