【OOP】DOTA世界中的对象建模

本文通过DOTA游戏中的英雄、技能和物品,探讨面向对象编程(OOP)的设计思想。作者提出,英雄类可以作为基类,通过组合而非继承来处理英雄类型和攻击类型,以实现更灵活的分类。技能类则关注其不同类型和目标,物品类则涉及复杂的合成和组合关系。整个建模过程旨在实践OOP原则并提供一种有趣的学习方式。
摘要由CSDN通过智能技术生成

“献给那些在斧王半岛饱受摧残的红皮兽人。”

作为一名DOTA的老玩家,我突然有了一个想法,就是试着将DOTA世界中的英雄、物品等各种机制进行一个简单的OOP建模。我会将我每步的思考都写下来,如有不对,恳请指正。

英雄

首先,DOTA中最核心的角色就是各个英雄了。所以英雄应当作为一个基类,有以下这些属性:

先来说说HeroType和RangeType这两个属性。

如果将力量、敏捷、智力分别分为三类,近战、远程分为两类,都继承自Hero类,那么就会如下图这样:

可是这样做的话,不管采用哪种分类,总会面临在下一层需要再次区分英雄类型的问题。比如采用了力量|敏捷|智力的分类,那么英雄的近战|远程就区分不开了,必须在下层再进行区分,就变成了这样:

很显然,这样很臃肿。很不美丽。

当继承(is-a)行不通的时候,我们想到使用组合(has-a)。何必要把这些属性绑定到Hero类里呢?不如把英雄类型和攻击类型作为一个接口,是哪种类型的英雄实现哪种接口就好了,如下图:

这样做的话,比如在实例化斧王时,分别赋值Strength和Melee,即可让斧王成为一名强壮的近战力量英雄。

还有一个好处,虽然英雄的类型一般是固定的,但是我们不必把类型和英雄绑定的死死的,基于OOP中的Open-Close原则,保不齐哪天V社会将斧王改成一名远程法师呢?所以在斧王能尽情斩杀的时候珍惜他吧。

很显然,Hero类中的Spells、Items、Words同样也可以用组合的方式关联起来,只不过斧王有好多个技能,有很多物品和语音,所以使用聚合的方式。

下面我们来谈谈英雄的技能。

 

技能

先看看技能的基本属性。

显然,SpellType的两种类型和TargetType的三种类型使用组合关联到Spell类就可以了。

至于Cast属性,因为不是所有英雄技能都是耗蓝的,比如哈斯卡就是用生命在燃烧,卡尔的三球法术切换就不需要任何代价,土猫/火猫的石头和魂都是可以充能的技能。所以这里需要将Cost分离出来,如下图:

注意到这里和英雄的几种类型实现有所不同。这是因为英雄只可能是力量、敏捷、智力其中的一种,也不可能既是近战也是远程英雄,但是技能则不同,一个技能可能既耗费魔法又消耗点数(比如火猫的飞魂),也可能既耗费魔法又消耗生命值(比如凤凰的飞)。

这里把Cost定义为接口,以下的三个ManaCost、HealthCost、PointCost也是接口,这样在一个技能同时满足其中两个条件时,可以实现多个接口。以后还可以添加GoldCost的技能,比如突变模式中打赏消耗对方生命值。

我们再来看看物品。

 

物品

DOTA中纷繁复杂的物品合成是其一大特色,这里列出它的一些基本属性:

物品也有技能,所以它和Spell显然是组合关系,而它可以合成和被合成物品,所以它和自己本身是一种聚合关系。层层递进:

以上是我对DOTA世界的一些概念的简单建模,也许有很多纰漏,但只是为了练习一下OOP相关的概念,Just For Fun!

如有错误的地方,欢迎指正。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值