Unity之街机捕鱼

目录

😪炮台系统

🎶炮口方向跟随鼠标

🎶切换炮台

😪战斗系统

🎮概述

🎮单例模式 

🎮开炮

🎮子弹脚本

🎮渔网脚本 

🎮鱼属性信息的脚本

😪奖励和等级的实现 

😪Unity数据持久化

📖保存游戏

📖继续游戏

📖开始新游戏

最近又跟着教程从头到尾完成了一个实例,虽然是好久之前的教程,但是老师讲的很好,我作为Unity初学者也收获很多,复盘后把收获写在这篇博客上,希望看到的你同样会有收获。


来看一下实例效果:切换炮台、捕鱼、加减金币(消耗炮弹的金币)、等级头衔设置、保存、继续游戏;作为一个捕鱼游戏基本功能都很齐全。

Unity中级案例 - 捕鱼达人哔哩哔哩_bilibili 教程分为上、中、下三部分。上主要对游戏UI进行设计和制作;中负责完成游戏主要玩法战斗系统;下对游戏进一步优化包括特效、音效、游戏保存、游戏发布。


UI和特效这里就先不说了,可以跟着教程实操一下。这里想记录核心玩法的实现和编码思路 ,学会思路和实现方式在其他想写的游戏上也能用到。

炮台系统

炮口方向跟随鼠标

所谓炮口方向跟随鼠标就是给炮口一个旋转朝向鼠标的方向。

我们要做的是获取 鼠标到炮台中心的连线 和 炮口所指位置的 夹角,然后将炮台 z轴旋转的数值 设置到和夹角一致就可以实现炮口方向跟随鼠标转动的目的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//让炮口跟随鼠标
public class GunFollow : MonoBehaviour
{public RectTransform UGUICanvas;public Camera mainCamera;void Update(){//定义鼠标的当前位置Vector3 mousePos;//将屏幕坐标转换为世界坐标,结合Input.mousePosition获取鼠标在 当前Canvas(炮台所在的Canvas) 下的位置RectTransformUtility.ScreenPointToWorldPointInRectangle(UGUICanvas,new Vector2(Input.mousePosition.x, Input.mousePosition.y), mainCamera,out mousePos);//定义 z轴 的旋转值float z;//判断鼠标在炮口左边还是右边if (mousePos.x > transform.position.x){//Vector3.up  表示炮口的正方向//mousePos - transform.position  向量相减得到一条线;  与炮口正方向形成夹角//Vector3.Angle()  鼠标和炮台的夹角计算方法  返回值为正数  所以要判断鼠标在炮口左边还是右边z = -Vector3.Angle(Vector3.up, mousePos - transform.position);}else{z = Vector3.Angle(Vector3.up, mousePos - transform.position);}//设置炮口旋转transform.localRotation = Quaternion.Euler(0, 0, z);}
}

给所有炮台都挂载上跟随脚本:

切换炮台

炮台在游戏中一共有五种,同样也对应着五种子弹类型(每种子弹类型又有不同颜色与等级相对应),(每一炮所需要的金币数量)类型却有20种。也就是说每一种炮台分别有四挡所消耗的金币数。

来看看脚本是怎么实现的:

public class GameController : MonoBehaviour
{//所有炮台的预设体,用来更换炮台public GameObject[] gunGos;//炮弹生成点父物体public Transform bulletHolder;//五种炮弹预制体,对应五种炮台public GameObject[] bullet1Gos;public GameObject[] bullet2Gos;public GameObject[] bullet3Gos;public GameObject[] bullet4Gos;public GameObject[] bullet5Gos;//每一炮所消耗的金币数档位private int[] oneShootCosts =  { 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };//使用的是第几档消耗金币数档位private int costIndex = 0;  //五种炮台对应20个消耗金币档位,也就是说每种炮台对应四个消耗金币档位void Update(){ChangeBulletCost();}//通过滚轮改变每发炮弹所消耗的钱void ChangeBulletCost(){if (Input.GetAxis("Mouse ScrollWheel") < 0){OnButtonMDown();}if (Input.GetAxis("Mouse ScrollWheel") > 0){OnButtonPDown();}}public void OnButtonPDown(){//costIndex  表示消耗金币档位,炮台和消耗金币档位是1对4的关系,那么 costIndex / 4  代表了我们在用哪个炮台//禁用武器          gunGos[costIndex / 4].SetActive(false);costIndex++;//播放音效AudioManager.Instance.PlayEffectSound(AudioManager.Instance.changeClip);//播放换枪特效Instantiate(changeEffect);//防止数组越界costIndex = (costIndex > oneShootCosts.Length - 1) ? 0 : costIndex;//启用武器gunGos[costIndex / 4].SetActive(true);//更新每发炮弹所消耗的钱oneShootCostText.text = "$" + oneShootCosts[costIndex];}public void OnButtonMDown(){//禁用武器gunGos[costIndex / 4].SetActive(false);costIndex--;AudioManager.Instance.PlayEffectSound(AudioManager.Instance.changeClip);//播放换枪特效Instantiate(changeEffect);//防止数组越界costIndex = (costIndex < 0) ? oneShootCosts.Length - 1 : costIndex;//启用武器gunGos[costIndex / 4].SetActive(true);//更新每发炮弹所消耗的钱oneShootCostText.text = "$" + oneShootCosts[costIndex];}
}

战斗系统

概述


当炮弹射出去之后碰到鱼;炮弹会消失生成渔网;渔网生成后也会在特定的时间消失。

同时渔网在消失前会对鱼进行碰撞检测;撞到渔网的鱼也会对自身生命值进行判断;

鱼死了(┏┛<・)))><<  墓┗┓) ——  播放死亡动画销毁自身并生成金币,对应玩家金币数量增加;鱼没死  ——  接着游,炮台接着开炮。



 单例模式 

