在我的项目(游戏)中,我有多个通过触摸操作的对象,所以我认为将所有可触摸对象作为“可触摸”抽象类的子类是一个好主意,类似于:
Touchable 是 CCSprite 的子类
Box 是 Touchable 的子类
Motor 是 Touchable 的子类
因此Box和Motor都是CCSprite,它们继承了Touchable的常用方法,并且可以覆盖它们
这是解决这个问题的正确方法,还是有其他方法来解决这个层次结构?
在我的项目(游戏)中,我有多个通过触摸操作的对象,所以我认为将所有可触摸对象作为“可触摸”抽象类的子类是一个好主意,类似于:
Touchable 是 CCSprite 的子类
Box 是 Touchable 的子类
Motor 是 Touchable 的子类
因此Box和Motor都是CCSprite,它们继承了Touchable的常用方法,并且可以覆盖它们
这是解决这个问题的正确方法,还是有其他方法来解决这个层次结构?
我之前解释了为什么子类化 CCSprite 几乎总是一个坏主意。
顾名思义,“可触摸”是对象的一种能力。一个节点可以被触摸,也可以不被触摸。此外,这绝不能仅限于精灵。如果以后你想要一个可触摸的标签、一个可触摸的粒子效果或其他一些可触摸的节点类怎么办?
显然,您不能将 CCNode 子类化以使其可触摸,然后将该可触摸节点类的子类转回精灵、标签等,因为 cocos2d 已经建立了类层次结构——这就是这种层次结构系统的不灵活性表现出来的地方,并开始成为真正的痛苦。
您可以随时将这种可触摸(或可杀死、飞行、跳跃、可驾驶、可滑动等)能力添加到任何对象,也可以随时将其带走。这使它成为插件类(组件)的候选者。任何能力,尤其是那些可能是临时的,都不应该是超类的一部分,而是可以添加到现有对象的附加对象,并根据需要启用/禁用。
解决此问题的一种方法是使用节点的 userObject 属性。编写一个 Abilities 容器类,并将其分配给节点的 userObject。然后将所需的能力类添加到节点的容器中。然后该节点通过转发更新方法更新 userObject 容器类,该更新方法将更新转发给所有能力。或者,Ability 容器本身向 CCScheduler 注册以接收更新。容器类和能力类唯一需要的是对拥有节点的(弱)引用。
取决于“可触摸”是否表示每个类必须显式实现以支持的一组随机行为,或者是否可以有一个实现“仅适用于”继承(可能需要一些定制)。
如果是前者,那么你的想法基本上是正确的。如果是后者,那么 Jack 建议使用 an @protocol
(很像 Java 中的接口)是有道理的。
就个人而言,我会保持它非常简单。从一个SPAbstractSprite
作为子类的类开始CCSprite
。然后,将其子类化为SPBox
and SPMotor
。
SPBox
在和/或中开始您的实现,并且SPMotor
当常见的事情发生时,将它们重构为SPAbstractSprite
.
至于“可触摸”的概念,我暂时不会担心试图让它成为一个命名的东西。以与上述相同的方式接近它;在您的电机或盒子中实现可触摸支持,然后重构为抽象父类。
诚然,我是一个非常设计和代码交错的人,并且完全承认有些人真的很喜欢在编写一行代码之前坐下来画出一组漂亮的框/线/层次结构.
在任何情况下,您都应该注意,Apple 提供的类和示例的类层次结构往往很浅,并且不会做大量的这种抽象,尽管抽象仍然被大量使用(UIView
是所有的抽象容器例如,所有这些子类都需要的类似 goop 的视图)。