IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 游戏设计模式:命令模式(以Unity开发坦克大战为例) -> 正文阅读

[游戏开发]游戏设计模式:命令模式(以Unity开发坦克大战为例)

命令模式

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

我们在游戏设计中使用命令模式有以下好处:

? 1.可以把游戏行为和游戏角色解耦合,易于分别维护游戏角色和游戏行为的代码,更新其一时不需要或只需要少量改动另一的代码

? 2.可以通过记录产生过的游戏指令序列来记录整个游戏过程,生成体积很小的游戏回放文件

? 3.易于实现游戏中的撤销功能

? 4.易于编写AI操控游戏角色


示例

以坦克大战为例(这里使用Unity做示范):

1.首先我们得有一个坦克类的脚本,挂载在坦克的预制件上

  class Tank : MonoBehaviour  
    {
        GameObject t;
        Rigidbody2D rb;
        public float speed;
        void Start()
        {
            rb = transform.GetComponent<Rigidbody2D>();
        }
        public void Move(Vector2 v)
        {
            rb.velocity = v;
        }
    }

这个类负责提供操控一个坦克实例的函数,以及存储该坦克实例的各种参数。

2.然后我们设置一个命令类,以最基本的移动命令为例(大部分游戏物体都具有移动这一游戏行为)

 interface Command //给坦克下达的命令
    {
        void Execute(ref Tank t);
    };
    class MoveCommand : Command  //移动指令
    {
        private Vector2 v;
        private static MoveCommand instance = new MoveCommand();
        private MoveCommand(){   //阻止生成实例
            v = Vector2.zero;
        }
        public static ref MoveCommand getInstance(){  //返回实例的引用
            return ref instance;
        }
        public void Setv(Vector2 _v)  //设置速度
        {
            v = _v;
        }
        public void Execute(ref Tank t)
        {
            t.Move(v);
        }
    }

这里又使用了所谓单例模式:将移动命令类的构造函数声明为private,可以阻止其被初始化为多个实例,在内部生成一个实例然后通过getInstance返回,这样可以保证全局只有一个移动命令类的实例,好处是免去了在各个地方生成和销毁实例的开销,并且可以避免多个命令类实例同时对一个实例下达命令导致其行为冲突的可能性。

我们没有在命令类中绑定某一个实例,而是在Execute中直接传入,这样可以用同样的配置(比如这里是速度的配置)批量对任意数量的游戏实例执行命令。

而对于特定的某一个实例如果需要单独记录其配置,则可以在Tank类中增加相关的成员来记录,并在命令类中增加一个开关:使用实例中的配置还是指令中的配置。需要注意更改其配置也应通过相应命令类来实现。

在Execute中记录当前的命令类实例,执行的对象实例,以及执行时的时间,即可生成指令序列形式的游戏回放,也可以实现Undo(撤销)操作

我们再设置一个Player类,这个类用于接收玩家从外设输入的指令。

  public class Player : MonoBehaviour
    {
        KeyCode[] keymap;  //0:上 1:下 2:左 3:右
        Vector2[] dv;
        Tank t;
        MoveCommand mc;
        void Start()
        {
            //初始化按键列表
            keymap = new KeyCode[] { KeyCode.W, KeyCode.S, KeyCode.A, KeyCode.D };
            //初始化单位方向向量列表
            dv = new Vector2[] { Vector2.up,Vector2.down,Vector2.left,Vector2.right};  
            mc = MoveCommand.getInstance();
            
        }
   
        public void Bind(ref Tank _t)
        {
            t = _t;
            this.transform.parent=t.transform;  //让Player跟随绑定的坦克移动
        }
        /// <summary>
        /// 处理移动控制的外设输入
        /// </summary>
        void MoveControl() 
        {
            for(int i=0;i<4;i++)
            {
                if (Input.GetKey(keymap[i]))
                {
                    mc.Setv(t.speed*dv[i]);
                    mc.Execute(ref t);
                    return;
                }
            }
            mc.Setv(Vector2.zero);
            mc.Execute(ref t);
        }
        private void FixedUpdate()
        {
            MoveControl();
        }
    }

在本游戏中,玩家要控制一个坦克,我们可以在Player类里绑定一个游戏场景中的坦克的实例,这样当玩家需要重生或者更换坦克时就非常方便.

如果要支持多人游戏,可以生成多个Player实例绑定不同的坦克实例来实现,不需要添加额外的代码。

当Player实例接收到玩家输入的指令时, 就通过命令类把绑定的坦克实例作为参数传入,让命令类驱动坦克类执行命令。

接下来只要生成一个Tank实例然后调用Player的Bind函数绑定即可

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-02-09 21:02:32  更:2022-02-09 21:04:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:42:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码