用QFramework来重构 祖玛游戏

资料

Unity - 祖玛游戏
GitHub

说明

用QF一个场景就够了,在UIRoot下切换预制体达到面板切换。
但测试中当然要有一个直接跳到测试面板的 测试脚本,保留测试Scene(不然初学者也不知道怎么恢复测试Scene),所以全文按Scene划分
在这里插入图片描述
在这里插入图片描述

----------------------------------------------------

01 Scene 开始进入(面板脚本,主要是 动(功能)静(UI引用)分离)

01 先创建一个UIRoot(QF里面有的)

在这里插入图片描述

02 做好UI,给需要引用的UI加 Bind脚本(默认设置看图)

在这里插入图片描述

03 拖出来做预制体,并且 CreateUICode,会生成两个脚本(自动生成位置是上一级目录的Scripts/UI),一个管UI引用(xxx.Designer),一个管功能(xxx),管功能的会自动加到预制体上

在这里插入图片描述

在这里插入图片描述

xxxPanelData 、xxxPanel(不叫Panel,叫xxxWindow,xxxUI随便)

using UnityEngine;
using UnityEngine.UI;
using QFramework;
using UnityEngine.SceneManagement;

namespace QFramework.Example
{
	public class StartGamePanelData : UIPanelData
	{
	}
	public partial class StartGamePanel : UIPanel
	{
		protected override void OnInit(IUIData uiData = null)
		{
			mData = uiData as StartGamePanelData ?? new StartGamePanelData();
			// please add init code here

			Screen.SetResolution(640, 1136, false);//宽,高,不可修改
			BtnStart.onClick.AddListener(() => {


				Debug.Log("StartGamePanel");
                SceneManager.LoadScene("01 SelectLevel");
            });
		}
		
		protected override void OnOpen(IUIData uiData = null)
		{
		}
		
		protected override void OnShow()
		{
		}
		
		protected override void OnHide()
		{
		}
		
		protected override void OnClose()
		{
		}
	}
}

xxxPanel.Designer

using System;
using UnityEngine;
using UnityEngine.UI;
using QFramework;

namespace QFramework.Example
{
	// Generate Id:29cfe4a1-ad1e-4350-a490-3bdf8cf34278
	public partial class StartGamePanel
	{
		public const string Name = "StartGamePanel";
		
		[SerializeField]
		public UnityEngine.UI.Button BtnStart;
		
		private StartGamePanelData mPrivateData = null;
		
		protected override void ClearUIComponents()
		{
			BtnStart = null;
			
			mData = null;
		}
		
		public StartGamePanelData Data
		{
			get
			{
				return mData;
			}
		}
		
		StartGamePanelData mData
		{
			get
			{
				return mPrivateData ?? (mPrivateData = new StartGamePanelData());
			}
			set
			{
				mUIData = value;
				mPrivateData = value;
			}
		}
	}
}

04 调用,RrsKit.Init();必须调用

/****************************************************
    文件:GameStart.cs
	作者:lenovo
    邮箱: 
    日期:2023/7/2 22:59:41
	功能:
*****************************************************/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;


namespace QFramework.Example
{
    public class GameStart : MonoBehaviour
    {

        #region 生命

        /// <summary>首次载入</summary>
        void Awake()
        {
            ResKit.Init();
            UIKit.OpenPanel<StartGamePanel>();
            GameObject.DontDestroyOnLoad(gameObject);
        }
        

        #endregion 


    }

}




06 写包名,标记(ResKit才有它在打包的列表中),做AB包(QF有个相关示例中不打包运行不了;剪辑了,实际没那么快)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

06 效果

在这里插入图片描述

---------------------------------------------------------------

02 Scene 选择

世界选择

关卡选择

stars Plugins文件夹名

unity中,Plugins文件夹下,会被变成firstpass程序集

--------------------------------------------------------

03 Scene 游戏界面

