游戏中的MVC框架

游戏中的MVC框架游戏的 MVC 框架 前言 最近看看公司的代码 了解到了公司的游戏 UI 基本上都是利用 MVC 框架去实现的 所以想写一篇关于 MVC 框架的博客 公司用的是 lua 去实现 我就直接用 C 在 Unity 中实现一个排行榜系统 GitHub 项目 一 MVC 框架的概念 1 1 什么是 MVC 框架

大家好,我是讯享网,很高兴认识大家。

游戏的MVC框架

前言

一、MVC框架的概念

1.1 什么是MVC框架

MVC框架是一种设计模式,在游戏中一般用于UI模块,它将UI模块分为三个部分:模型(Model也就是数据),视图(View也就是UI界面),控制器(Controller).模型用于负责管理数据与逻辑,视图负责用户的界面,控制器负责处理用户输入和协调模型和视图 .

1.2 MVC框架的优点

可以将应用程序的数据,视图和控制器分离,使代码更加清晰和易维护.也可以方便扩展模型和视图的功能,在项目中能够修改数据结构或者UI界面,而不影响其他部分


讯享网

1.3 MVC框架流程:

  • Ctrl: Controller
  • M: Model
  • V: View
  1. 接收数据 : 服务器发送数据在C中接收数据
  2. 更新数据 : Ctrl更新M中的数据
  3. 获得数据:V从Ctrl中获得M数据并更新V
  4. 发送数据: V用户交互通过Ctrl数据发送给服务器
    如下图所示:
    在这里插入图片描述

二、MVC框架项目(实现排行榜)

2.1 基本思路

利用MVC框架简单的实现以下排行榜,我会利用Xml文件序列化与反序列化去进行一个本地化存储.一共分了四个代码去实现.

  • XmlUtil:Xml序列化与反序列化
  • RankData:排行榜的数据与逻辑
  • UI_Rank:排行榜的界面
  • RankCtrl:用于负责处理排行榜输入和协调数据和界面

2.2 相关代码

2.2.1 序列化相关代码(XmlUtil)
using System.Collections; using System.Collections.Generic; using System.Xml.Serialization; using UnityEngine; using System.IO; using System; using System.Runtime.Serialization.Formatters.Binary; using System.Xml; public class XmlUtil { 
    //序列化:将数据写入Xml文件中 public static void SerializeXml<T>(string path, T data) where T: class { 
    if (path == null || data == null) return; if (File.Exists(path)) File.Delete(path); //XmlSerializer:用于xml序列化与反序列的类 XmlSerializer serializer = new XmlSerializer(typeof(T)); //FileStream:表示文件流的类,它继承自Stream类,可以对文件进行字节级的读写操作。 FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); //StreamWriter:表示文本写入器的类,将字符或字符串编码为字节并写入到一个Stream中 using (StreamWriter sw = new StreamWriter(fileStream, System.Text.Encoding.UTF8)) { 
    serializer.Serialize(sw, data);//保存数据 sw.Close(); fileStream.Close(); } } //反序列化,读取数据 public static T DeserializeXml<T>(string path) where T : class { 
    T data = null; try { 
    if (path == null) return null; if (!File.Exists(path)) { 
    XmlDocument xml = new XmlDocument(); //创建根节点 XmlElement root = xml.CreateElement("objects"); //将根节点添加到xml文档中 xml.AppendChild(root); xml.Save(path); return null; } FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); XmlSerializer serializer = new XmlSerializer(typeof(T)); data = serializer.Deserialize(fs) as T; } catch { 
    Debug.LogError("读取文件失败!"); } return data; } //深拷贝 public static T DeepCopy<T>(T obj) { 
    object retval; using (MemoryStream ms = new MemoryStream()) { 
    BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj); ms.Seek(0, SeekOrigin.Begin); retval = bf.Deserialize(ms); ms.Close(); } return (T)retval; } } 

讯享网
2.2.2 排行榜数据相关代码(RankData)
讯享网using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Xml; using System; using System.Xml.Serialization; using System.IO; using System.Linq; [Serializable] public class RankData { 
    private string path = Application.streamingAssetsPath + "/rank.xml"; private RankMembers rankMemers; private List<Member> members; public Member[] Members { 
    get { 
    if (rankMemers != null && rankMemers.members != null && rankMemers.members.Length > 0) return rankMemers.members; return new Member[1] { 
    new Member(1, 0) }; } set { 
    } } //初始化数据 public void InitData() { 
    members = new List<Member>(); rankMemers = GetRankXml(); if(rankMemers != null && rankMemers.members != null && rankMemers.members.Length > 0) { 
    foreach (var item in rankMemers.members) { 
    members.Add(item); } } } //获得本地化数据 public RankMembers GetRankXml() { 
    RankMembers rankmemers = new RankMembers(); rankmemers = XmlUtil.DeserializeXml<RankMembers>(path); return rankmemers; } //刷新当前排行榜数据 public void RefreshRankMemeber(Member member) { 
    if(members.Count < 10) { 
    members.Add(member); rankMemers.members = members.ToArray(); SortRank(rankMemers, members); } else { 
    var lastIndex = members.Count - 1; var lastmember = members[lastIndex]; if (lastmember.score <= member.score) { 
    lastmember.score = member.score; member = null; rankMemers.members = members.ToArray(); SortRank(rankMemers, members); } } } //对排行榜数据进行排序 public void SortRank(RankMembers rankmemers, List<Member> members) { 
    Array.Sort(rankmemers.members, (a, b) => { 
    return b.score - a.score; }); members.Sort((a, b) => { 
    return b.score - a.score; }); if(rankmemers.members.Length > 0) { 
    for (int i = 0; i < rankmemers.members.Length; i++) { 
    var item = rankmemers.members[i]; item.id = i + 1; members[i].id = i + 1; } } } public void OnDestory() { 
    SaveRankData(); members.Clear(); members = null; rankMemers = null; } //保存数据 public void SaveRankData() { 
    if (path == null) { 
    Debug.LogError("RankXml的路径为空!"); return; } if (!File.Exists(path)) File.Create(path); try { 
    XmlUtil.SerializeXml(path, rankMemers); } catch { 
    Debug.Log("Xml文件保存失败!"); } } } //需要序列化的类 [Serializable] [XmlRoot("Members")] public class RankMembers { 
    public Member[] members; } [Serializable] public class Member { 
    [XmlAttribute("id")] public int id; [XmlAttribute("score")] public int score; public Member() { 
    } public Member(int _id, int _score) { 
    id = _id; score = _score; } } 
2.2.3 排行榜界面(UI_Rank)
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UI_Rank : MonoBehaviour { 
    private Text[] texts; private Transform obj; private Button closeBtn; private Button addBtn; private RankData rankData; private InputField inputField; private Action<Member> addAction; private void Start() { 
    OnInit(); } //获得RankCtlr里的rankData数据,以及初始化UI private void OnInit() { 
    rankData = RankCtrl.Instance.RankData; InitUI(); } //初始化UI private void InitUI() { 
    obj = transform.Find("Scroll View/Viewport/Content"); inputField = transform.Find("InputField").GetComponent<InputField>(); addBtn = transform.Find("AddBtn").GetComponent<Button>(); closeBtn = transform.Find("CloseBtn").GetComponent<Button>(); texts = new Text[10]; int num = obj.childCount; for (int i = 0; i < num; i++) { 
    texts[i] = obj.GetChild(i).gameObject.GetComponent<Text>(); } closeBtn.onClick.AddListener(CloseSelf); addBtn.onClick.AddListener(AddMember); RefreshUI(); } //率刷新UI界面 private void RefreshUI() { 
    if (rankData != null) { 
    if(rankData.Members.Length == 0) { 
    for (int i = 0; i < 10; i++) { 
    texts[i].text = string.Format("第{0}名: {1}分", i + 1, 0); } } else if(rankData.Members.Length < 10) { 
    for (int i = 0; i < rankData.Members.Length; i++) { 
    var item = rankData.Members[i]; texts[i].text = string.Format("第{0}名: {1}分", item.id, item.score); } for (int i = rankData.Members.Length; i < 10; i++) { 
    texts[i].text = string.Format("第{0}名: {1}分", i + 1, 0); } } else { 
    for (int i = 0; i < rankData.Members.Length; i++) { 
    var item = rankData.Members[i]; texts[i].text = string.Format("第{0}名: {1}分", item.id, item.score); } } } } //点击按钮,添加排行榜成员,并刷新UI private void AddMember() { 
    var numTxt = inputField.text; if (int.TryParse(numTxt, out var num)) { 
    Member member = new Member(); member.score = num; addAction.Invoke(member); RefreshUI(); } } //回调函数 public void SetHandler(Action<Member> action) { 
    addAction = action; } //关闭UI private void CloseSelf() { 
    this.gameObject.SetActive(false); } private void OnDestroy() { 
    texts = null; addAction = null; } } 
2.2.4 控制器(RankCtrl)
讯享网using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; using System; public class RankCtrl : MonoBehaviour { 
    private RankData rankData; private GameObject rankPanelObj; private UI_Rank rankPanel; public RankData RankData => rankData; private void Awake() { 
    OnInit(); } //初始化 private void OnInit() { 
    rankData = new RankData(); rankData.InitData(); rankPanelObj = GameObject.Find("UI_Rank"); rankPanel = rankPanelObj.GetComponent<UI_Rank>(); rankPanel.SetHandler(AddRankMember); } //单例模式 private static RankCtrl instance; public static RankCtrl Instance { 
    get { 
    if (instance == null) { 
    instance = FindObjectOfType<RankCtrl>(); if(instance == null) { 
    GameObject rankCtrlObj = new GameObject("RankCtrl"); instance = rankCtrlObj.AddComponent<RankCtrl>(); } DontDestroyOnLoad(instance.gameObject); } return instance; } set { 
    } } //添加数据 public void AddRankMember(Member member) { 
    rankData.RefreshRankMemeber(member); } public void OnDestroy() { 
    rankData.OnDestory(); rankData = null; rankPanelObj = null; rankPanel = null; } } 

三、对MVC框架的想法

在网上搜索了很多博客和资料,也拿这些资料与公司的MVC框架做比较,最后发现,MVC只是一种设计模式,它的体现是将数据和UI分离开来,提高代码的可扩展、可维护性等.一千个读者里面有一千个哈姆雷特,在游戏中不同的人实现MVC框架的方式不同,最后实现的都是由自己做决定,只要其主要思想不变就行.

小讯
上一篇 2025-03-20 10:51
下一篇 2025-01-13 14:02

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/117618.html