我们来看一下实例中单例模式的应用:

public class GameController : MonoBehaviour
{//单例模式private static GameController _instance;public static GameController Instance{get{return _instance;}}//在Awake()生命周期函数中给 _instance 赋值void Awake(){_instance = this;}//定义初始金币和经验值public int exp = 0;public int gold = 500;
}//=================================================================
//当鱼死亡后通过单例模式增加 GameController 脚本中的金币和经验值
//=================================================================//当鱼死亡加金币和经验值GameController.Instance.gold += gold;GameController.Instance.exp += exp;

开炮

每个炮台都有一个空对象用来标记子弹发射点;来看看脚本是怎么实现开炮功能的:

  //开炮void Fire(){//当前炮台用的什么子弹,默认是第五种炮使用的炮弹GameObject[] useBullets = bullet5Gos;int bulletIndex;//当按下发射键并没有碰到其他UI按键(比如加减钱按钮、设置按钮)时才会发射炮弹if (Input.GetMouseButtonDown(0) && EventSystem.current.IsPointerOverGameObject() == false){//判断当前金币够不够开炮if (gold - oneShootCosts[costIndex] >= 0){switch (costIndex / 4){case 0: useBullets = bullet1Gos; break;case 1: useBullets = bullet2Gos; break;case 2: useBullets = bullet3Gos; break;case 3: useBullets = bullet4Gos; break;case 4: useBullets = bullet5Gos; break;}//根据等级分配哪一套子弹里的哪一种颜色bulletIndex = (lv % 10 >= 9) ? 9 : lv % 10;//扣钱gold -= oneShootCosts[costIndex];//播放音效AudioManager.Instance.PlayEffectSound(AudioManager.Instance.fireClip);//播放开火特效Instantiate(fireEffect);//实例化子弹GameObject bullet = Instantiate(useBullets[bulletIndex]);bullet.transform.SetParent(bulletHolder, false);//让子弹的朝向和旋转都和炮口开炮位置一样bullet.transform.position = gunGos[costIndex / 4].transform.Find("FirePos").transform.position;bullet.transform.rotation = gunGos[costIndex / 4].transform.Find("FirePos").transform.rotation;//设置子弹的伤害值bullet.GetComponent<BulletAttr>().damage = oneShootCosts[costIndex];  //把价格的序号传过去//让子弹移动bullet.AddComponent<Ef_AutoMove>().dir = Vector3.up; //改变方向bullet.GetComponent<Ef_AutoMove>().speed = bullet.GetComponent<BulletAttr>().speed ;     //给子弹速度    }else{//TODO Flash The Text;如果金币不足,通过闪烁金币数值提醒玩家StartCoroutine(GoldNotEnough());  //以协程的方式开启}}}//金币不足开炮时进行闪烁提示IEnumerator GoldNotEnough(){goldText.color = goldColor;goldText.color = Color.red;//让程序在这等待0.5秒然后从这接着运行yield return new WaitForSeconds(0.5f);goldText.color = goldColor;}

