在 AS3 中,如何在不继承的情况下为多个类提供附加功能?

发布于 2024-09-29 15:32:23 字数 728 浏览 0 评论 0原文

我正在用 ActionScript 编写一个游戏,其中有多个应该可以通过射击“击中”的类。

所有其他游戏内实体继承的最通用的类​​是 CombatObject; CombatShip、CombatAsteroid 和其他各种类都继承自它。 CombatAi 和 CombatPlayer 类都继承自 CombatShip。

现在我想让 CombatAi、CombatPlayer 和 CombatAsteroid 可被射击击中,但我不希望它们继承它(以后可能会有不应该被击中的 CombatShips)。

我现在的想法是让这三个实现一个接口 IHitable,这样当它们与射击相撞时,我可以询问 if(hitObject is IHitable) 如果为真,则摧毁射击并造成伤害。

现在的问题是,最好让这些类中的每一个都

  1. 自己实现承受伤害所需的所有代码(例如检查护盾、计算伤害百分比等)。
  2. 让它们都拥有类 DamageManager 的实例 并实现一个函数 getDamageManager():DamageManager,该函数返回一个处理所有与伤害相关的功能的类。
  3. (2.) 的一个缺点是每个 CombatShip、CombatAsteroid 等都必须拥有 DamageManager 的实例。让 DamageManager 成为 Singleton 并且只引用船舶和给予它的射击并让它处理其余的事情可能会更好吗?

I am writing a game in ActionScript where I've got multiple classes that should be "hitable" by shots.

The most generic class that all other in-game entities inherit from is CombatObject; The classes CombatShip, CombatAsteroid and various others inherit from it. The classes CombatAi and CombatPlayer both inherit from CombatShip.

Now I want to make CombatAi, CombatPlayer and CombatAsteroid hitable by shots, but I don't want them to inherit it (later there might be CombatShips that shouldn't be hitable).

My idea now was to have these three implement an Interface, IHitable, so that when they collide with a shot, I can ask if(hitObject is IHitable) and if true, have the shot destroyed and do damage.

Now the question is, would it be best to have each of these classes

  1. Implement all the needed code to take damage (such as checking shields, calculating damage percentages, etc.) themselves
  2. Have them all own an instance of the class DamageManager and implement a function getDamageManager():DamageManager, that returns a class that handles all damage related functionality
  3. One disadvantage of (2.) would be that each CombatShip, CombatAsteroid, etc would have to own an Instance of DamageManager. Would it perhaps be even better to have DamageManager be a Singleton and just have a reference to the ship and the shot given to it and let it handle the rest?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

左耳近心 2024-10-06 15:32:23

Mixins 是一个好主意,但它在 AS3 中的支持是模拟的。

选项 2 可以工作,但是暴露 DamageManager 的实例会破坏封装。您可以通过在 IHitable 接口中添加 hit 方法来解决此问题。当有东西击中此对象时,您的游戏将调用此方法。该方法的实现由对象决定。您可以为每个对象以不同的方式实现它(选项 1),但您也可以创建一个通用 DamageManager 类并使用它来计算损坏。

class DamageManager {
    public function calculateDamage(...){
        // implement your damage logic...
    } 
}

interface IHitable {
    function hit(by:GameObject);
}

例如,在 CombatPlayer 中,

class CombatPlayer implements IHitable
{
    private var _damage:DamageManager;

    public function CombatPlayer(){
         _damage = new DamageManager();
    }

    public function hit(by:GameObject):void {
        _damage.calculateDamage(...);
    }
}

我将 DamageManager 的实现保持打开状态,因为我不知道您的对象是如何实现的,也不知道您想要如何计算伤害。

我认为理想情况下, DamageManager 不应直接修改您的对象。您可以传递一个 Stat 对象(保存该对象的生命值和护盾信息)以及另一个描述“击球手”属性的对象,并且 DamageManager 将返回另一个 Stat 对象,您可以使用它来更新“击球手”的统计数据。

希望它有一些意义!

Mixins are a good idea, but its support in AS3 is, well, simulated.

Option 2 will work, but exposing the instance of DamageManager breaks the encapsulation. You could solve this by adding a hit method in your IHitable interface. This method will be called by your game when something hits this object. The implementation of this method is up to the object. You could implement it differently for each object (option 1) but you could also create a generic DamageManager class and use it to calculate the damage.

class DamageManager {
    public function calculateDamage(...){
        // implement your damage logic...
    } 
}

interface IHitable {
    function hit(by:GameObject);
}

And for exemple in CombatPlayer

class CombatPlayer implements IHitable
{
    private var _damage:DamageManager;

    public function CombatPlayer(){
         _damage = new DamageManager();
    }

    public function hit(by:GameObject):void {
        _damage.calculateDamage(...);
    }
}

I've left the implementation on DamageManager open since I don't know how your objects are implemented neither how you want to calculate the damage.

I think that ideally, the DamageManager should not modify directly your object. You could pass a Stat object (which holds the object's health and shield information) along with another object describing the properties of the "hitter" and the DamageManager will return another Stat object which you can use to update the "hittee"'s stats.

Hope it makes some senses!

长亭外,古道边 2024-10-06 15:32:23

选项 1 会导致大量重复代码,而且由于显而易见的原因,这很糟糕。

选项 3 意味着所有碰撞代码都放入一个类中。从封装的角度来看,这很糟糕,因为您最终会得到一个处理所有事情的庞大类。

这使得选项 2 成为最佳选择。选项 2 比选项 3 更好,因为您可以为不同类型的飞船和小行星扩展 DamageManager 类。

不过,我还想提出一个选项 4:mixins

Mixins 是一种语言级功能,允许您向多个类添加通用功能而无需继承。尽管 ActionScript 3 语言不支持 mixins,但 AS3 足够灵活,您可以模拟它。 AS3 中的 Mixin 或 Trait 实现?

Option 1 would result in a lot of repetitive code, and that's bad for obvious reasons.

Option 3 would mean that all your collision code goes into a single class. From an encapsulation standpoint, this is bad because you'll end-up with a behemoth class that handles everything.

That leaves Option 2 as the best option. Option 2 is better than option 3 because you can extend the DamageManager class for different types of ships and asteroids.

However, I would also like to present an option 4: mixins

Mixins are a language-level feature that allow you to add common functionality to multiple classes without inheritance. Although the ActionScript 3 language doesn't support mixins, AS3 is flexible enough that you can simulate it. Mixin or Trait implementation in AS3?

梦里°也失望 2024-10-06 15:32:23

在 IHitable 接口中实现 isHitable getter 怎么样,如果您想在游戏后期对某些类进行更改,这可以提供更大的灵活性,因为对于 IHitable 实例,“is IHitable”将始终返回 true。

取决于计算的类型和对于由此产生的修改,DamageManager 并不一定是单例,您可以调用一个静态方法来处理损坏评估并返回修改后的对象。

What about implementing an isHitable getter , in the IHitable interface, this could allow more flexibility if you want to make changes in certain classes later in the game, because with a IHitable instance "is IHitable" will always return true.

Depending on the type of calculations & resulting modifications, DamageManager doesn't really have to be a Singleton, you could call a static method that would handle the damage assessment and return your modified object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文