modify 拆分Enum

对初学者有好点。但实际Unity的内置脚本,有枚举写在类内部的
在这里插入图片描述

GameUI拆成 Pass面板、Fail面板

Pass面板

using UnityEngine;
using UnityEngine.UI;
using QFramework;
using UnityEngine.SceneManagement;

namespace QFramework.Example
{
	public class SuccPanelData : UIPanelData
	{
	}
	public partial class SuccPanel : UIPanel
	{
		protected override void OnInit(IUIData uiData = null)
		{
			mData = uiData as SuccPanelData ?? new SuccPanelData();
			// please add init code here


			BtnNext.onClick.AddListener(() => { 
                GameData.LevelIndex++;
                SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);			
			});
        }
		
		protected override void OnOpen(IUIData uiData = null)
		{
		}
		
		protected override void OnShow()
		{
		}
		
		protected override void OnHide()
		{
		}
		
		protected override void OnClose()
		{
		}
	}
}

Fail面板

using UnityEngine;
using UnityEngine.UI;
using QFramework;
using UnityEngine.SceneManagement;

namespace QFramework.Example
{
	public class GameOverPanelData : UIPanelData
	{
	}
	public partial class GameOverPanel : UIPanel
	{
		protected override void OnInit(IUIData uiData = null)
		{
			mData = uiData as GameOverPanelData ?? new GameOverPanelData();
			// please add init code here

			BtnReset.onClick.AddListener(()=>{
                GameManager.Instance.StartBack();
				CloseSelf();
            });

            BtnReplay.onClick.AddListener(() => {
                SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
            });

			BtnHome.onClick.AddListener(() => {
				UIKit.OpenPanel<StartGamePanel>();
                CloseSelf();
            });
        }
		
		protected override void OnOpen(IUIData uiData = null)
		{
		}
		
		protected override void OnShow()
		{
		}
		
		protected override void OnHide()
		{
		}
		
		protected override void OnClose()
		{
		}
	}
}

watch QF中获取一个资源

new ResLoader()这种过时了
爆炸特效
球的预制体

			//在扫雷案例中测试的,用到WhiteChess
			ResKit.Init();
            ResLoader loader = ResLoader.Allocate();
			GameObject prefab = loader.LoadSync<GameObject>("WhiteChess");
			Instantiate(prefab , transform);

处理GameManager成GamePanel

01 首先将子节点的所有脚本上提到父节点 GamePanel
02 将脚本中引用的节点 进行提取,重命名(和节点名字相同),添加Bind脚本。到脚本最上面,方便看
03 因为用到UI,SpriteRenderer该改成Image

watch Awake的特点

脚本中只用Awake方法,前面就不会有勾选选项
在这里插入图片描述

bug AB资源不存在

明明有,重新打

bug 3D转UGUI

SpriteRenderer转Image后(想要用QF的调用面板的方式),球移动很小。
方法 生成地图文件之前用同样用UIRoot,也就是UGUI,而不是原来的世界坐标。此时小心注意父节点的Scale、预制体小球Ball的RectTranfrom的Scale都调为1,不然球与球之间的距离会有问题(问题就是要么球之间的距离有问题,要么轨道不重合)

modify 转UGUI Image

3000是球沿着曲线移动的平滑度
0.3也相当于球的直径,这个直径就是你要实例的那个球预制体的直径
在这里插入图片描述

方法 生成地图文件之前用同样用UIRoot,也就是UGUI,而不是原来的世界坐标。同时需要乘以倍率(试230合适)

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

public class MapConfig : ScriptableObject
{
    public float EndPoint { get; private set; }

    public List<Vector3> pathPointList = new List<Vector3>();

    public void InitMapConfig()
    {
        EndPoint = pathPointList.Count - 2;
    }