子弹脚本

public class BulletAttr : MonoBehaviour
{//子弹速度public int speed;//子弹伤害值public int damage;//子弹碰到鱼后生成网的预制体public GameObject webPrefab;private void OnTriggerEnter2D(Collider2D collision){//如果撞到边界(屏幕之外设定了一个UI边界),直接销毁自身if (collision.tag == "Border"){Destroy(gameObject);}//如果撞到鱼,销毁自身并生成网if (collision.tag == "Fish"){//生成网GameObject web = Instantiate(webPrefab);web.transform.SetParent(gameObject.transform.parent, false);//网的位置等于当前子弹的位置web.transform.position = gameObject.transform.position;//将子弹的伤害赋值给网的伤害web.GetComponent<WebAttr>().damage = damage;Destroy(gameObject);}}
}

渔网脚本 

public class WebAttr : MonoBehaviour
{//网消失的时间public float disapperTime;//子弹的伤害public int damage;void Start(){//隔多长时间销毁网自身Destroy(gameObject, disapperTime);}//检测是否碰到鱼private void OnTriggerEnter2D(Collider2D collision){if (collision.tag=="Fish"){//发送消息 给 FishAttr脚本 的 TakeDamage() 方法//通知鱼 我(渔网)打到你了 伤害值为 damagecollision.SendMessage("TakeDamage", damage);}}
}

鱼属性信息的脚本

//记录鱼的属性信息
public class FishAttr : MonoBehaviour
{//每种鱼的这些属性值都不一样,自己来设定public int hp;    //血量public int exp;   //经验值public int gold;  //金币值public int maxNum;    //生成最大数量public int maxSpeed;  //最大速度 //鱼死亡预设体public GameObject diePrefab;//金币预设体public GameObject goldPrefab;private void OnTriggerEnter2D(Collider2D collision){//撞到边界(屏幕之外设定了一个UI边界)就销毁鱼if (collision.tag == "Border"){Destroy(gameObject);}}//鱼受伤void TakeDamage(int value)  //value是从WebAttr脚本传过来的伤害值{hp -= value;//鱼死亡if (hp <= 0){//当鱼死亡加金币和经验值 —— 单例模式的应用GameController.Instance.gold += gold;GameController.Instance.exp += exp;//播放鱼死亡动画GameObject die = Instantiate(diePrefab);die.transform.SetParent(gameObject.transform.parent, false);die.transform.position = transform.position;die.transform.rotation = transform.rotation;//鱼死亡实例化金币GameObject goldGo = Instantiate(goldPrefab);goldGo.transform.SetParent(gameObject.transform.parent, false);goldGo.transform.position = transform.position;goldGo.transform.rotation = transform.rotation;//判断鱼身上有没有播放特效的脚本 Ef_PlayEffectif (gameObject.GetComponent<Ef_PlayEffect>() != null){AudioManager.Instance.PlayEffectSound(AudioManager.Instance.rewardClip);gameObject.GetComponent<Ef_PlayEffect>().PlayEffect();}Destroy(gameObject);}}
}

