3D Game Programming Design(四):游戏对象与图形基础(访问者模式)

本文探讨了在游戏开发中如何使用访问者模式来解决游戏中命令扩展的问题,通过该模式可以轻松地为游戏中的不同对象定义新的操作,而不必修改这些对象的类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们聊回上一次做的小游戏,分析下我写的Model有什么缺陷

上一篇的链接:https://blog.youkuaiyun.com/keven2148/article/details/79760734

GameController了解三种游戏物体并有他们的引用,三种物体想要获得其他的属性(例如Man的excuse需要知道boat和land的空位数组)可以通过GameController来引用,而不用显式相互引用,使耦合松散

游戏和一般工程不同,实例的生成大都是有计划性的,只有特定的一整套实例同时存在才有意义。在游戏内容不发生机制上的颠覆性改变(比如咱不过河了,咱改成漂流游戏)的前提下,改动Land,Man,Boat的规则都不会影响到其他三个类的正常使用,是容易维护的

但这里有一个问题,我们的InputController默认只会发出一个命令——excuse,excuse的逻辑分别由两个类自己处理,如果我们需要增加命令,例如让人或者船自杀,让人或者船变成金色!并且这些命令是对两个物体都同时有效的,也就是说,如果要增加命令,不仅要改动接口,还要同时修改boat和man类,显然不符合封闭开放原则,所以我们需要把命令的逻辑封装后分离出来。

这里我选择使用“访问者模式”

访问者模式:表示一个作用于某对象结构的各元素的操作。它使你可以在不改变元素的类的前提下定义作用于这些元素的新操作(——GOF)

仔细读读访问者模式的定义,封装了对元素的操作,并且“不改变元素的类”,正好,我们的boat和man是不需要改变的(变了这个游戏就不叫和尚与魔鬼了),“定义新操作”,是的,我们需要定义更多的操作。这个模式正是我们需要的

核心代码:

Visitor.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class Visitor{

    public abstract void VisitMan(Man Element);

    public abstract void VisitBoat(Boat Element);

}


Visitor_B.cs(Vistor_A.cs)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Visitor_B : Visitor {

    public override void VisitMan(Man Element)
    {
        Debug.Log("We right click on the Man!!!!");
    }

    public override void VisitBoat(Boat Element)
    {
        Debug.Log("We right click on the Boat!!!!");
    }
}

抽象类Vistor派生出不同的访问者,访问者分别对类的不同对象分别处理逻辑

传参保证了可以引用到类的对象的属性


InputController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//处理鼠标输入点击
public class InputController : MonoBehaviour {

    Visitor visitor;

    void Accept(Visitor _visitor) {
        visitor = _visitor;
    }

    void Update() {
        //如果鼠标左键有点击
        if (Input.GetMouseButtonDown(0)) {
            Accept(new Visitor_A());
            Raycast();
        }
        //如果鼠标右键键有点击
        else if (Input.GetMouseButtonDown(1)) {
            Accept(new Visitor_B());
            Raycast();
        }
    }

    void Raycast() {
       .....//非核心代码
    }
}

根据不同情况实例对应的访问者,并传入给被访问者


Man.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Man : MonoBehaviour , IObjectAction{

    ........//前略    

    public void  Accept(Visitor _visitor)
    {
        _visitor.VisitMan(this);
    }
}
关于状态的传递,这里使用了“双分派”的技巧。首先InputController将访问者作为参数传递给了“人”类,完成第一次分派。然后“人”类调用作为参数的访问者的方法中的针对“人”类的方法——VisitMan,并将自己作为参数传递进去,完成第二次分派。结果是访问者和被访问者在这之后可以相互引用了
3D游戏引擎编程-3D.Game.Engine.Programming.pdf,作者:Stefan Zerbst & Oliver Duvel,本书是英文版,大小 271 MB,被压缩成两部分分别上传。这是第一部分,第二部分下载地址:http://download.youkuaiyun.com/source/2697012。 IT业中游戏业最吃香?为什么呢?大家说有多少网民没有玩过游戏?不过中国游戏人才也是缺啊!看看盛大为了招收人才自己到各个大学去招收计算机本科生啊!中国最大的游戏公司竟然自己去招收人才,可想而知啊!!中国游戏人才到底缺多少!我们缺的不是玩游戏的,而是做游戏的!大家想必都有过要自己做游戏的梦想吧?为什么没有实现呢?因为觉得自己办不到?错!你能办到!从现在开始吧!我们一起将韩国泡菜赶出国门!一起努力实现中国第一个暴雪公司!创造中国自己畅销全世界的游戏!以中国的武侠魅力去震撼世界!我们不要让外国人牵着鼻子走! 我们技术上比不过美国,美工上比不过日本,创意上比不过韩国!我们有什么可以自豪的呢?中国游戏产业的振兴就靠我们这一代,不要让我们的下一代都只玩美国的XBOX,日本的PS,韩国的传奇!我们看到了中国游戏业这块大蛋糕已经让外国瓜分的剩不下多少了!中国的公司为了代理外国的一个游戏争的头破血流!这样的事情不要让他们再一次次重演了! 游戏开发职业虽然含金量较高,但从业门槛也高高在上,因此,学习前一定要先看看自己是否适合这一职业。判断标准主要有以下七点:一看学历,一般需有大专以上的教育背景;二看年龄,游戏业是年轻人的行业,18-35岁是最佳年龄段;三看逻辑性,从业人员除具备IT基本知识外,还要有相当强的逻辑能力,否则将难以担当复杂的编程工作;看知识面,游戏软件开发设计编剧、美术、音乐、动画、程序等诸多方面,知识面宽泛;五看创新能力,游戏开发需要经常翻花头,对开发者创新能力的要求较高;六看合作能力,游戏软件开发往往由一个小组负责,需要开发者有团队合作精神;七看兴趣,游戏开发是一项异常枯燥的工作,如果对此没有足够的兴趣,将很难做好。 发布的这些书都是原版的英文书籍,没有中文的,因为中文翻译的慢!大家如果想从事游戏开发,我真的建议大家先学英语,英语是你一切的一切的基础!大家也可以下载一个金山词霸来边翻译边看!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值