    public Vector3 GetPosition(float progress)
    {
        Camera ui=Camera.main.gameObject.FindComponentWithTag<Camera>("UI");
        int index = Mathf.FloorToInt(progress);
         //return Vector3.Lerp(pathPointList[index], pathPointList[index + 1], progress - index);

        Vector3 v1 = Vector3.Lerp(pathPointList[index], pathPointList[index + 1], progress - index);

        return v1*230f;
    }

}

效果 轨道球

在这里插入图片描述

-------------------------------------

modify 发射球的发射位置、速度和终点超界判定

发射球的位置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

速度

在这里插入图片描述

超界的判定

就是把Canvas上的 球 ,拖到Canvas的边界,看坐标
在这里插入图片描述

效果

在这里插入图片描述

-------------------------------------------

bug 销毁特效的大小和位置

using QFramework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ResLoader = QFramework.ResLoader;

public class FXManager :MonoSingleton<FXManager>
{
       Transform FXs;
   //
    GameObject destroyFXPrefab;
    ObjectPool<GameObject> destroyFXPool;
 

                                                                
    public void Init(Transform FXs)
    {
        this.FXs = FXs;
        //
        ResKit.Init();
        QFramework.ResLoader loader =  QFramework.ResLoader.Allocate();
        destroyFXPrefab = loader.LoadSync<GameObject>("DestroyFX"); 
        destroyFXPool = new ObjectPool<GameObject>(InstantiateFX, 10);
    }


    private GameObject InstantiateFX()
    {
        GameObject go = Instantiate(destroyFXPrefab, FXs);
        go.Hide();
        return go;
    }


    public void ShowDestroyFX(Vector3 pos)
    {
        GameObject go = destroyFXPool.GetObject();
        go.Show();
        go.transform.localPosition = pos;

        //延时0.5f执行回收操作
        ScheduleOnce.Start(this, () =>
         {
             go.Hide();
             destroyFXPool.AddObject(go);
         }, 0.5f);
    }
}

bug 发射器旋转一次就固定朝向左下方

后面又自动好了,可能改掉了循环调用打开GamePanel,导致存在多个GamePanel?
在这里插入图片描述

bug 自动刷新

点了几下没反应,因为原来没加自动刷新
在这里插入图片描述

bug 三个mapConfig不能放Resources,生成时空白

不放Resources,又会
GameManager.Instance.mapConfig运行后为空。这是因为
public class GameSceneConfig : MonoSingleton中的mapconfigArr有的为空

bug 抬起发射时不灵敏

关掉这个
在这里插入图片描述

watch 消球后不回退

小球后回退需要
小球后还能存在继续消球的情况在

bug 复活后回退太狠

modify SoundManager