奖励和等级的实现 

游戏中为避免玩家金币耗光有两种金币奖励功能:小奖励通过每60s倒计时自动给玩家50金币;大奖励240s倒计时结束后变为按钮,玩家点击按钮会获得500金币然后会重新倒计时。

 游戏设定等级称号为:"新手", "入门", "钢铁", "青铜", "白银", "黄金", "白金", "钻石", "大师", "宗师"。根据等级来对应称号

提示玩家升到多少级的UI文本: 

 脚本实现:

public class GameController : MonoBehaviour
{//等级public int lv = 0;//经验public int exp = 0;//初始金币值public int gold = 500;public const int bigCountdown = 240;   //240秒大奖励public const int smallCountdown = 60;  //60秒小奖励public float bigTimer = bigCountdown;  //计时器public float smallTimer = smallCountdown;private string[] lvName = { "新手", "入门", "钢铁", "青铜", "白银", "黄金", "白金", "钻石", "大师", "宗师" };void Update(){//更新等级UpdateUI();}void UpdateUI(){bigTimer -= Time.deltaTime;   //倒计时smallTimer -= Time.deltaTime; //倒计时//如果小计时器小于0,给玩家发金币if (smallTimer <= 0){//计时器重新计时smallTimer = smallCountdown;gold += 50;}//大计时器小于0 并且 当按钮没有显示出来才会执行if (bigTimer <= 0 && bigCountdownButton.gameObject.activeSelf == false){//倒计时结束隐藏计时器bigCountdownText.gameObject.SetActive(false);//显示领取金币按钮bigCountdownButton.gameObject.SetActive(true);}//经验等级换算公式:升级所需经验=1000+200*当前等级while (exp >= 1000 + 20*lv){exp = exp - (1000 + 200 * lv);lv++;//提示玩家升到多少级lvUpTips.SetActive(true);lvUpTips.transform.Find("Text").GetComponent<Text>().text = lv.ToString();//启动协程把提示关闭StartCoroutine(lvUpTips.GetComponent<Ef_HideSelf>().HideSelf(0.6f));//播放音效AudioManager.Instance.PlayEffectSound(AudioManager.Instance.lvUpClip);//播放升级特效Instantiate(lvEffect);}goldText.text = "$" + gold;lvText.text = lv.ToString();//如果玩家等级超过99级,就一直是宗师if ((lv / 10) <= 9){lvNameText.text = lvName[lv / 10];}else{lvNameText.text = lvName[9];}//小计时器                           拿到十位数                       拿到个位smallCountdownText.text = "  " + (int)smallTimer / 10 + "  " + (int)smallTimer % 10;//大计时器bigCountdownText.text = (int)bigTimer + "s";//滑动条显示的是比例 —— 滑动条用来显示等级进度expSlider.value = ((float)exp) / (1000 + 20 * lv);}//大计时器点击领取金币按钮public void OnBigCountdownButtonDown(){gold += 500;AudioManagerFwl.Instance.PlayEffectSound(AudioManagerFwl.Instance.rewardClip);//显示加金币特效Instantiate(goldEffect);//领取完隐藏按钮bigCountdownButton.gameObject.SetActive(false);//显示倒计时bigCountdownText.gameObject.SetActive(true);//给倒计时重新赋值bigTimer = bigCountdown;}
}

Unity数据持久化

Unity的这种数据持久化是通过 键值对 的方式存储在 Windows注册表 

