QFramework v1.0 Guide: 工具篇——ViewControllor, ActionKit时序动作执行系统,ResKit资源管理开发解决方案

目录

一、QFramework.Toolkits简介

二、View Controllor

1、作用

2、应用场景

3、示例

三、ActionKit时序动作执行系统

1. 用法

(1)延时回调

(2)序列执行

(3)帧延时

(4)条件执行

(5)重复执行

(6)并行执行

(7)自定义动作

(8)协程支持

(9)全局 Mono 生命周期

(10)DOTween 集成

(11)UniRx 集成

2. 优势

3. 应用场景

总结

四、 ResKit 资源管理&开发解决方案

1. 用法

(1)开发阶段(模拟模式)

(2)真机阶段(非模拟模式)

2. 优势

3. 应用场景

4. 示例

(1)加载场景

(2)加载 Resources 中的资源

(3)加载网络图片

(4)自定义资源加载

总结


一、QFramework.Toolkits简介

QFramework.Toolkits 称为 QFramework 工具集,是一套开箱即用的、渐进式快速开发框架。

QFramework.Toolkits 特性一览

  • 工具集(QFramework.Toolkits v0.16)

    • UIKit 界面&View快速开发&管理解决方案

      • UI、GameObject 的代码生成&自动赋值

      • 界面管理

      • 层级管理

      • 界面堆栈

      • 默认使用 ResKit 方式管理界面资源

      • 可自定义界面的加载、卸载方式

      • Manager Of Manager 架构集成(不推荐使用)

    • ResKit 资源快速开发&管理解决方案

      • AssetBundle 提供模拟模式,开发阶段无需打包即可加载资源

      • 资源名称代码生成支持

      • 同一个 API 可加载 AssetBundle、Resources、网络 和 自定义来源的资源

      • 提供一套引用计数的资源管理模型

    • AudioKit 音频管理解决方案

      • 提供背景音乐、人声、音效 三种音频播放 API

      • 音量控制

      • 默认使用 ResKit 方式管理音频资源

      • 可自定义音频的加载、卸载方式

    • CoreKit 提供大量的代码工具

      • ActionKit:动作序列执行系统

      • CodeGenKit:代码生成 & 自动序列化赋值工具

      • EventKit:提供基于类、字符串、枚举以及信号类型的事件工具集

      • FluentAPI:对大量的 Unity 和 C# 常用的 API 提供了静态扩展的封装(链式 API)

      • IOCKit:提供依赖注入容器

      • LocaleKit:本地化&多语言工具集

      • LogKit:日志工具集

      • PackageKit:包管理工具,由此可更新框架和对应的插件模块。

      • PoolKit:对象池工具集,提供对象池的基础上,也提供 ListPool 和 Dictionary Pool 等工具。

      • SingletonKit:单例工具集

      • TableKit:提供表格类数据结构的工具集

二、View Controllor

View Controller(视图控制器) 是MVC(Model-View-Controller,模型-视图-控制器)架构模式中的一个关键组件,用于管理和协调视图(View)与模型(Model)之间的交互。

1、作用

  1. 管理视图的显示与更新

    • 视图控制器负责加载和管理视图(View),并根据模型(Model)中的数据更新视图。

    • 例如,当玩家的分数(存储在模型中)发生变化时,视图控制器会通知视图更新显示。

  2. 处理用户输入

    • 视图控制器接收用户的输入(如点击按钮、移动鼠标等),并将其转换为对模型的操作。

    • 例如,玩家点击“增加分数”按钮时,视图控制器会调用模型中的方法来更新分数。

  3. 协调视图与模型的交互

    • 视图控制器作为视图和模型之间的桥梁,确保两者之间的数据同步。

    • 它可以监听模型中的数据变化,并通知视图进行更新。

  4. 管理视图的生命周期

    • 视图控制器负责管理视图的加载、显示、隐藏和销毁。

    • 在Unity中,这通常通过脚本控制游戏对象的激活状态来实现。