看了示例,不需要类似于UIkit的ResKit.Init()的初始化
AudioKit.PlaySound(“resources://Sound/”+clipName );
AudioKit.PlayMusic(“resources://Sound/”+name,volume:volume);

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

public class SoundManager : MonoSingleton<SoundManager>
{
    static AudioSource bgAudio;


    public void Init()
    {
        bgAudio = gameObject.GetOrAddComponent<AudioSource>();
    }


    private static void PlaySound(string clipName)
    {
      //  AudioSource.PlayClipAtPoint(GetAudioClip(clipName), Vector3.zero);
        AudioKit.PlaySound("resources://Sound/"+clipName );
    }


    public static AudioClip GetAudioClip(string clipName)
    {
        return Resources.Load("Sound/" + clipName, typeof(AudioClip)) as AudioClip;
    }


    public static void PlayDestroy() { PlaySound("Eliminate");  }
    public static void PlayShoot()   { PlaySound("Shoot"); }
    public static void PlayInsert()  { PlaySound("BallEnter"); }
    public static void PlayBomb()    { PlaySound("Bomb"); }
    public static void PlayFail()    { PlaySound("Fail"); }
    public static void PlayFastMove(){ PlaySound("FastMove"); }
    public static void PlayMusic(string name,float volume=0.3f) 
    {                                                   
        //bgAudio.clip = SoundManager.GetAudioClip(name);//*-
        //bgAudio.volume = volume;
        //bgAudio.loop = true;
        //bgAudio.Play();
        AudioKit.PlayMusic("resources://Sound/"+name,volume:volume);
    }



}

bug shooterSO数据丢失

发生里面的Vector3丢失的情况,所以用了以下。暂时不知道管不管用

        EditorUtility.SetDirty(fromAsset);

在这里插入图片描述

bug Object的AB包命名

原本我命名AB为 0_mapconfig,打包出也有这个ABbao1
但是右面自动出现了 0_asset,并且自动把 文件标记为 0)_asset,导致后面打包出现 0_asset
在这里插入图片描述

bug 通关下一关球没被销毁,只是progress==0

这是开始初始化的一段小球,不动是因为此时的GmaeState==Succ。重新进入游戏,需要重置 GameState
在这里插入图片描述

modify Manager拆分

将Manager从GamePanel中拆分出来
在这里插入图片描述

--------------------------------------------------------

Panel两个面板说明

也是采用QF的UI脚本自动生成,往里面填代码
。。。。
复活时回退得太多了(3D转UGUI的原因),需要调数值(里面有个回退时间是3秒)
。。。。
两个面板的效果在文章最后

Panel 成功

using UnityEngine;
using UnityEngine.UI;
using QFramework;
using UnityEngine.SceneManagement;
using QFramework.PointGame;


namespace QFramework.Example
{
	public class SuccPanelData : UIPanelData
	{
	}
	public partial class SuccPanel : UIPanel
	{
		protected override void OnInit(IUIData uiData = null)
		{
			mData = uiData as SuccPanelData ?? new SuccPanelData();
			// please add init code here


			BtnNext.onClick.AddListener(() => {
				
				UIKit.OpenPanel<GamePanel>(
					new GamePanelData() { LevelCount=GameData.GetLevelIndex() }
				);
				CloseSelf();
			});

			BtnHome.onClick.AddListener(() => {
                UIKit.OpenPanel<StartGamePanel>();
                CloseSelf();
            });
        }
		
		protected override void OnOpen(IUIData uiData = null)
		{
		}
		
		protected override void OnShow()
		{
		}
		
		protected override void OnHide()
		{
		}
		
		protected override void OnClose()
		{
		}
	}
}

Panel 失败

主要是复活,不能Close,所以失败后先Hide,后面
01 复活,就Show
02 再来一次,就Close,在Open
03 回主页

using UnityEngine;
using UnityEngine.UI;
using QFramework;
using UnityEngine.SceneManagement;

namespace QFramework.Example
{
	public class GameOverPanelData : UIPanelData
	{
	}


	public partial class GameOverPanel : UIPanel
	{
		protected override void OnInit(IUIData uiData = null)
		{
			mData = uiData as GameOverPanelData ?? new GameOverPanelData();
			// please add init code here

			BtnReset.onClick.AddListener(()=>{ //复活
                GameManager.Instance.GameRevive();
                CloseSelf();

            });

            BtnReplay.onClick.AddListener(() => { //再来一次
                UIKit.ClosePanel<GamePanel>();
                UIKit.OpenPanel<GamePanel>( new GamePanelData() { LevelCount=GameData.GetLevelIndex() });
                CloseSelf();
            });

			BtnHome.onClick.AddListener(() => {	 //主页
                UIKit.ClosePanel<GamePanel>();
                UIKit.OpenPanel<StartGamePanel>();
                CloseSelf();
            });
        }
		
		protected override void OnOpen(IUIData uiData = null)
		{
		}
		
		protected override void OnShow()
		{
		}
		
		protected override void OnHide()
		{
		}
		
		protected override void OnClose()
		{
		}
	}
}

---------------------------------------------------------

Tool 轨道制作

modify BezierPathController

制作Ball预制体(我用了红球(可以用别的)的sprite(UGUI),原本的是MeshRender(3D世界中))
节点“Map”是BezierPathController.Awake()中用到的,是演示蓝色球坐标的,可以注释掉

01 拖一个到“1”节点(带有BezierPathController脚本)下
01 不断Ctrl+D复制节点下的预制体(每4个(基本2个控制弯曲度,2个在轨道上)红球预制体就有生成一段蓝色球)
02 Control Point List里面就是红球的坐标数据(世界坐标)
06 每4个红色球后,Scene中会生成一段蓝色球
03 04 全部做完,点击“生成地图文件”,“Path Point List”里面就是蓝色球的位置(世界坐标)
05 Map文件夹下也保存了一份坐标数据

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using UnityEditor;
using System;
using UnityEngine.UI;

public class BezierPathController : MonoBehaviour
{

    #region 字属



    public int segmentsPerCurve = 3000;
    /// <summary>连线上求和球之间的举例,也就是比直径大一点</summary>
    public float BallAndBallDis = 0.3f;
    public bool Debug = true;
    public GameObject ballPrefab;

    /// <summary>贝塞尔曲线的节点。控制弯曲度的白球</summary>
    public List<GameObject> ControlPointList = new List<GameObject>();
    /// <summary>贝塞尔曲线的的线段。连线的蓝球的坐标</summary>
    public List<Vector3> pathPointList = new List<Vector3>();
    #endregion


    //private void Awake()
    //{
    //    Debug = true;
    //    foreach (var item in pathPointList)
    //    {
    //        GameObject ball = Instantiate(ballPrefab, GameObject.Find("Map").transform);
    //        ball.transform.position = item;
    //    }
    //}


    private void OnDrawGizmos()
    {
        //节点
        ControlPointList.Clear();
        foreach (Transform item in transform)//没错,就是遍历子节点
        {
            ControlPointList.Add(item.gameObject);
        }


        //线段
        List<Vector3> controlPointPos 
            = ControlPointList.Select(point => point.transform.position).ToList();
        var points = GetDrawingPoints(controlPointPos, segmentsPerCurve);

        Vector3 startPos = points[0];
        pathPointList.Clear();
        pathPointList.Add(startPos);
        for (int i = 1; i < points.Count; i++)
        {
            if (Vector3.Distance(startPos, points[i]) >= BallAndBallDis)
            {
                startPos = points[i];
                pathPointList.Add(startPos);
            }
        }

        foreach (var item in ControlPointList)
        {
            item.GetComponent<Image>().enabled = Debug;//相当于将物体隐身,并不会影响物体的脚本运行,物体的碰撞体也依然存在。
        }

        if (Debug == false)
        { 
            return;
        } 


        //01 画连线球的球
        Gizmos.color = Color.blue;
        foreach (var pos in pathPointList)
        {
            Gizmos.DrawSphere(pos, BallAndBallDis / 2);
        }

        //02 画连线球的线
        Gizmos.color = Color.yellow;
        for (int i = 0; i < points.Count - 1; i++)
        {
            Gizmos.DrawLine(points[i], points[i + 1]);
        }

        //03 画连线球的的弯曲度控制线
        //绘制贝塞尔曲线控制点连线,红,色
        Gizmos.color = Color.red;
        for (int i = 0; i < controlPointPos.Count - 1; i++)
        {
            Gizmos.DrawLine(controlPointPos[i], controlPointPos[i + 1]);
        }

    }



    #region 辅助


    /// <summary>贝塞尔线段</summary>
    List<Vector3> GetDrawingPoints(List<Vector3> controlPoints, int segmentsPerCurve)
    {
        List<Vector3> points = new List<Vector3>();
        for (int i = 0; i < controlPoints.Count - 3; i += 3)
        {
            var p0 = controlPoints[i];
            var p1 = controlPoints[i + 1];
            var p2 = controlPoints[i + 2];
            var p3 = controlPoints[i + 3];

            for (int j = 0; j <= segmentsPerCurve; j++)
            {
                var t = j / (float)segmentsPerCurve;
                points.Add(CalculateBezierPoint(t, p0, p1, p2, p3));
            }
        }
        return points;
    }

    /// <summary>
    /// <summary>贝塞尔曲线的三次方公式</summary>
    /// </summary>
    /// <param name="t"></param>
    /// <param name="p0">起点</param>
    /// <param name="p1">一侧的平滑度调节点</param>
    /// <param name="p2">另一侧的平滑度调节点</param>
    /// <param name="p3">终点</param>
    /// <returns></returns>
    Vector3 CalculateBezierPoint(float t
        , Vector3 p0
        , Vector3 p1, Vector3 p2
        , Vector3 p3)
    {
        var x   = 1 - t;
        var xx  = x * x;
        var xxx = x * x * x;
        var tt  = t * t;
        var ttt = t * t * t;
        return p0 * xxx 
            +   3 * p1 * t * xx 
            +   3 * p2 * tt * x 
            +  p3 * ttt;
    }


#if UNITY_EDITOR
    /// <summary>
    /// pathPointList写入"Assets/Map/map.asset"
    /// 但没有覆盖功能,删掉再创建就看得见效果了
    /// </summary> 
    public void CreateMapAsset()
    {
        string assetPath =String.Format(  "Assets/Map/{0}.asset",gameObject.name);  //写这Vector3数据的
        MapConfig mapConfig = new MapConfig();
        foreach (Vector3 item in pathPointList)
        {
            mapConfig.pathPointList.Add(item);
        }
        AssetDatabase.CreateAsset(mapConfig, assetPath);
        AssetDatabase.SaveAssets();
    }
#endif


    #endregion


}


#if UNITY_EDITOR
[CustomEditor(typeof(BezierPathController))]
public class BezierEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        if (GUILayout.Button("生成地图文件"))//详情面板下的按钮
        {
            (target as BezierPathController).CreateMapAsset();
        }
        AssetDatabase.Refresh();
    }
}
#endif



