unity作业:MVC架构代码实现的计算器

一、MVC架构

        MVC(Model-View-Controller)是一种广泛使用的软件架构模式,旨在将应用程序的不同部分分离,以提高可维护性、可扩展性和组织性。MVC 模式将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。

        模型是应用程序的核心部分,负责管理数据、业务逻辑和状态。它直接与数据源进行交互,例如数据库或外部 API,并处理获取、存储和更新数据的任务。

        视图是用户界面部分,负责呈现模型的数据并接受用户输入。视图从模型中获取数据,并以适当的格式显示出来,只关注如何展示信息,而不涉及业务逻辑。

        控制器充当模型和视图之间的中介,处理来自视图的用户输入,调用模型的相应方法,并根据需要更新视图。控制器接收用户的动作(如按钮点击),并据此决定如何响应。

二、计算器代码实现

        1. 模型

              模型用于进行数学计算。CalculatorModel类里维护一个expression变量,存储表达式,使用 C# 的 System.Data.DataTable 来计算。

                

using System;
using System.Data;
using UnityEngine;

public class CalculatorModel : MonoBehaviour
{
    private string expression = "";  // 当前输入的表达式

    public string GetExpression()
    { 
        return expression; 
    }

    // 计算结果
    public bool ComputeResult()
    {
        try
        {
            // 使用 C# 的 System.Data.DataTable 来计算表达式
            var result = new System.Data.DataTable().Compute(expression, null);
            expression = result.ToString();  // 保存计算结果,继续计算
            return true;
        }
        catch (System.Exception ex)
        {
            expression = "";
            Debug.LogError("计算错误: " + ex.Message);  // 打印详细的错误信息
            return false;   
        }
    }

    // 添加到表达式
    public void Add(string input)
    {
        //Debug.Log(input);
        expression += input;
    }

    // 删除表达式的最后一个字符
    public void DeleteLastCharacter()
    {
        if (expression.Length > 0)
        {
            expression = expression.Substring(0, expression.Length - 1);
        }
    }

    // 清除表达式
    public void ClearExpression()
    {
        expression = "";
    }
}

    2.  视图

        本项目的视图主要用于表达式显示,界面和按钮等已在场景里铺设好。

        

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using TMPro;

public class CalculatorUI : MonoBehaviour
{
    public TextMeshProUGUI resultText;  // 显示输入和结果的Text

    public void SetResultText(string text)
    {
        resultText.text = text;
    }
}

3. 控制器

      控制器用于模型和视图之间的交互,负责按钮点击触发事件,修改模型类CalculatorModel里的表达式,并将表达式传输给视图类CalculatorUI ,更新视图。

using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class CalculatorController : MonoBehaviour
{
    public CalculatorModel model;  // 数据模型
    public CalculatorUI view;    // 用户界面

    // 按钮文本映射
    public Button[] numberButtons;  // 数字按钮数组
    public Button[] operatorButtons;  // 运算符按钮数组
    public Button delButton;  // 删除按钮
    public Button acButton;   // 清除按钮
    public Button dotButton;  // 小数点按钮
    public Button equalsButton;  // 计算按钮

    public void Start()
    {
        // 打印出按钮事件监听器的数量
        Debug.Log("Number Button 0 Listeners: " + numberButtons[0].onClick.GetPersistentEventCount());

        // 确保按钮点击事件只绑定一次
        foreach (Button btn in numberButtons)
        {
            btn.onClick.RemoveAllListeners();  // 移除所有监听器
            
            string input = btn.GetComponentInChildren<TextMeshProUGUI>().text;

            if (string.IsNullOrEmpty(input))
            {
                Debug.Log("000");
            }
            else
            {
                btn.onClick.AddListener(() => OnNumberButtonClick(input));
            }
                
        }

        foreach (Button btn in operatorButtons)
        {
            btn.onClick.RemoveAllListeners();  // 移除所有监听器

            string input = btn.GetComponentInChildren<TextMeshProUGUI>().text;

            if (string.IsNullOrEmpty(input))
            {
                Debug.Log("000");
            }
            else
            {
                btn.onClick.AddListener(() => OnOperatorButtonClick(input));
            }
        }

        // 删除按钮
        delButton.onClick.RemoveAllListeners();  // 移除所有监听器
        delButton.onClick.AddListener(OnDeleteButtonClick);

        // 清除按钮
        acButton.onClick.RemoveAllListeners();  // 移除所有监听器
        acButton.onClick.AddListener(OnClearButtonClick);

        // 小数点按钮
        dotButton.onClick.RemoveAllListeners();  // 确保只绑定一次
        dotButton.onClick.AddListener(OnDotButtonClick);

        // 等号按钮
        equalsButton.onClick.RemoveAllListeners();
        equalsButton.onClick.AddListener(OnEqualsButtonClick);
    }

    // 数字按钮点击事件
    public void OnNumberButtonClick(string number)
    {
        //Debug.Log(number);
        Debug.Log("Number Button: " + number + " Clicked");  // 输出按钮名称
        model.Add(number);
        view.SetResultText(model.GetExpression());
    }

    // 运算符按钮点击事件
    public void OnOperatorButtonClick(string operatorSymbol)
    {
        //Debug.Log(operatorSymbol);
        Debug.Log("Operator Button: " + operatorSymbol + " Clicked");  // 输出按钮名称

        if (operatorSymbol == "×")
           operatorSymbol = "*";
        else if(operatorSymbol == "÷")
           operatorSymbol = "/";

        model.Add(operatorSymbol);
        view.SetResultText(model.GetExpression());
    }

    // 小数点按钮点击事件
    public void OnDotButtonClick()
    {
        Debug.Log("Dot Button Clicked");

        model.Add(".");
        view.SetResultText(model.GetExpression());
    }

    // 删除按钮点击事件
    public void OnDeleteButtonClick()
    {
        Debug.Log("Delete Button Clicked");

        model.DeleteLastCharacter();
        view.SetResultText(model.GetExpression());
    }

    // 清除按钮点击事件
    public void OnClearButtonClick()
    {
        Debug.Log("Clear Button Clicked");

        model.ClearExpression();
        view.SetResultText("0");
    }

    // 等号按钮点击事件,执行计算
    public void OnEqualsButtonClick()
    {
        Debug.Log("Equal Button Clicked");

        if (model.ComputeResult())
        {
            view.SetResultText(model.GetExpression());
        }
        else 
        {
            view.SetResultText("Error");
        }
    }

    // 监听键盘输入(可选)
    public void Update()
    {
        // 监听键盘输入
        foreach (char c in Input.inputString)
        {
            if (char.IsDigit(c))  // 如果是数字
            {
                OnNumberButtonClick(c.ToString());
            }
            else if (c == '*')  // 处理乘法
            {
                OnOperatorButtonClick("×");  // 使用 * 代替 ×
            }
            else if (c == '/')  // 处理除法
            {
                OnOperatorButtonClick("÷");  // 使用 / 代替 ÷
            }
            else if ("+-".Contains(c.ToString()))  // 处理加减法
            {
                OnOperatorButtonClick(c.ToString());
            }
            else if (c == '\b')  // 回退键 (Backspace)
            {
                OnDeleteButtonClick();
            }
            else if (c == '.')   //小数点
            {
                OnDotButtonClick();
            }
            else if (c == '=')  // 回车键或等号
            {
                OnEqualsButtonClick();
            }
        }

        // 监听回车键(Enter)以触发等号
        if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
        {
            OnEqualsButtonClick();
        }
    }
}

三、项目展示

        总体效果:

                

视频

Rec 0001

项目地址

GitHub - fang2368/mycode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值