簡體   English   中英

RTS游戲中對象的多態性和類層次問題

[英]Issue with polymorphism and class hierarchy for objects in RTS game

我正在用Java編寫RTS游戲並遇到了一些多態問題。 為了描述我的問題,我將在游戲中列出一些對象/類:(我將在括號內說明每個對象/類應該做什么)

  • 坦克(可以移動,可以攻擊)
  • 塔(可以攻擊)
  • 工廠(可以建坦克)
  • 樹(可以養殖)
  • 老虎(可以移動,可以攻擊,可以養殖)

在我眼中這樣做的理想方式是每個獨特能力的類別,即Movable,Attackable,Farmable,Constructible。 這是所有列出的對象具有的不同能力。 它們都是GameObject(層次結構中的最高級別,包含所有對象的公共數據)。

Movable保存用於移動物體的所有代碼(計算速度,方向,新位置等)。 Attackable持有跟蹤目標,射擊,更新射擊等的代碼。其他能力類也是如此。

所以在我看來這將是完美的:

public class Tank extends Movable, Attackable, GameObject {}
public class Tiger extends Movable, Attackable, Farmable, GameObject {}

顯然,Java不允許擴展多個類。 我不知道如何使用接口來解決我的多態性和類層次結構問題。

有任何想法嗎? 目標當然不是​​重復游戲中幾個對象共享的代碼。

MovableAttackable是對象的各種可能行為,因此它們更適合作為接口

至於這些行為的實現 - 為了解決重復代碼的問題,你可以為每個行為設置單獨的類 - 讓它們命名為服務 - 例如。 MoveServiceAttackService

然后,您可以將這些服務注入您正在創建的對象(例如, 新的Tank(myMoveService) )或將對象傳遞給這些服務,例如。 MoveService.instance()。移動(myTank)

您可以通過調用委托方法為每個類運行一些自定義代碼。

interface Movable { public void onMove(); }

class Tank implements Movable {
    public void onMove() { 
        //tank moved! 
    }
}

class MoveService {
    public void move(Movable m) {
        // do what you need to do to move
        // invoke custom code by running a delegate method
        m.onMove();
    }
}

我會建議接口和組合的組合。 這是一個工廠的例子,它使用泛型來保存一些代碼。

interface UnitFactory<U extends Unit> {
    public U newUnit();
}

abstract class UnitFactoryBuilding<U, F extends AbstractUnitFactory<U>>
extends Building // assume 'Building extends GameObject'
implements UnitFactory<U> {

    final F factory;

    UnitFactoryBuilding(F factory) {
        this.factory = factory;
    }

    MapPosition getExitPoint() {
        /* return the point for the 'door' on the model */
    }

    @Override
    public U newUnit() {
        U unit = factory.newUnit();

        /* assume Building has a method that
         * returns the player that 'owns' it
         */
        getPlayer().deductResources(unit.getResourceCost());

        return unit;
    }
}

abstract class AbstractUnitFactory<U>
implements UnitFactory<U> {
    final Building owner;

    AbstractUnitFactory(Building owner) {
        this.owner = owner;
    }

    MapPosition getPositionForNewUnit() {
        return owner.getExitPoint();
    }
}

class TankFactory
extends AbstractUnitFactory<Tank> {

    TankFactory(TankFactoryBuilding owner) {
        super(owner);
    }

    @Override
    public Tank newUnit() {
        return new Tank(getPositionForNewUnit());
    }
}

class TankFactoryBuilding
extends UnitFactoryBuilding<Tank, TankFactory> {

    TankFactoryBuilding() {
        super(new TankFactory(this));
    }
}

它有點復雜,但是類似的東西讓你可以保持你的實現分離,而不必復制大量的代碼。 創建一種新的Factory只需要編寫最后兩個類。

您不必使用泛型來做這種事情,但它使得它很方便,因為TankFactoryBuilding可以作為TankFactory訪問其factory成員。

Movable和Attackable只是屬性。

考慮一個具有“隱身”能力的單位,它在隱身時不會受到攻擊,但可能在不隱身時受到攻擊。

對象樹是關於行為的。

諸如Terrain,Unit,Building等類更有意義,因為它們具有大致相似的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM