游戏的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
- 接收数据 : 服务器发送数据在C中接收数据
- 更新数据 : Ctrl更新M中的数据
- 获得数据:V从Ctrl中获得M数据并更新V
- 发送数据: 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框架的方式不同,最后实现的都是由自己做决定,只要其主要思想不变就行.


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