MVC:全名是Model-View-Controller
View(视图层 - 顶层)
Controller(控制层 - 中层)
Model(数据层 - 底层)
View(视图层)
说明:展现给玩家的(包括UI,包括场景中的一些表现)
注意:View层不能对Model的数据进行修改,但是能对Model的数据进行访问
功能:
1、数据的展现
2、管理自己面板的一些逻辑
3、实现用户界面的按钮的操作逻辑
Model(数据层)
说明:位于Frame最底层,属于数据中心
功能:
1、存放数据
2、提供修改访问数据的方法
3、通知View层数据已经发生改变,需要更新界面(通过事件)
Controller(控制层)
说明:对Model层具有访问和修改的权限。
功能:
1、根据逻辑对Model层的数据进行修改。
2、回调View的方法通知操作完成或者失败
MVC的优点:
1、工程结构更加的清晰
2、提高代码的可读性,封装性,扩展性
3、提高工作效率
游戏界面实例
画布尺寸1280x720

把原图当作底图,调整透明度,去添加调整元素位置

描边组件

取消滑动条的交互

代码逻辑
视图层:
延迟函数问题:连续点击时会生成多个延迟函数,未消失的延迟函数,会影响到下次调用结果
代码逻辑
视图层:
延迟函数问题:连续点击时会生成多个延迟函数,未消失的延迟函数,会影响到下次调用结果
控制层:用单例模式抽象封装方法
提示界面问题:用委托和回调方法来实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController
{
private static PlayerController instance;
public static PlayerController Instance
{
get
{
if (instance == null)
{
instance = new PlayerController();
}
return instance;
}
}
private PlayerController(){ }
public delegate void Del(string str);
/// <summary>
/// 增加经验的方法,参数是增加的经验
/// </summary>
/// <param name="exp"></param>
public void AddExp(float exp)
{
//人物死亡不能获得经验
if (PlayerData.Instance.CurrentHP > )
{
PlayerData.Instance.CurrentExp += exp;
//递归判断是否升级
CheckLevelUp();
}
else
{
Debug.Log("人物死亡");
}
}
/// <summary>
/// 使用递归判断是否升级
/// </summary>
void CheckLevelUp()
{
if (PlayerData.Instance.CurrentExp >= PlayerData.Instance.MaxExp)
{
PlayerData.Instance.CurrentExp -= PlayerData.Instance.MaxExp;
PlayerData.Instance.Level++;
PlayerData.Instance.Gold += PlayerData.Instance.Level * ;//每次升级需要增加玩家金币
CheckLevelUp();
}
}
/// <summary>
/// 购买金币,参数的购买的 100 * num
/// /// </summary>
/// <param name="gold"></param>
public void BuyGoldByDiamonds(int num, Del callback)
{
//金币比钻石 2 : 1
//判断钻石的数量是否够用
if (PlayerData.Instance.Diamonds >= (num * * 0.5f))
{
PlayerData.Instance.Diamonds -= (num * );
PlayerData.Instance.Gold += (num * );
}
else
{
Debug.Log("钻石不足,请充值");
//告诉调用的人,钻石不够了
if (callback != null)
{
callback("钻石不足,请充值,没钱玩什么游戏!");
}
}
}
public void Hit(float value, Del callback)
{
if (PlayerData.Instance.CurrentHP > )
{
PlayerData.Instance.CurrentHP = PlayerData.Instance.CurrentHP >= value ?
PlayerData.Instance.CurrentHP - value : ;
}
else
{
Debug.Log("玩家已经死亡");
if (callback != null)
{
callback("玩家已经死亡,不能鞭尸!!!!!");
}
}
}
/// <summary>
/// 通过金币购买血量 10 : 1
/// </summary>
/// <param name="hp"></param>
public void AddHPByGold(float hp)
{
if (PlayerData.Instance.CurrentHP <= )
{
Debug.Log("玩家已经死亡");
}
else
{
int gold = (int)Mathf.Ceil(hp * 0.1f);
if (PlayerData.Instance.Gold >= gold)
{
PlayerData.Instance.Gold -= gold;
PlayerData.Instance.CurrentHP += hp;
PlayerData.Instance.CurrentHP = PlayerData.Instance.CurrentHP > PlayerData.Instance.MaxHP ?
PlayerData.Instance.MaxHP : PlayerData.Instance.CurrentHP;
}
else
{
Debug.Log("金币不够");
}
}
}
public void ResetLife()
{
if (PlayerData.Instance.CurrentHP <= )
{
if (PlayerData.Instance.Diamonds >= )
{
PlayerData.Instance.Diamonds -= ;
PlayerData.Instance.CurrentHP = PlayerData.Instance.MaxHP * 0.5f;
}
else
{
Debug.Log("钻石不足, 请充值! 没钱,玩什么游戏!");
}
}
else
{
Debug.Log("玩家还没死呢,复什么活!");
}
}
/// <summary>
/// 充值
/// </summary>
public void Recharge(int diamonds)
{
PlayerData.Instance.Diamonds += diamonds;
}
}
数据层:用单例模式管理数据,提供修改访问数据的方法
数据刷新和同步问题:用属性对字段进行封装,用事件储存需要监控当前数据变化的界面的方法,当访问属性的时候,调用事件函数
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//所有的数据都已经放在PlayerData里了
public class PlayerData
{
//未继承Mono的单例
//1、先有一个私有的静态的自己的实例
private static PlayerData instance;
//2、提供一个访问实例的属性或者方法
public static PlayerData Instance
{
get
{
//判断实例是否为null
if (instance == null)
{
instance = new PlayerData();
}
return instance;
}
}
public string PlayerName
{
get
{
return playerName;
}
set
{
if (playerName != value)
{
//通知界面更新
playerName = value;
Debug.Log("值发生改变,更新界面");
UpdatePanel();
}
}
}
public float MaxHP
{
get
{
return maxHP;
}
set
{
if (maxHP != value)
{
maxHP = value;
Debug.Log("值发生改变,更新界面");
UpdatePanel();
}
}
}
public float CurrentHP
{
get
{
return currentHP;
}
set
{
if (currentHP != value)
{
currentHP = value;
Debug.Log("值发生改变,更新界面");
UpdatePanel();
}
}
}
public float MaxExp
{
get
{
return maxExp;
}
set
{
if (maxExp != value)
{
maxExp = value;
Debug.Log("值发生改变,更新界面");
UpdatePanel();
}
}
}
public float CurrentExp
{
get
{
return currentExp;
}
set
{
if (currentExp != value)
{
currentExp = value;
Debug.Log("值发生改变,更新界面");
UpdatePanel();
}
}
}
public int Level
{
get
{
return level;
}
set
{
if (level != value)
{
level = value;
Debug.Log("值发生改变,更新界面");
UpdatePanel();
}
}
}
public int Gold
{
get
{
return gold;
}
set
{
if (gold != value)
{
gold = value;
Debug.Log("值发生改变,更新界面");
UpdatePanel();
}
}
}
public int Diamonds
{
get
{
return diamonds;
}
set
{
if (diamonds != value)
{
diamonds = value;
Debug.Log("值发生改变,更新界面");
UpdatePanel();
}
}
}
//3、私有构造函数
private PlayerData()
{
//私有构造函数里进行数据的初始化
PlayerName = "寒冰射手";
MaxHP = ;
CurrentHP = ;
MaxExp = ;
CurrentExp = ;
Level = ;
Gold = ;
Diamonds = ;
}
private string playerName;
private float maxHP;
private float currentHP;
private float maxExp;
private float currentExp;
private int level;
private int gold;
private int diamonds;
//1.声明一个委托类型
public delegate void Del();
//2.声明一个事件变量
public event Del updateEvent;//这个事件里存储了所有的需要监控当前数据变化的界面的方法
void UpdatePanel()
{
//通知界面更新,不知道有多少界面,
//可以使用委托=事件的方式,来通知所有的界面
if (updateEvent != null)
{
updateEvent();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UGUI_Shop : MonoBehaviour
{
private Button expButton;
private Button goldButton;
private Button diamondsButton;
private void Awake()
{
expButton = transform.Find("Button1").GetComponent<Button>();
goldButton = transform.Find("Button2").GetComponent<Button>();
diamondsButton = transform.Find("Button3").GetComponent<Button>();
expButton.onClick.AddListener(BuyExpClick);
goldButton.onClick.AddListener(BuyGoldClick);
diamondsButton.onClick.AddListener(BuyDiamondsClick);
}
void BuyExpClick()
{
PlayerController.Instance.AddExp();
}
void BuyGoldClick()
{
PlayerController.Instance.BuyGoldByDiamonds(, null);
}
void BuyDiamondsClick()
{
PlayerController.Instance.Recharge();
}
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UGUI_Message : MonoBehaviour {
private Text nameText;
private Text hpText;
private Text expText;
private Text levelText;
void Awake()
{
nameText = transform.Find("Text1").GetComponent<Text>();
hpText = transform.Find("Text2").GetComponent<Text>();
expText = transform.Find("Text3").GetComponent<Text>();
levelText = transform.Find("Text4").GetComponent<Text>();
//当数据改变时,需要更新界面,把更新界面的方法添加到PlayerData的事件里去
PlayerData.Instance.updateEvent += UpdatePanel;
}
// Use this for initialization
void Start()
{
UpdatePanel();//数据初始化
}
private void OnDestroy()
{
//当界面销毁的时候,不需要去监听数据的变化了,把事件移除
PlayerData.Instance.updateEvent -= UpdatePanel;
}
//数值发生改变的时候,更新界面
public void UpdatePanel()
{
nameText.text = "名字:" + PlayerData.Instance.PlayerName;
hpText.text = "血量:" + ((int)PlayerData.Instance.CurrentHP).ToString()
+ "/" + ((int)PlayerData.Instance.MaxHP).ToString();
expText.text = "经验:" + ((int)PlayerData.Instance.CurrentExp).ToString()
+ "/" + ((int)PlayerData.Instance.MaxExp).ToString();
levelText.text = "等级:" + PlayerData.Instance.Level.ToString();
}
}

Unity3D学习笔记(二十四):MVC框架的更多相关文章

  1. python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法

    python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...

  2. (C/C++学习笔记) 二十四. 知识补充

    二十四. 知识补充 ● 子类调用父类构造函数 ※ 为什么子类要调用父类的构造函数? 因为子类继承父类,会继承到父类中的数据,所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程. ...

  3. Java基础学习笔记二十四 MySQL安装图解

    .MYSQL的安装 1.打开下载的mysql安装文件mysql-5.5.27-win32.zip,双击解压缩,运行“setup.exe”. 2.选择安装类型,有“Typical(默认)”.“Compl ...

  4. Unity3D学习笔记(十四):Animation旧动画

        animator(新动画系统):骨骼动画,骨骼驱动,格式化编辑,动画机图形化 animation(旧动画系统):物理系统,帧动画 一.如何建立动画文件 Animation Clip 手动添加动 ...

  5. Java学习笔记二十四:Java中的Object类

    Java中的Object类 一:什么是Object类: Object类是所有类的父类,相当于所有类的老祖宗,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object ...

  6. PHP学习笔记二十四【Get Set】

    <?php Class Person{ private $n1; private $n2; private $n3; //使用__set方法来管理所有的属性 public function __ ...

  7. angular学习笔记(二十四)-$http(2)-设置http请求头

    1. angular默认的请求头: 其中,Accept 和 X-Requested-With是$http自带的默认配置 Accept:application/json,text/plain       ...

  8. python3.4学习笔记(二十五) Python 调用mysql redis实例代码

    python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...

  9. 学习笔记:CentOS7学习之二十四:expect-正则表达式-sed-cut的使用

    目录 学习笔记:CentOS7学习之二十四:expect-正则表达式-sed-cut的使用 24.1 expect实现无交互登录 24.1.1 安装和使用expect 24.2 正则表达式的使用 24 ...

  10. 设计模式学习(二十四):Spring 中使用到的设计模式

    设计模式学习(二十四):Spring 中使用到的设计模式 作者:Grey 原文地址: 博客园:设计模式学习(二十四):Spring 中使用到的设计模式 CSDN:设计模式学习(二十四):Spring ...

随机推荐

  1. JS闭包中的循环绑定处理程序

    前几天工作中写前端js代码时,遇到了遍历元素给它添加单击事件.就是这个问题让我整整调了一个下午.最后还是下班回家,上网查资料才知道怎么解决的. (PS:之前也在<jQuery基础教程>第四 ...

  2. 前端 HTML的规范

    1.编写HTML规范 1)所有标记元素都要正确的嵌套,不能交叉嵌套.正确写法举例:<h1><font></font></h1> (2)HTML标签通常是 ...

  3. 如何修改WordPress网站默认登录地址wp-admin

    使用过WordPress程序建网站的学员都知道,我们使用Wordpress建好的网站,它的网站登录后台就是“网站域名/wp-admin”.如下图: 为了网站安全,如何修改Wordpress网站默认登录 ...

  4. easyUI的datebox添加清空按钮功能

    需要修改源码: 第一步:按下图修改 第二步:按下两图修改(*zh_CN.js)

  5. EXTJS 4:在renderer中如何控制一个CheckColumn的行为,如显示,只读等属性

    在编写grid下的column时,大家肯定会经常用到renderer这个方法来改变文字的呈现形式,那么如果该column是一个特殊的column,比如CheckColumn时,该方法应该怎样写呢?官方 ...

  6. TFS修改映射路径办法

    如果你之前配置好了TFS项目的映射路径.然后每次下载项目都会在你配置的路径,但我们可以修改 方法一:我们可以在 "工作区" 中修改路径

  7. tfs项目解绑及svn上传

    1.tfs解绑 file--源代码管理——tfs解绑 2.svn将本地的文件夹上传到server 右击--import--url--新建文件夹

  8. Understanding Convolutional Neural Networks for NLP

    When we hear about Convolutional Neural Network (CNNs), we typically think of Computer Vision. CNNs ...

  9. Cookie学习笔记

    1.简介 1.什么是cookie:cookie是一种能够让网站服务器把少量数据(4kb左右)存储到客户端的硬盘或内存.并且读可以取出来的一种技术. 2.当你浏览某网站时,由web服务器放置于你硬盘上的 ...

  10. python+Django框架运用(一)

    Django 介绍: django是一个采用Python语言开发的开源框架,2005年发布.早期是做新闻以及内容管理的网站的,提供了非常强大的后管理系统. django官网:https://www.d ...