unity PlayerPrefs数据存储位置_playerprefer保存的数据位置-CSDN博客文章浏览阅读1.4k次,点赞4次,收藏8次。1、首先查看自己当前工程的名字:可以在Unity->Edit->Project Settings->Player中设置与查看,如图所示:2、按下键盘Win+R键,输入regedit,打开注册表编辑器,找到相应位置查看如下图:_playerprefer保存的数据位置https://blog.csdn.net/Monkey_Xuan/article/details/115518561unity3d--PlayerPrefs 游戏存档_unity 修改playerprefs.setfloat-CSDN博客文章浏览阅读5.7k次,点赞4次,收藏42次。Unity3D游戏开发之数据持久化PlayerPrefs的使用 转载自 本文作者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/24195977 博主今天研究了在Unity3D中的数据持久化问题。数据持久化在任何一个开发领域都是一个值得关注的问题,小到一个_unity 修改playerprefs.setfloathttps://blog.csdn.net/acmer_sly/article/details/52675954

保存游戏

游戏一共两个场景:一个Start游戏开始界面场景和Main主要玩法场景。在Main中有一个 返回 按钮点击会返回到开始界面场景中,当我们按下这个按钮保存当前游戏的功能就发挥了作用。

我们需要保存的数据有金币数量、当前等级、当前倒计时数值、还有背景音乐的开关。


当我们按下返回按钮后 :

    //返回按钮public void OnBackButtonDown(){//TODO 保存当前游戏  PlayerPrefs只支持 int float string 三种数据类型//保存金币值PlayerPrefs.SetInt("gold", GameController.Instance.gold);//保存等级PlayerPrefs.SetInt("lv", GameController.Instance.lv); //小计时器PlayerPrefs.SetFloat("scd", GameController.Instance.smallTimer);//大计时器PlayerPrefs.SetFloat("bcd", GameController.Instance.bigTimer);//保存经验值PlayerPrefs.SetInt("exp", GameController.Instance.exp);int temp = (AudioManager.Instance.IsMute == false) ? 0 : 1;//保存当前游戏场景的背景音乐是开还是关PlayerPrefs.SetInt("mute", temp);//跳转到开始界面场景UnityEngine.SceneManagement.SceneManager.LoadScene(2);}

继续游戏

当我们点击完返回按钮来到游戏开始界面后,点击 继续游戏 按钮会获取保存好的玩家信息。

public class GameController : MonoBehaviour
{//等级public int lv = 0;//经验public int exp = 0;public int gold = 500;public const int bigCountdown = 240;   //240大奖励public const int smallCountdown = 60;  //60秒小奖励public float bigTimer = bigCountdown;  //计时器public float smallTimer = smallCountdown;//读取游戏void Start(){//通过键值对的形式获取保存好的数值gold = PlayerPrefs.GetInt("gold", gold);lv = PlayerPrefs.GetInt("lv", lv);exp = PlayerPrefs.GetInt("exp", exp);smallTimer = PlayerPrefs.GetFloat("scd", smallCountdown);bigTimer = PlayerPrefs.GetFloat("bcd", bigCountdown);UpdateUI();}
}

 开始新游戏

保存好玩家信息后如果点击 开始游戏 ,通过脚本会删除保存好的玩家信息开始新游戏。

using UnityEngine;
using UnityEngine.SceneManagement;public class StartSceneUI : MonoBehaviour
{//开始游戏按钮清空数据后在加载游戏场景public void NewGame(){//根据键删除保存好的值PlayerPrefs.DeleteKey("gold");PlayerPrefs.DeleteKey("lv");PlayerPrefs.DeleteKey("exp");PlayerPrefs.DeleteKey("scd");PlayerPrefs.DeleteKey("bcd");SceneManager.LoadScene(1);}//继续游戏直接加载游戏场景,在 GameController 脚本获取保存好的玩家信息public void OldGame(){SceneManager.LoadScene(1);}public void OnCloseButton(){//退出游戏Application.Quit();}
}

本篇到这里就结束了,希望我们都能有所收获,拜拜┏(^0^)┛ 

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

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

相关文章

怎样获得CNVD原创漏洞证书