2、应用场景

  1. 游戏开发

    • 角色属性显示:玩家的血量、经验值、等级等数据存储在模型中,视图控制器负责将这些数据更新到UI视图上。

    • 游戏菜单管理:主菜单、设置菜单、暂停菜单等视图由视图控制器管理,用户点击菜单项时,视图控制器处理输入并触发相应的逻辑。

  2. UI界面管理

    • 动态UI更新:例如,玩家购买道具时,视图控制器更新背包视图中的道具数量。

    • 多视图切换:在游戏的不同阶段(如教程、关卡选择、游戏结束等)切换不同的视图。

  3. 复杂交互逻辑

    • 事件驱动:视图控制器可以监听事件(如玩家死亡、任务完成等),并根据事件更新视图或触发其他逻辑。

    • 状态管理:视图控制器可以保存和恢复视图的状态,例如在游戏暂停时保存当前界面状态。

3、示例

以下是一个简单的Unity MVC示例,展示如何使用视图控制器来管理玩家的分数:

PlayerModel.cs(模型)

public class PlayerModel
{public int score;public void AddScore(int points){score += points;}
}

PlayerView.cs(视图)

using UnityEngine;
using UnityEngine.UI;public class PlayerView : MonoBehaviour
{public Text scoreText;public void UpdateScore(int score){scoreText.text = "Score: " + score;}
}

PlayerController.cs(视图控制器)