modify 保存位置,文件命名

保存位置放在Resources会报错
文件命名改为gameObject.name,不写死

string assetPath =String.Format( “Assets/Map/{0}.asset”, gameObject.name); //写这Vector3数据的

watch 遍历子节点

Transform 内部实现了迭代器,所以就可以这样写

        //节点
        ControlPointList.Clear();
        foreach (Transform item in transform)//没错,就是遍历子节点
        {
            ControlPointList.Add(item.gameObject);
        }

Tool 青蛙Shooter的位置

GameMapConfig来控制,里面有个Vector3数组

modify 修改图片的名字(-1),方便对应

在这里插入图片描述

modify 制作Shooter位置的一个工具

/****************************************************
    文件:MakeShooterPos.cs
	作者:lenovo
    邮箱: 
    日期:2023/7/19 15:37:17
	功能:
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Random = UnityEngine.Random;
 

public class MakeShooterPos : MonoBehaviour
{
#if UNITY_EDITOR
    /// <summary>
    /// pathPointList写入"Assets/Map/map.asset"
    /// 但没有覆盖功能,删掉再创建就看得见效果了
    /// </summary> 
    public void RecordeShooterPos()
    {
        MapConfig fromAsset= AssetDatabase.LoadAssetAtPath<MapConfig>("Assets/Map/shooter.asset");
        int idx = int.Parse( gameObject.name);
        Transform shooter = GameObject.Find("ShooterTrans").transform;
        fromAsset.pathPointList[idx] = shooter.localPosition;
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
#endif

}

#if UNITY_EDITOR
[CustomEditor(typeof(MakeShooterPos))]
public class MakeShooterPosEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        if (GUILayout.Button("生成Shooter位置"))//详情面板下的按钮
        {
            (target as MakeShooterPos).RecordeShooterPos();
        }
        AssetDatabase.Refresh();
    }
}
#endif





效果

在这里插入图片描述

---------------------------------------------------------

总的效果

01 主要按 S(Success)键,快速通关,进行测试。
02 主要按F(Fail)键,快速失败,进行测试
地图数据只做了三关,所以最后报空错误了
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

经营在线业务的首选客服工具--SS客服

随着网购正在快速取代传统零售业&#xff0c;各行各业的企业都在大力发展电子商务以取悦客户。但是&#xff0c;有这么多可用的电子商务平台&#xff0c;选择一款符合自己发展的平台确实不容易。电子商务平台不仅是企业在线销售产品和服务的地方&#xff0c;也是他们管理日常运…

按键消抖实现

一、使用状态机实现按键消抖 可将按键按下整个过程看做四个状态&#xff1a;按键空闲状态&#xff0c;按下抖动状态&#xff0c;稳定按下状态&#xff0c;释放抖动状态。 代码实现&#xff1a; /** Description: 状态机方式按键消抖(多按键)* Author: Fu Yu* Date: 2023-07-27…

听GPT 讲K8s源代码--pkg(八)

k8s项目中 pkg/kubelet/envvars&#xff0c;pkg/kubelet/events&#xff0c;pkg/kubelet/eviction&#xff0c;pkg/kubelet/images&#xff0c;pkg/kubelet/kubeletconfig这些目录都是 kubelet 组件的不同功能模块所在的代码目录。 pkg/kubelet/envvars 目录中包含了与容器运行…

服务器用友数据库中了locked勒索病毒后怎么解锁数据恢复

随着信息技术的迅速发展&#xff0c;服务器成为现代企业中不可或缺的重要设备。然而&#xff0c;由于网络安全风险的存在&#xff0c;服务器在日常运作中可能遭受各种威胁&#xff0c;包括恶意软件和勒索病毒攻击。近日&#xff0c;我们收到很多企业的求助&#xff0c;企业的用…

Jenkins+Gitlab+Maven集成CI/CD

MavenGitlab集成 配置好下列环境 # Java环境 JAVA_HOME /usr/lib/jvm/java-11-openjdk-11.0.19.0.7-1.el7_9.x86_64# Maven环境 MAVEN_HOME /usr/local/maven# Maven环境变量 PATHEXTRA $MAVEN_HOME/bin1. 配置settings.xml路径 2. 安装maven插件 创建项目 配置gitlab地址和指…

19.2:纸牌问题

给定一个整型数组arr&#xff0c;代表数值不同的纸牌排成一条线 玩家A和玩家B依次拿走每张纸牌 规定玩家A先拿&#xff0c;玩家B后拿 但是每个玩家每次只能拿走最左或最右的纸牌 玩家A和玩家B都绝顶聪明 请返回最后获胜者的分数 方法一&#xff1a;暴力解法 自然智慧。 pack…

Redis 基础知识和核心概念解析:探索 Redis 的数据结构与存储方式

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

基于解析法和遗传算法相结合的配电网多台分布式电源降损配置(Matlab实现)

目录 1 概述 2 数学模型 2.1 问题表述 2.2 DG的最佳位置和容量&#xff08;解析法&#xff09; 2.3 使用 GA 进行最佳功率因数确定和 DG 分配 3 仿真结果与讨论 3.1 33 节点测试配电系统的仿真 3.2 69 节点测试配电系统仿真 4 结论 1 概述 为了使系统网损达到最低值&a…

1200*B. Vanya and Lanterns

Examples input 7 15 15 5 3 7 9 14 0 output 2.5000000000 input 2 5 2 5 output 2.0000000000 解析&#xff1a; 最大距离即为每相邻两盏灯之间的最大距离/2 注意起点没有灯&#xff0c;终点可能有灯&#xff0c;需要分别判断 #include<bits/stdc.h> using nam…

Cesium态势标绘专题-直线箭头(标绘+编辑)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

大语言模型LLM

目录 一、语言模型的发展 语言模型&#xff08;Language Model&#xff0c;LM&#xff09;目标是建模自然语言的概率分布&#xff0c;具体目标是构建词序列w1,w2,...,wm的概率分布&#xff0c;即计算给定的词序列作为一个句子出现可能的大小P(w1w2...wm)。但联合概率P的参数量…

0-虚拟机补充知识

虚拟机克隆 如果想要构建服务器集群&#xff0c;没有必要一台一台的去进行安装&#xff0c;只要通过克隆就可以。 快速获得多台服务器主要有两种方式&#xff0c;分别为&#xff1a;直接拷贝操作和vmware的克隆操作 直接拷贝 将之前安装虚拟机的所有文件进行拷贝&#xff0…

git撤销上一次的commit

一行命令 git reset --soft HEAD^如果在vscode上面&#xff0c;就可以

Oracle 截取指定字符到目标串的末尾

SQL&#xff1a; SELECT-- 目标字符串 目标字符串 指定符号 最后一个 最后一个字符位置1 substr( HG/2106010103/YG\FJSJ\SXKTFJ\FJ03_JPHD, instr( HG/2106010103/YG\FJSJ\SXKTFJ\FJ03_…

transformer 笔记

目录 目前在NLP领域当中&#xff0c;主要存在三种特征处理器——CNN、RNN 以及 Transformer&#xff0c;当前Transformer的流行程度已经大过CNN和RNN&#xff0c;它抛弃了传统CNN和RNN神经网络&#xff0c;整个网络结构完全由Attention机制以及前馈神经网络组成。 Transformer…

【蓝图】p40-p43对象引用、变量有效性、实现键盘控制物体自转、简单点名系统

p40-p43对象引用、变量有效性、实现键盘控制物体自转、简单点名系统 p40对象引用、变量有效性p41实现键盘控制物体自转创建bool值控制旋转实现通过键盘控制自转 p42p43简单点名系统Get All Actors Of Class&#xff08;获得场景中所有该类的actor演员&#xff09;getFor Each L…

Dart - 语法糖(持续更新)

文章目录 前言开发环境中间表示语法糖1. 操作符/运算符&#xff08;?./??/??/../?../.../...?&#xff09;2. 循环&#xff08;for-in&#xff09;3. 函数/方法&#xff08;>&#xff09;4. 关键字&#xff08;await for&#xff09; 最后 前言 通过将dill文件序列化…

【腾讯云 Cloud Studio 实战训练营】沉浸式体验编写一个博客系统

文章目录 前言项目中技术栈新建工作空间登录(注册)Cloud Studio 账号&#xff1a;进入 Cloud Studio 控制台&#xff1a;配置工作空间参数&#xff1a;确认并创建工作空间&#xff1a;项目搭建 配置nuxt 脚手架运行项目报错信息解决错误脚手架运行预览问题 开启博客代码配置lay…

法大大携手盘子女人坊,以数字化唤醒国风摄影新体验

第三方数据显示&#xff0c;目前&#xff0c;我国共有163万家摄影相关企业&#xff0c;有约1900个从事摄影相关业务的品牌&#xff0c;且预计到2025年艺术摄影市场规模将达到7063.18亿元。艺术摄影行业作为在时代进步、科技发展以及人民生活水平提高的推动下逐渐发展起来的行业…

GPT一键化身「AI助理」——自定义指令功能

最近GPT又更新了一个超实用的功能——自定义指令&#xff0c;启用后&#xff0c;你可以给GPT设置一些固定指令&#xff0c;让它记住或扮演某个角色&#xff0c;比如客服、律师、投资管理师、老师、营养师...... 这样&#xff0c;我们就不再需要每次都要打开新的聊天&#xff0c…