需要使用派生类的值的基类中的switch语句

时间:2016-01-30 17:59:45

标签: c++ oop inheritance switch-statement game-physics

我目前正在使用SFML在C ++中制作自己的游戏引擎,并制作2D平台游戏。

我的游戏对象目前分为两类:

  1. Tiles:绑定到网格,以便更轻松地进行碰撞检查
  2. 实体:可以自由移动,不需要在网格中
  3. 所有实体都在指向基类Entity的指针向量中,当然还包含一些派生类,例如“CharacterEntity”。当循环遍历向量时,游戏引擎调用Entity的main函数,然后调用Entity或派生的Entity的私有函数,例如TileCollision()。

    我遇到的问题是在Entity基类的碰撞函数中。该函数接受一个指向Tile的指针,确定它是什么类型的Tile(每个Tile都有一个名为TileType的枚举类),并根据它的Tile类型进行不同的碰撞。

    void Entity::TileCollision(const Tile *pTile)
    
    {
        /// If the Tile is null
        if (pTile == nullptr)
        {
            return;
        }
        if (pTile->GetApplyCollision() == true)
        {
            sf::Vector2f tilePosition = pTile->GetPosition();
            sf::Vector2f tileDimensions = pTile->GetDimensions();
            switch (pTile->GetTileType())
            {
            case TileType::LADDERTOP:
                /// If Entity is going downwards
                if (m_speed.y >= 0) /// NEED TO ADD A CONDITION HERE
                {
                    /// Check for X-Axis overlap
                    if (m_position.x + m_dimensions.x / 2 > tilePosition.x &&
                        m_position.x - m_dimensions.x / 2 < tilePosition.x + tileDimensions.x)
                    {
                        /// If in the current tick, the Entity's bottom side is above the LadderTop, though not two Tiles above, but it will be in the next tick
                        if (m_position.y + m_dimensions.y / 2 <= tilePosition.y &&
                            m_position.y + m_dimensions.y / 2 >= tilePosition.y - m_rMap.GetTileSize() &&
                            m_position.y + m_dimensions.y / 2 + m_speed.y > tilePosition.y)
                        {
                            m_position.y = tilePosition.y - m_dimensions.y / 2;
                            m_isOnGround = true;
                            m_speed.y = 0;
                            m_moveSpeed.y = 0;
                            m_vehiculeSpeed.y = 0;
                        }
                    }
                }
                break;
            default:
                /// More collision code for other Tiles... (not relevant here)
    

    我遇到的问题是我希望Entity(或者在这种情况下,派生的Entity类,如CharacterEntity)能够在按下时通过LadderTop Tile向下移动。

    派生的CharacterEntity类具有这些变量来处理移动。

    class CharacterEntity : public Entity
    {
    protected:
        bool m_isPressingUp;
        bool m_isPressingDown;
        bool m_isPressingLeft;
        bool m_isPressingRight;
        bool m_isPressingShift;
    

    这些布尔值不仅限于确定是否按下了键,而是将CharacterEntity WANTS指向该方向。例如,AI生物在想要向左移动时会将m_isPressingLeft设置为true,但这并不一定意味着它可以,它只是意味着它将触发使其在主函数中向左移动的函数。

    现在问题是:在Entity基类的TileCollision函数中,理想情况下我需要访问布尔值,并使用这个if()子句来确定是否应用LadderTop碰撞:

    if (m_speed.y >= 0 && m_isPressingDown == false)
    

    但是,因为TileCollision位于Entity类中,而Entity类没有这些变量(因为Entity类是为不能自行移动但可以通过外部源移动的​​实体设计的,例如箭头或鹅卵石),这是行不通的。

    我该怎么做才能解决这个问题?我有一种感觉,这个问题是由于我使用switch语句处理继承时出现了更大的问题。

    我可以在CharacterEntity中创建一个派生的TileCollision()类,但这是不是意味着必须复制粘贴所有当前代码,只是为了一个不同的if()语句?有没有办法让某些东西能像衍生案例一样工作?我真的不知道,并希望得到一些建议。

    提前感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您几乎不应该打开对象的类型。添加一个虚函数(比如处理冲突)并在派生类中实现它。这样,您的逻辑可以直接写在CharacterEntity中,它已经可以访问所有必要的数据。

答案 1 :(得分:0)

  

CharacterEntities是有意愿做事的人

非常仔细地阅读:&#34; 的&#34;。现在,问自己一个问题:继承我们如何表达&#34;有一个&#34; C ++中的关系?

不,不是。继承代表&#34;是&#34;关系。存储成员变量代表&#34;有一个&#34 ;;类型&#34;有一个&#34;变量。所以你的&#34;实体有一个意志&#34;类型应该是...... Entity将。

所以你需要一些表示朝着一个方向移动的愿望(这种类型如何提供所述方向或多或少无关紧要。它可能来自AI,用户界面或其他任何东西)。并且每个Entity可能或者可能不会拥有此类内容。如果是,那么您的碰撞解决方案可以检测到(如果指针不存在,指针将为NULL)并且可以采取适当的行动。

由于您误用了语言功能,因此您已将自己设计在一个角落里。正确设计课程后,您会发现问题自行解决。

这是component-based entity systems的基础。