using UnityEngine;public class PlayerController : MonoBehaviour
{public PlayerModel playerModel;public PlayerView playerView;void Start(){playerModel = new PlayerModel();playerView = GetComponent<PlayerView>();playerView.UpdateScore(playerModel.score);}public void OnAddScoreButtonClicked(){playerModel.AddScore(10); // 假设按钮点击增加10分playerView.UpdateScore(playerModel.score);}
}

在这个例子中:

  • PlayerModel 存储玩家的分数。

  • PlayerView 负责显示分数。

  • PlayerController 接收用户输入(按钮点击),更新模型,并通知视图更新显示。

通过这种方式,视图控制器在Unity中实现了视图与模型的解耦,使得代码更加模块化和易于维护

三、ActionKit时序动作执行系统

ActionKit 是一个强大的时序动作执行系统,用于简化游戏开发中的各种时序任务(如动画播放、延时操作、资源加载、网络请求等)。它通过统一的 API 将这些任务整合在一起,使得开发者可以更方便地管理和控制这些任务的执行顺序和逻辑。

1. 用法

ActionKit 提供了多种方法来定义和执行时序任务,包括延时回调、序列执行、条件执行、重复执行、并行执行等。以下是一些主要的用法:

(1)延时回调
using UnityEngine;
using QFramework;public class DelayExample : MonoBehaviour
{void Start(){Debug.Log("Start Time:" + Time.time);ActionKit.Delay(1.0f, () =>{Debug.Log("End Time:" + Time.time);}).Start(this);}
}
  • 在指定的延时后执行回调函数。

  • 优势:简化了延时操作的代码,避免手动使用 InvokeCoroutine

  • 应用场景:适用于需要在特定时间后执行某些操作的场景,例如动画播放、UI 更新等。

(2)序列执行
using UnityEngine;
using QFramework;public class SequenceAndCallback : MonoBehaviour
{void Start(){Debug.Log("Sequence Start:" + Time.time);ActionKit.Sequence().Callback(() => Debug.Log("Delay Start:" + Time.time)).Delay(1.0f).Callback(() => Debug.Log("Delay Finish:" + Time.time)).Start(this, _ => { Debug.Log("Sequence Finish:" + Time.time); });}
}
  • 按照顺序执行一系列动作。

  • 优势:可以方便地定义复杂的执行顺序,支持嵌套序列。

  • 应用场景:适用于需要按顺序执行多个任务的场景,例如动画序列、任务流程等。

(3)帧延时
using UnityEngine;
using QFramework;public class DelayFrameExample : MonoBehaviour
{void Start(){Debug.Log("Delay Frame Start FrameCount:" + Time.frameCount);ActionKit.DelayFrame(1, () => { Debug.Log("Delay Frame Finish FrameCount:" + Time.frameCount); }).Start(this);ActionKit.Sequence().DelayFrame(10).Callback(() => Debug.Log("Sequence Delay FrameCount:" + Time.frameCount)).Start(this);}
}
  • 在指定的帧数后执行回调函数。

  • 优势:基于帧数的延时,适用于需要精确控制帧数的场景。

  • 应用场景:适用于动画帧控制、帧率同步等场景。

(4)条件执行
using UnityEngine;
using QFramework;public class ConditionExample : MonoBehaviour
{private void Start(){ActionKit.Sequence().Callback(() => Debug.Log("Before Condition")).Condition(() => Input.GetMouseButtonDown(0)).Callback(() => Debug.Log("Mouse Clicked")).Start(this);}
}
  • 只有在满足特定条件时才执行后续动作。

  • 优势:可以灵活地控制动作的执行条件。

  • 应用场景:适用于需要根据用户输入或游戏状态触发操作的场景。

(5)重复执行
using UnityEngine;
using QFramework;public class RepeatExample : MonoBehaviour
{private void Start(){ActionKit.Repeat().Condition(() => Input.GetMouseButtonDown(0)).Callback(() => Debug.Log("Mouse Clicked")).Start(this);ActionKit.Repeat(5).Condition(() => Input.GetMouseButtonDown(1)).Callback(() => Debug.Log("Mouse right clicked")).Start(this, () =>{Debug.Log("Right click finished");});}
}
  • 重复执行某个动作,直到满足特定条件或达到指定次数。

  • 优势:简化了重复操作的代码,支持无限循环和有限循环。

  • 应用场景:适用于需要反复执行的任务,例如资源加载、网络请求等。

(6)并行执行
using UnityEngine;
using QFramework;public class ParallelExample : MonoBehaviour
{void Start(){Debug.Log("Parallel Start:" + Time.time);ActionKit.Parallel().Delay(1.0f, () => { Debug.Log(Time.time); }).Delay(2.0f, () => { Debug.Log(Time.time); }).Delay(3.0f, () => { Debug.Log(Time.time); }).Start(this, () =>{Debug.Log("Parallel Finish:" + Time.time);});}
}
  • 同时执行多个动作。

  • 优势:可以并行处理多个任务,提高效率。

  • 应用场景:适用于需要同时执行多个任务的场景,例如多个动画同时播放、多个资源同时加载等。

(7)自定义动作
using UnityEngine;
using QFramework;public class CustomExample : MonoBehaviour
{class SomeData{public int ExecuteCount = 0;}private void Start(){ActionKit.Custom(a =>{a.OnStart(() => { Debug.Log("OnStart"); }).OnExecute(dt =>{Debug.Log("OnExecute");a.Finish();}).OnFinish(() => { Debug.Log("OnFinish"); });}).Start(this);ActionKit.Custom<SomeData>(a =>{a.OnStart(() =>{a.Data = new SomeData(){ExecuteCount = 0};}).OnExecute(dt =>{Debug.Log(a.Data.ExecuteCount);a.Data.ExecuteCount++;if (a.Data.ExecuteCount >= 5){a.Finish();}}).OnFinish(() => { Debug.Log("Finished"); });}).Start(this);}
}
  • 允许开发者自定义动作的执行逻辑。

  • 优势:提供了高度的灵活性,可以实现复杂的逻辑。

  • 应用场景:适用于需要自定义逻辑的场景,例如自定义动画、自定义任务流程等。

(8)协程支持
using System.Collections;
using UnityEngine;
using QFramework;public class CoroutineExample : MonoBehaviour
{private void Start(){ActionKit.Coroutine(SomeCoroutine).Start(this);SomeCoroutine().ToAction().Start(this);ActionKit.Sequence().Coroutine(SomeCoroutine).Start(this);}IEnumerator SomeCoroutine(){yield return new WaitForSeconds(1.0f);Debug.Log("Hello:" + Time.time);}
}
  • 支持将协程转换为 ActionKit 的动作。

  • 优势:可以将协程与 ActionKit 的动作系统无缝集成。

  • 应用场景:适用于需要使用协程的场景,例如复杂的异步任务。

(9)全局 Mono 生命周期
using UnityEngine;
using QFramework;public class GlobalMonoEventsExample : MonoBehaviour
{void Start(){ActionKit.OnUpdate.Register(() =>{if (Time.frameCount % 30 == 0){Debug.Log("Update");}}).UnRegisterWhenGameObjectDestroyed(gameObject);ActionKit.OnFixedUpdate.Register(() =>{// fixed update code here}).UnRegisterWhenGameObjectDestroyed(gameObject);ActionKit.OnLateUpdate.Register(() =>{// late update code here}).UnRegisterWhenGameObjectDestroyed(gameObject);ActionKit.OnGUI.Register(() =>{GUILayout.Label("See Example Code");}).UnRegisterWhenGameObjectDestroyed(gameObject);ActionKit.OnApplicationFocus.Register(focus =>{Debug.Log("focus:" + focus);}).UnRegisterWhenGameObjectDestroyed(gameObject);ActionKit.OnApplicationPause.Register(pause =>{Debug.Log("pause:" + pause);}).UnRegisterWhenGameObjectDestroyed(gameObject);ActionKit.OnApplicationQuit.Register(() =>{Debug.Log("quit");}).UnRegisterWhenGameObjectDestroyed(gameObject);}
}
  • 允许开发者在全局范围内注册和管理生命周期事件。

  • 优势:简化了全局事件的管理,避免在多个脚本中重复编写相同的代码。

  • 应用场景:适用于需要全局管理生命周期事件的场景,例如全局状态管理、资源清理等。

(10)DOTween 集成
using DG.Tweening;
using UnityEngine;
using QFramework;public class DOTweenExample : MonoBehaviour
{private void Start(){ActionKit.Custom(c =>{c.OnStart(() => { transform.DOLocalMove(Vector3.one, 0.5f).OnComplete(c.Finish); });}).Start(this);DOTweenAction.Allocate(() => transform.DOLocalRotate(Vector3.one, 0.5f)).Start(this);DOVirtual.DelayedCall(2.0f, () => Debug.Log("2.0f")).ToAction().Start(this);ActionKit.Sequence().DOTween(() => transform.DOScale(Vector3.one, 0.5f)).Start(this);}
}
  • 将 DOTween 的动画功能集成到 ActionKit 中。

  • 优势:可以使用 ActionKit 的统一 API 来管理 DOTween 动画。

  • 应用场景:适用于需要使用 DOTween 动画的场景,例如复杂的动画序列。

(11)UniRx 集成
using System;
using UniRx;
using UnityEngine;
using QFramework;public class UniRxExample : MonoBehaviour
{void Start(){ActionKit.Custom(c =>{c.OnStart(() => { Observable.Timer(TimeSpan.FromSeconds(1.0f)).Subscribe(_ => c.Finish()); });}).Start(this, () => Debug.Log("1.0f"));UniRxAction<long>.Allocate(() => Observable.Timer(TimeSpan.FromSeconds(2.0f))).Start(this, () => Debug.Log("2.0f"));Observable.Timer(TimeSpan.FromSeconds(3.0f)).ToAction().Start(this, () => Debug.Log("3.0f"));ActionKit.Sequence().UniRx(() => Observable.Timer(TimeSpan.FromSeconds(4.0f))).Start(this, () => Debug.Log("4.0f"));}
}
  • 将 UniRx 的响应式编程功能集成到 ActionKit 中。

  • 优势:可以使用 ActionKit 的统一 API 来管理 UniRx 的异步任务。

  • 应用场景:适用于需要使用 UniRx 的场景,例如复杂的异步任务、响应式编程等。

2. 优势
  1. 统一的 API:ActionKit 提供了一套统一的 API 来管理各种时序任务,简化了代码的复杂性。

  2. 高度灵活:支持多种执行方式(如延时、序列、条件、重复、并行等),可以满足各种复杂的场景需求。

  3. 易于集成:支持与协程、DOTween、UniRx 等工具集成,扩展性强。

  4. 生命周期管理:支持全局生命周期事件的注册和管理,方便全局状态的控制。

  5. 简化开发:减少了手动编写重复代码的工作量,提高了开发效率。

3. 应用场景
  1. 游戏开发:适用于动画播放、任务流程、资源加载、网络请求等场景。

  2. UI 管理:适用于复杂的 UI 动画和交互逻辑。

  3. 全局事件管理:适用于全局生命周期事件的管理,例如 UpdateFixedUpdateLateUpdate 等。

  4. 异步任务管理:适用于需要异步执行的任务,例如资源加载、网络请求等。

  5. 动画序列:适用于需要按顺序或并行播放多个动画的场景。

总结

ActionKit 是一个功能强大的时序动作执行系统,通过统一的 API 和灵活的执行方式,极大地简化了游戏开发中的时序任务管理。它支持多种执行模式(如延时、序列、条件、重复、并行等),并且可以与协程、DOTween、UniRx 等工具无缝集成,适用于各种复杂的开发场景。

四、 ResKit 资源管理&开发解决方案

ResKit 是一个资源管理与快速开发解决方案,旨在简化 Unity 项目中的资源加载和管理流程。它通过统一的 API,支持从多种来源(如 dataPathResourcesStreamingAssetsPathPersistentDataPath、网络等)加载资源,并基于引用计数简化资源的加载和卸载。

1. 用法

ResKit 的使用分为开发阶段和真机阶段,支持模拟模式和非模拟模式,以适应不同的开发需求。

(1)开发阶段(模拟模式)
  • 标记资源:在 Asset 目录下,对需要标记的文件或文件夹右键选择 @ResKit - AssetBundle Mark

  • 编写代码:使用 ResLoader 加载资源,ResKit 会自动从 Application.dataPath 加载资源,无需打包。

using UnityEngine;
using QFramework;public class ResKitExample : MonoBehaviour
{private ResLoader mResLoader = ResLoader.Allocate();private void Start(){ResKit.Init(); // 初始化 ResKit// 同步加载资源var prefab = mResLoader.LoadSync<GameObject>("AssetObj");var gameObj = Instantiate(prefab);gameObj.name = "Loaded Object";}private void OnDestroy(){mResLoader.Recycle2Cache(); // 释放资源mResLoader = null;}
}
(2)真机阶段(非模拟模式)
  • 打包资源:取消模拟模式,使用 ResKit 提供的工具打包 AssetBundle。

  • 加载资源:在运行时加载 AssetBundle 资源,ResKit 会自动处理加载逻辑。

示例代码(异步加载):

using System.Collections;
using UnityEngine;
using QFramework;public class AsyncLoadExample : MonoBehaviour
{private ResLoader mResLoader = ResLoader.Allocate();private IEnumerator Start(){yield return ResKit.InitAsync(); // 异步初始化 ResKitmResLoader.Add2Load<GameObject>("AssetObj", (succeed, res) =>{if (succeed){var gameObj = res.Asset.As<GameObject>().Instantiate();gameObj.name = "Loaded Object";}});mResLoader.LoadAsync(); // 执行异步加载}private void OnDestroy(){mResLoader.Recycle2Cache();mResLoader = null;}
}
2. 优势
  1. 统一 API:支持从多种来源加载资源,简化了资源管理的复杂性。

  2. 引用计数:基于引用计数管理资源加载和卸载,避免资源泄漏。

  3. 开发效率:模拟模式下无需频繁打包,直接从 dataPath 加载资源,提高开发效率。

  4. 异步加载:支持异步加载队列,优化加载性能。

  5. 代码生成:可生成资源名常量代码,减少拼写错误。

  6. 灵活扩展:支持自定义资源加载逻辑,可集成 Addressables 或其他资源管理方案。

3. 应用场景
  1. 游戏开发:适用于需要动态加载资源的场景,如游戏关卡加载、道具加载等。

  2. UI 管理:快速加载 UI 预制体和资源,优化用户体验。

  3. 网络资源加载:支持从网络加载图片、模型等资源。

  4. 多平台支持:适用于多种平台(如 Android、iOS、WebGL 等),尤其是 WebGL 平台的异步加载支持。

  5. 资源热更新:支持 AssetBundle 的热更新,方便游戏版本迭代。

4. 示例

以下是一些具体的使用示例:

(1)加载场景
using UnityEngine;
using QFramework;public class LoadSceneExample : MonoBehaviour
{private ResLoader mResLoader = null;void Start(){ResKit.Init();mResLoader = ResLoader.Allocate();// 同步加载场景mResLoader.LoadSceneSync("SceneRes");// 异步加载场景mResLoader.LoadSceneAsync("SceneRes", onStartLoading: operation =>{// 加载进度处理});}private void OnDestroy(){mResLoader.Recycle2Cache();mResLoader = null;}
}
(2)加载 Resources 中的资源
using UnityEngine;
using UnityEngine.UI;
using QFramework;public class LoadResourcesResExample : MonoBehaviour
{public RawImage RawImage;private ResLoader mResLoader = ResLoader.Allocate();private void Start(){// 加载 Resources 目录里的资源RawImage.texture = mResLoader.LoadSync<Texture2D>("resources://TestTexture");}private void OnDestroy(){mResLoader.Recycle2Cache();mResLoader = null;}
}
(3)加载网络图片
using UnityEngine;
using UnityEngine.UI;
using QFramework;public class NetImageExample : MonoBehaviour
{private ResLoader mResLoader = ResLoader.Allocate();private void Start(){var image = transform.Find("Image").GetComponent<Image>();mResLoader.Add2Load<Texture2D>("http://example.com/image.jpg".ToNetImageResName(),(succeed, res) =>{if (succeed){var texture = res.Asset as Texture2D;var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f);image.sprite = sprite;mResLoader.AddObjectForDestroyWhenRecycle2Cache(sprite);}});mResLoader.LoadAsync();}private void OnDestroy(){mResLoader.Recycle2Cache();mResLoader = null;}
}
(4)自定义资源加载
using UnityEngine;
using QFramework;public class CustomResExample : MonoBehaviour
{public class MyRes : Res{public MyRes(string name){mAssetName = name;}public override bool LoadSync(){// 自定义同步加载逻辑State = ResState.Ready;return true;}public override void LoadAsync(){// 自定义异步加载逻辑State = ResState.Ready;}protected override void OnReleaseRes(){// 自定义资源释放逻辑State = ResState.Waiting;}}public class MyResCreator : IResCreator{public bool Match(ResSearchKeys resSearchKeys){return resSearchKeys.AssetName.StartsWith("myres://");}public IRes Create(ResSearchKeys resSearchKeys){return new MyRes(resSearchKeys.AssetName);}}private void Start(){ResFactory.AddResCreator<MyResCreator>();var resLoader = ResLoader.Allocate();var resSearchKeys = ResSearchKeys.Allocate("myres://hello_world");var myRes = resLoader.LoadResSync(resSearchKeys);resSearchKeys.Recycle2Cache();Debug.Log(myRes.AssetName);Debug.Log(myRes.State);}
}

总结

ResKit 是一个功能强大的资源管理解决方案,通过统一的 API 和灵活的加载方式,极大地简化了 Unity 项目中的资源管理流程。它支持多种加载来源、引用计数管理、异步加载队列、代码生成等功能,适用于游戏开发、UI 管理、网络资源加载等多种场景。

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

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

相关文章

GLIDE论文阅读笔记与DDPM(Diffusion model)的原理推导

Abstract 扩散模型&#xff08;Diffusion model&#xff09;最近被证明可以生成高质量的合成图像&#xff0c;尤其是当它们与某种引导技术结合使用时&#xff0c;可以在生成结果的多样性与保真度之间进行权衡。本文探讨了在文本条件图像生成任务中使用扩散模型&#xff0c;并比…

@Pushgateway 数据自动清理

文章目录 Pushgateway 数据自动清理一、Pushgateway 数据清理的必要性二、自动清理方案方案1&#xff1a;使用带TTL功能的Pushgateway分支版本方案2&#xff1a;使用Shell脚本定期清理方案3&#xff1a;结合Prometheus记录规则自动清理 三、最佳实践建议四、验证与维护五、示例…

QML视图组件ListView、TableView、GridView介绍

1 MVD模型 Model:模型,包含数据及其结构。View:视图,用于显示数据。Delegate:代理,规定数据在视图中的显示方式。2 ListView 以列表形式展示数据。2.1 属性 model:设置或获取列表视图的数据模型delegate:定义了列表中每一项的外观和行为currentIndex:获取或设置当前选…

解决vscode打开一个单片机工程文件(IAR/keil MDK)因无法找到头文件导致的结构体成员不自动补全问题。

最近一直在用vscode安装c/c插件后编辑STM32标准库&#xff08;keil MDK&#xff09;项目源文件&#xff0c;因为我感觉vscode在代码编辑方面比keil MDK本身优秀太多。发现打开工程后&#xff0c;结构体变量的成员在输入“.”后不自己弹出的问题&#xff0c;后来查找各方资料&am…

5分钟申请edu邮箱【方案本周有效】

这篇文章主要展示的是成果。如果你是第1次看见我的内容&#xff0c;具体的步骤请翻看往期的两篇作品。先看更正补全&#xff0c;再看下一个。 建议你边看边操作。 【更正补全】edu教育申请通过方案 本周 edu教育邮箱注册可行方案 #edu邮箱 伟大无需多言 我已经验证了四个了…

零知开源——STM32F407VET6驱动ILI9486 TFT显示屏 实现Flappy Bird游戏教程

简介 本教程使用STM32F407VET6零知增强板驱动3.5寸 ILI9486的TFT触摸屏扩展板实现经典Flappy Bird游戏。通过触摸屏控制小鸟跳跃&#xff0c;躲避障碍物柱体&#xff0c;挑战最高分。项目涉及STM32底层驱动、图形库移植、触摸控制和游戏逻辑设计。 目录 简介 一、硬件准备 二…

云台式激光甲烷探测器:守护工业安全的“智慧之眼”

在石油化工、天然气场站、城市燃气管网等场景中&#xff0c;甲烷泄漏的早期监测是保障生产安全的核心防线。云台式激光甲烷探测器凭借高精度、无接触、智能化的技术优势&#xff0c;成为工业安全监测领域的革新者。本文将深度解析其技术原理、核心功能及适用场景&#xff0c;助…

解决 Ubuntu 20.04 虚拟机中 catkin_make 编译卡死问题

完整解决步骤 1. 禁用当前交换文件 sudo swapoff /swapfile 2. 删除旧的交换文件 sudo rm /swapfile 3. 使用更可靠的创建方法 # 使用 dd 命令创建交换文件&#xff08;更兼容但较慢&#xff09; sudo dd if/dev/zero of/swapfile bs1M count4096# 或者使用 truncate 命令…

实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.7 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第5章析因设计引导5.7节思考题5.7 R语言解题。主要涉及方差分析&#xff0c;正态假设检验&#xff0c;残差分析&#xff0c;交互作用图&#xff0c;等值线图。 dataframe <-data.frame…

linux变量的分类

文章目录 bash中的引号linux变量的分类1.环境变量2.本地变量&#xff1a;3.局部变量4.内置变量5. 位置参数变量6. 特殊变量 变量的定义规则8.数组 bash中的引号 双引号"" &#xff1a;会把引号的内容当成整体来看待&#xff0c;允许通过 符号引用其他变量值单引 号 …

逻辑回归知识点

一、逻辑回归概念 逻辑回归(Logistic Regression)是一种广泛应用于分类问题的统计方法&#xff0c;尤其适用于二分类问题。 注意: 尽管名称中有"回归"二字&#xff0c;但它实际上是一种分类算法。 解决二分类的问题。 API&#xff1a;sklearn.linear_model.Logis…

GCC内存占用统计使用指南

GCC 的 --print-memory-usage 选项用于在编译链接过程中输出程序的内存占用统计信息&#xff0c;特别适用于嵌入式开发等内存受限的场景。其主要作用和输出内容如下&#xff1a; 核心功能 显示内存分段占用 输出程序在目标设备内存中的分段占用情况&#xff0c;通常包括&#…

Vue3 + Typescript:类型使用记录 / 类型注解 / 积累

一、ReturnType<typeof createApp> ReturnType<typeof createApp> 是一种类型安全的写法&#xff0c;是 TypeScript 中的一个高级类型&#xff0c;它用于获取函数 createApp 的返回类型。 实例&#xff1a; import registerFocus from ./focus // 获取焦点 impo…

SIFT 算法原理详解

SIFT 算法原理详解 SIFT&#xff08;尺度不变特征变换&#xff0c;Scale-Invariant Feature Transform&#xff09;是一种经典的局部特征检测和描述算法&#xff0c;它能够在不同的尺度、旋转和光照变化下稳定地检测图像特征。SIFT 主要包括以下几个步骤&#xff1a;尺度空间极…

2024年认证杯SPSSPRO杯数学建模D题(第二阶段)AI绘画带来的挑战解题全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现&#xff1a; 2023 年开年&#xff0c;ChatGPT 作为一款聊天型AI工具&#xff0c;成为了超越疫情的热门词条&#xff1b;而在AI的另一个分支——绘图领域&#xff0c;一款名为Midjourney&#xff08;MJ&#xff…

电子电路:全面深入了解晶振的定义、作用及应用

本次了解重点: 1.压电效应的数学描述 2.生产工艺以及关键工序 3.电路设计部分如负阻原理和匹配电容计算 4.失效案例比如冷启动问题 5.新形态晶振技术引入5G和量子计算 6.温补晶振的补偿机制 7故障案例讲解-更换负载电池或增加预热电路 蓝牙音频断续-频偏导致 工控机死机-起振电…

【Java实用工具类】手撸SqlBuilder工具类,优雅拼接动态SQL,MyBatisPlus同款风格!

&#x1f4cc; 正文&#xff1a; 有时候我们项目底层是 JdbcTemplate 查询&#xff0c;没法像 MyBatisPlus 一样用 Wrapper 拼接条件&#xff0c;但我们又不想手撸字符串。那怎么办&#xff1f;我今天就给你整了个 SqlBuilder 工具类&#xff0c;支持 eq、ne、like、in、gt、l…

WEB3——开发者怎么查看自己的合约日志记录

在区块链中查看合约的日志信息&#xff08;也叫事件 logs&#xff09;&#xff0c;主要有以下几种方式&#xff0c;具体方法依赖于你使用的区块链平台&#xff08;如 Ethereum、BSC、Polygon 等&#xff09;和工具&#xff08;如 Etherscan、web3.js、ethers.js、Hardhat 等&am…

Maven-生命周期

目录 1.项目对象模型 2.依赖管理模型 3.仓库&#xff1a;用于存储资源&#xff0c;管理各种jar包 4.本地仓库路径 1.项目对象模型 2.依赖管理模型 3.仓库&#xff1a;用于存储资源&#xff0c;管理各种jar包 4.本地仓库路径

redis数据过期策略

redis数据过期策略有两种方案 1.惰性删除 2.定期删除 首先说惰性删除&#xff0c;对于已经过期的数据&#xff0c;访问这个key的时候判断key是否过期&#xff0c;如果过期则删除&#xff0c;这种方式对cpu友好&#xff0c;只有使用key的时候才会进行过期检查&#xff0c;用不到…