1. 前言 因为工作变动&#xff0c;我最近把这一年多的工作挖漏洞的一些工作成果提交到了CNVD漏洞平台&#xff08;https://www.cnvd.org.cn/&#xff09;&#xff0c;获得了多张CNVD原创漏洞证书。本篇博客讲下怎么获得CNVD原创漏洞证书&#xff0c;以供大家参考。 2. CNVD原创…

Canvas笔记03:Canvas元素功能、属性、获取、原理等一文讲透

hello&#xff0c;我是贝格前端工场&#xff0c;最近在学习canvas&#xff0c;分享一些canvas的一些知识点笔记&#xff0c;本期分享canvas元素的知识&#xff0c;欢迎老铁们一同学习&#xff0c;欢迎关注&#xff0c;如有前端项目可以私信贝格。 Canvas元素是HTML5中的一个重…

基于Intel x86的轨道交通/印度地铁自动售检票(AFC)系统

印度孟买地铁3号线 目前&#xff0c;印度孟买3号线正在全面建设中&#xff0c;这条全长33.5公里的线路将是孟买第一条地下地铁线路&#xff0c;设有27个地下车站和1个地面车站&#xff0c;此条线路的成功通车将连接其他地铁线路、单轨铁路、郊区铁路、城际铁路和孟买机场等&am…

解决prettier 报错 Delete `␍`

根目录&#xff08;么有的话&#xff09;新建 .prettierrc.js配置文件 module.exports {tabWidth: 2,semi: true,printWith: 80,singleQuote: true,quoteProps: consistent,htmlWhitespaceSensitivity: strict,vueIndentScriptAndStyle: true,// 主要是最后一行endOfLine:aut…

Ubuntu环境使用docker构建并运行SpringBoot镜像

今天Ubuntu环境使用docker构建并运行SpringBoot镜像&#xff0c;看文章之前建议先查看安装流程: Linux环境之Ubuntu安装Docker流程 一、镜像打包过程及执行 1、创建一个测试目录 mkdir javaDemo 2、springBoot的包复制到此目录下 cp demo1-0.0.1-SNAPSHOT.jar /data/app/…

计算机网络实验 基于ENSP的协议分析

实验二 基于eNSP的协议分析 一、实验目的&#xff1a; 1&#xff09;熟悉VRP的基本操作命令 2&#xff09;掌握ARP协议的基本工作原理 3&#xff09;掌握IP协议的基本工作原理 4&#xff09;掌握ICMP协议的基本工作原理 二、实验内容&#xff1a; 1、场景1&#xff1a;两台PC机…

React-子传父

1.概念 说明&#xff1a;React中子组件向父组件传递数据通常涉及回调函数和状态提升等方法。 2.代码实现 2.1绑定事件 说明&#xff1a;父组件绑定自定义事件 <Son onGetSonMsg{getMsg}></Son> 2.2接受事件 说明&#xff1a;子组件接受父组件的自定义事件名称…

前端食堂技术周刊第 114 期:Interop 2024、TS 5.4 RC、2 月登陆浏览器的新功能、JSR、AI SDK 3.0

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;凉拌鸡架 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 大家好&#xff0c;我是童欧巴。欢迎来到前端食堂技术周刊&#xff0c;我们先来看下…

机器学习模型总结

多元线性回归&#xff08;linear regression&#xff09; 自变量&#xff1a;连续型数据&#xff0c;因变量&#xff1a;连续型数据 选自&#xff1a;周志华老师《机器学习》P53-55 思想&#xff1a;残差平方和达到最小时的关系式子即为所求&#xff0c;残差平方和&#xff1a…

【学习心得】爬虫JS逆向通解思路

我希望能总结一个涵盖大部分爬虫逆向问题的固定思路&#xff0c;在这个思路框架下可以很高效的进行逆向爬虫开发。目前我仍在总结中&#xff0c;下面的通解思路尚不完善&#xff0c;还望各位读者见谅。 一、第一步&#xff1a;明确反爬手段 反爬手段可以分为几个大类 &#…

