我目前正在使用SFML在C ++中制作自己的游戏引擎,并制作2D平台游戏。
我的游戏对象目前分为两类:
所有实体都在指向基类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()语句?有没有办法让某些东西能像衍生案例一样工作?我真的不知道,并希望得到一些建议。
提前感谢您的帮助!
答案 0 :(得分:0)
您几乎不应该打开对象的类型。添加一个虚函数(比如处理冲突)并在派生类中实现它。这样,您的逻辑可以直接写在CharacterEntity
中,它已经可以访问所有必要的数据。
答案 1 :(得分:0)
CharacterEntities
是有意愿做事的人
非常仔细地阅读:&#34; 的&#34;。现在,问自己一个问题:继承我们如何表达&#34;有一个&#34; C ++中的关系?
不,不是。继承代表&#34;是&#34;关系。存储成员变量代表&#34;有一个&#34 ;;类型&#34;有一个&#34;变量。所以你的&#34;实体有一个意志&#34;类型应该是...... Entity
,有将。
所以你需要一些表示朝着一个方向移动的愿望(这种类型如何提供所述方向或多或少无关紧要。它可能来自AI,用户界面或其他任何东西)。并且每个Entity
可能或者可能不会拥有此类内容。如果是,那么您的碰撞解决方案可以检测到(如果指针不存在,指针将为NULL
)并且可以采取适当的行动。
由于您误用了语言功能,因此您已将自己设计在一个角落里。正确设计课程后,您会发现问题自行解决。