使用按位比较时,继承的变量无法正确读取

时间:2010-03-30 17:18:58

标签: c++ inheritance bit-manipulation

我为游戏设置了几个类,以XMapObject为基础,XEntity,XEnviron和XItem继承它。

MapObjects有许多标志,其中一个是MAPOBJECT_SOLID。我的问题是XEntity是唯一正确检测MAPOBJECT_SOLID的类。无论旗帜的状态如何,两个物品都是游戏中的环境。重要的是Environs和Item几乎不应该是实体。

每个类都有一个非常基本的初步构造函数,只是将所有变量初始化为零或NULL。在CreateX()阶段,对象链接到地图中,设置为链接的链接列表。

XItem和XEnviron都有点草率。它们都是新的,在中间或我的调试尝试。

以下是相关代码示例:

XMapObject:

#define MAPOBJECT_ACTIVE 1
#define MAPOBJECT_RENDER 2
#define MAPOBJECT_SOLID 4

class XMapObject : public XObject
{
    public:
    Uint8 MapObjectType,Location[2],MapObjectFlags;

    XMapObject *NextMapObject,*PrevMapObject;

    XMapObject();

    void CreateMapObject(Uint8 MapObjectType);
    void SpawnMapObject(Uint8 MapObjectLocation[2]);
    void RemoveMapObject();
    void DeleteMapObject();

    void MapObjectSetLocation(Uint8 Y,Uint8 X);
    void MapObjectMapLink();
    void MapObjectMapUnlink();
};

XMapObject::XMapObject()
{
    MapObjectType = 0;
    Location[0] = 0;
    Location[1] = 1;
    NextMapObject = NULL;
    PrevMapObject = NULL;
}

void XMapObject::CreateMapObject(Uint8 Type)
{
    MapObjectType = Type;
}

void XMapObject::SpawnMapObject(Uint8 MapObjectLocation[2])
{
    if(!(MapObjectFlags & MAPOBJECT_ACTIVE)) { MapObjectFlags += MAPOBJECT_ACTIVE; }

    Location[0] = MapObjectLocation[0];
    Location[1] = MapObjectLocation[1];

    MapObjectMapLink();
}

XEntity:

XEntity *StartEntity = NULL,*EndEntity = NULL;

class XEntity : public XMapObject
{
    public:
    Uint8 Health,EntityFlags;
    float Speed,Time;
    XEntity *NextEntity,*PrevEntity;
    XItem *IventoryList;

    XEntity();

    void CreateEntity(Uint8 EntityType,Uint8 EntityLocation[2]);
    void DeleteEntity();

    void EntityLink();
    void EntityUnlink();

    Uint8 MoveEntity(Uint8 YOffset,Uint8 XOffset);
};

XEntity::XEntity()
{
    Health = 0;
    Speed = 0;
    Time = 1.0;
    EntityFlags = 0;
    NextEntity = NULL;
    PrevEntity = NULL;
    IventoryList = NULL;
}

void XEntity::CreateEntity(Uint8 EntityType,Uint8 EntityLocation[2])
{
    CreateMapObject(EntityType);
    SpawnMapObject(EntityLocation);

    if(!(MapObjectFlags & MAPOBJECT_SOLID) { MapObjectFlags += MAPOBJECT_SOLID; }
    EntityFlags = ENTITY_CLIPPING;
    Time = 1.0;
    Speed = 1.0;

    EntityLink();
}

void XEntity::EntityLink()
{
    if(StartEntity == NULL)
    {
        StartEntity = this;
        PrevEntity = NULL;
        NextEntity = NULL;
    }
    else
    {
        EndEntity->NextEntity = this;
    }

    EndEntity = this;   
}

XEnviron:

class XEnviron : public XMapObject
{
    public:
    Uint8 Effect,TimeOut;

    void CreateEnviron(Uint8 Type,Uint8 Y,Uint8 X,Uint8 TimeOut);
};

void XEnviron::CreateEnviron(Uint8 EnvironType,Uint8 Y,Uint8 X,Uint8 TimeOut)
{
    CreateMapObject(EnvironType);

    Location[0] = Y;
    Location[1] = X;

    SpawnMapObject(Location);

    XTile *Tile = GetTile(Y,X);
    Tile->Environ = this;

    MapObjectFlags = MAPOBJECT_ACTIVE + MAPOBJECT_SOLID;
    printf("%i\n",MapObjectFlags);
}

XItem:

class XItem : public XMapObject
{
    public:
    void CreateItem(Uint8 Type,Uint8 Y,Uint8 X);
};

void XItem::CreateItem(Uint8 Type,Uint8 Y,Uint8 X)
{
    CreateMapObject(Type);

    Location[0] = Y;
    Location[1] = X;

    SpawnMapObject(Location);
}

最后,实体移动代码。只有实体能够自己移动。

Uint8 XEntity::MoveEntity(Uint8 YOffset,Uint8 XOffset)
{
    Uint8 
      NewY = Location[0] + YOffset,
      NewX = Location[1] + XOffset;

    if((NewY >= 0 && NewY < MAPY) && (NewX >= 0 && NewX < MAPX))
    {
        XTile *Tile = GetTile(NewY,NewX);

        if(Tile->MapList != NULL)
        {
            XMapObject *MapObject = Tile->MapList;

            while(MapObject != NULL)
            {
                if(MapObject->MapObjectFlags & MAPOBJECT_SOLID)
                {
                    printf("solid\n");
                    return 0;
                }

                MapObject = MapObject->NextMapObject;
            }
        }

        if(Tile->Flags & TILE_SOLID && EntityFlags & ENTITY_CLIPPING)
        {
            return 0;
        }

        this->MapObjectSetLocation(NewY,NewX);

        return 1;
    }

    return 0;
}

什么是奇怪的,当MapObject是Environ或Item时,按位运算符总是返回true,但它对于实体正常工作。对于调试,我使用printf“Solid”,以及包含Environs和Items的标志值的printf。

非常感谢任何帮助,因为这是我正在进行的小游戏的主要错误。我也是面向对象编程的新手,也欢迎任何提示,建议和/或批评。

3 个答案:

答案 0 :(得分:1)

您的问题似乎是您永远不会在MapObjectFlags以外的任何类中初始化XEnviron因此,作为基本类型,它在XItem中会有一个未指定的值,{{1和其他XEntity派生对象。我建议,作为XMapObject的成员,您明确地将其初始化为已知值。

通常,确保在您定义的每个构造函数的初始化列表中显式初始化基本类型的所有成员通常是个好主意。

e.g。

XMapObject

答案 1 :(得分:0)

你不能(合法地)在MapObject或Environ上调用XEntity :: MoveEntity,因为它们没有这样的方法。如果您使用static_cast将对象指针更改为XEntity,以便可以在其上调用MoveEntity,那么您实际上无法保证位操作的工作方式。在某些实现中,事物似乎可以在MoveEntity中工作,但实际发生的是它将另一个对象的内存解释为XEntity。当它试图访问它认为MapObjectFlags存在的偏移量时,它实际上并不存在并始终将该位设置为1.

答案 2 :(得分:0)

我今天早些时候发现了问题 - 它与OO编程,继承或按位没有任何关系;这是一个简单的范围错误。

问题在于,在我快速测试中获得Environ游戏时,我在控制开关序列中声明了新变量,因此下次使用任何控件时,Environ将以不可预测的方式行动。

switch(Event.key.keysym.sym)
{
    ...
    case SDLK_c: { XEnviron Environ; Environ.InitEnviron(...); }
    ...
}