20240304-2-计算机网络

计算机网络 知识体系 Questions 1.计算机网络分层的优点和缺点 优点 各层之间是独立的&#xff1b;灵活性好&#xff1b;结构上可分割开&#xff1b;易于实现和维护&#xff1b;能促进标准化工作。 缺点&#xff1a; 降低效率&#xff1b;有些功能会在不同的层次中重复出现&…

微信小程序屏蔽控制台黄色提示信息

我们很多时候 一个小程序 啥都没有 终端就一直报一些黄色的警告 可以打开项目的 project.config.json 找一下setting 下面有没有 checkSiteMap 字段 如果没有加一个 如果有 直接将值改为 false 这样 再运行 就不会有这个黄色的提示信息了

第1章:绪论 1.1数据库系统概述

文章目录 1.1 数据库系统概述1.1.1 数据库的4个基本概念1.1.2 数据管理技术的产生和发展1.1.3 数据库系统的特点 1.1 数据库系统概述 1.1.1 数据库的4个基本概念 数据(Data) 是数据库中存储的基本对象 数据的定义&#xff1a;描述事物的符号记录 数据的种类&#xff1a;文本、…

Java多态性的作用及解析

多态性是 Java 面向对象编程的一个重要特性,它的主要作用包括以下几个方面: 提高代码的可扩展性:多态性使得我们可以在不修改现有代码的情况下,通过继承和重写方法来添加新的行为。这意味着我们可以在不影响现有功能的前提下,对代码进行扩展和修改。 增强代码的可读性:使…

JVM 基础知识学习笔记

JVM 基础知识学习笔记 1. JVM 介绍 什么是 JVM ? JVM 本质上是一个运行在计算机上的程序&#xff0c;它的职责是运行 Java 字节码文件。 JVM 的功能是什么 ? 解释和运行: 对字节码文件中的指令&#xff0c;实时的解释成机器码&#xff0c;让计算机执行。内存管理: 自动为…

【洛谷 P8682】[蓝桥杯 2019 省 B] 等差数列 题解(数学+排序+差分)

[蓝桥杯 2019 省 B] 等差数列 题目描述 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列&#xff0c;只记得其中 N N N 个整数。 现在给出这 N N N 个整数&#xff0c;小明想知道包含这 N N N 个整数的最短的等差数列有几项&#xff1f; 输…

001 GUI编程简介

一个知识该怎么学&#xff1f; 这是什么该怎么玩能干什么 图形化程序应该包含并不限于如下组件 窗口弹窗面板文本框列表框按钮图片监听事件鼠标键盘事件 GUI介绍 核心技术&#xff1a;Swing与AWT 不流行原因&#xff1a;界面不美观、需要JRE环境 仍然学习的原因&#xf…

【Web】速谈FastJson反序列化中JdbcRowSetImpl的利用

目录 简要原理分析 exp 前文&#xff1a;【Web】速谈FastJson反序列化中TemplatesImpl的利用 简要原理分析 前文的TemplatesImpl链存在严重限制&#xff0c;即JSON.parseObject()需要开启Feature.SupportNonPublicField fastjson的第二条链JdbcRowSetImpl&#xff0c;主要…

【AI视野·今日Robot 机器人论文速览 第八十一期】Mon, 4 Mar 2024

AI视野今日CS.Robotics 机器人学论文速览 Mon, 4 Mar 2024 Totally 25 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Robust Online Epistemic Replanning of Multi-Robot Missions Authors Lauren Bramblett, Branko Miloradovic, Patrick Sherm…

MySQL字符集和比较规则

MySQL字符集和比较规则 字符集和比较规则简介 字符集&#xff1a; 描述字符与二进制数据的映射关系 比较规则&#xff1a;比较指定字符集中的字符的规则 字符集 我们知道&#xff0c;计算机无法直接存储字符串&#xff0c;实际存储的都是二进制数据。字符集是有限的&#xff…