簡體   English   中英

對向量感到困惑<type*>迭代器

[英]Confused about Vector<type*> iterator

我有一個具有虛擬update功能的基類cGameObject 我希望有許多派生的游戲對象,每個對象都有自己特定的update功能。

我想將派生的游戲對象添加到向量中並遍歷它們以調用它們的每個更新方法。

我的迭代器有什么問題?

//In Header file
std::vector <cGameObject*> vGameObjs;
std::vector <cGameObject*>::iterator Iter;
cGameObject *AGameObj;

/In cpp file - add object pointer to vector
AGameObj = new BrickBat(128, 32, (1024 - 128) / 2, 768 - 64, 0);
vGameObjs.push_back(AGameObj);
AGameObj = new BrickBall(64, 512, 384, 1, 1, 0);
vGameObjs.push_back(AGameObj);

//Iterator Crashing??
for (Iter = vGameObjs.begin(); Iter != vGameObjs.end(); ++Iter)
{
    //Call Each Objects Update() method here?
    }

當我運行它時,它拋出一個異常:讀取訪問沖突。 _Mycont 是 nullptr。

不知道該怎么辦。

類 App Class 的 Header拋出的錯誤

#ifndef _H_AGK_TEMPLATE_
#define _H_AGK_TEMPLATE_

// Link to GDK libraries
#include "AGK.h"
#include "Brickbat.h"
#include "BrickBall.h"
#include "cGameObject.h"
#include <vector>

#define DEVICE_WIDTH 1024
#define DEVICE_HEIGHT 768
#define DEVICE_POS_X 32
#define DEVICE_POS_Y 32
#define FULLSCREEN false

// used to make a more unique folder for the write path
#define COMPANY_NAME "BitMaNip:Play"

// Global values for the app
class app
{
    public:

        // constructor
        app() { memset ( this, 0, sizeof(app)); }

        // main app functions - mike to experiment with a derived class for this..
        void Begin( void );
        int Loop( void );
        void End( void );

    private:
        //Vector of GameObject Pointers;
        std::vector <cGameObject*> vGameObjs;
        //Iterator of GameObjects
        std::vector <cGameObject*>::iterator Iter;


        BrickBat *MyBat;
        BrickBall *MyBall;

        cGameObject *AGameObj;


};

extern app App;

#endif

// Allow us to use the LoadImage function name
#ifdef LoadImage
 #undef LoadImage
#endif

Header 的 cpp 文件 // 包括 #include "template.h" #include "cGameObject.h" #include

// Namespace
using namespace AGK;

app App;

void app::Begin(void)
{
    agk::SetVirtualResolution (DEVICE_WIDTH, DEVICE_HEIGHT);
    agk::SetClearColor( 151,170,204 ); // light blue
    agk::SetSyncRate(60,0);
    agk::SetScissor(0,0,0,0);

    //Test
    /*BrickBall = agk::CreateSprite(0);
    agk::SetSpriteSize(BrickBall, 64, 64);
    agk::SetSpriteColor(BrickBall, 255, 255, 255, 255);
    xPos = (DEVICE_WIDTH - 64) / 2;
    yPos = (DEVICE_HEIGHT - 64) / 2;
    agk::SetSpritePosition(BrickBall, xPos , yPos  );
    xDir = 1;
    yDir = 1;
    iSpeed = 8;*/



    MyBat = new BrickBat(128, 32, (1024-128)/2, 768-64, 0);

    AGameObj = new BrickBat(128, 32, (1024 - 128) / 2, 768 - 64, 0);
    vGameObjs.push_back(AGameObj);

    MyBall = new BrickBall(64, 512, 384, 1, 1, 0);

    AGameObj = new BrickBall(64, 512, 384, 1, 1, 0);
    vGameObjs.push_back(AGameObj);

}

int app::Loop (void)
{
    agk::Print( agk::ScreenFPS() );

    if (agk::GetRawKeyState(37) == 1)
    {
        MyBat->MoveLeft();
    }

    if (agk::GetRawKeyState(39) == 1)
    {
        MyBat->MoveRight();
    }

    MyBat->Update();
    MyBall->Update();
    MyBall->Collided(MyBat->iGetBatID());


    for (Iter = vGameObjs.begin(); Iter != vGameObjs.end(); ++Iter)
    {
        //(*Iter)->Update();
        //(*Iter)->Collided(MyBat->iGetBatID());
    }

派生類

包括“cGameObject.h”

類磚塊:公共 cGameObject { 私有:

bool bHoriDir;
bool bVertDir;
int iSpeed;
bool bPause;    //in case game is paused

公共:BrickBall(int iSize,int xPos,int yPos,bool bHori,bool bVert,int ImageID); 虛擬無效更新()覆蓋; 虛擬無效碰撞(int OtherSpriteToCheck)覆蓋; };

    agk::Sync();

    return 0; // return 1 to close app
}


void app::End (void)
{

}

基類:

#pragma once
class cGameObject
{
protected:
    bool bInit = false;
    int iSprID;
    int iImageID;
    int iXPos;
    int iYPos;
    int iAngle;
    int iAlpha;
    int iWidth;
    int iHeight;
    int iColour;

    //Movement
    float fDeltaX;
    float fDeltaY;

    //Animation
    int iAniType;   //Type of animation
                    //0 = No Animation
                    //1 = Repeating Loop of Frames (All image is animation)
                    //2 = 

    int iFrameW;        //Width of Animation Frame
    int iFrameH;        //Height of Animation frame
    int iFPS;       //Animation Delay
    int iNumFrames; //Number of animation frames
    int iAniCount;  //Frame Counter

public:
    // set up default for constructor
    cGameObject(int width = 16, int height = 16, int xPos = 0, int yPos = 0, int ImageID = 0);

    void SetPosition(int ixPos, int iyPos);
    void SetSize(int iWidth, int iHeight);
    void SetWidth(int Width);
    void SetAngle(int iAngle);
    void SetTransparency(int iAlpha);
    void SetAnimation(int Type, int FrameW, int FrameH, int FPS, int NumFrames);

    virtual void Collided(int OtherSpriteToCheck) {};

    virtual void Update() {};

    int iGetWidth();
    int iGetHeight();
    int iGetX();
    int iGetY();
    int iGetSprID();

    ~cGameObject();
};

基類 cpp

    #include "cGameObject.h"
#include "agk.h"


void cGameObject::SetAngle(int iAngle)
{
    if (bInit == true)
    {
        if (iAngle > 0 && iAngle < 359)
        {
            agk::SetSpriteAngle(iSprID, iAngle);
        }
    }
}

//cGameObject::cGameObject(int width, int height, int xPos, int yPos, const char * szImageFile)
cGameObject::cGameObject(int width, int height, int xPos, int yPos, int ImageID)
{
    bInit = true;
    iImageID = 0;
    /*if (std::strlen(szImageFile) > 0)
    {
        iImageID = agk::LoadImage(szImageFile);
        if (iImageID < 1)
        {
            bInit = false;
        }
    }*/
    iColour = agk::MakeColor(255, 255, 255);

    //init animation code
    iAniType = 0;   //Type of animation
    iFrameW = 64;       //Width of Animation Frame
    iFrameH = 64;       //Height of Animation frame
    iFPS = 10;      //Animation Delay
    iNumFrames = 1; //Number of animation frames
    iAniCount = 0;  //Frame Counter


    iSprID = agk::CreateSprite(iImageID);
    if (iSprID < 1)
    {
        bInit = false;
    }
    else
    {
        agk::SetSpriteSize(iSprID, width, height);
        agk::SetSpritePosition(iSprID, xPos, yPos);
        fDeltaX = 4.0;
        fDeltaY = 4.0;

    }

}



void cGameObject::SetPosition(int ixPos, int iyPos)
{
    if (bInit == true)
    {
        agk::SetSpritePosition(iSprID, ixPos, iyPos);
    }
}

void cGameObject::SetSize(int iWidth, int iHeight)
{
    if (bInit == true)
    {
        if (iWidth > 0 && iWidth < 1024 && iHeight > 0 && iHeight < 1024)
        {
            agk::SetSpriteSize(iSprID, iWidth, iHeight);
        }
    }
}

void cGameObject::SetWidth(int Width)
{
    if (bInit == true)
    {
        agk::GetSpriteWidth(Width);
    }
}

void cGameObject::SetTransparency(int iAlpha)
{
    if (bInit == true)
    {
        if (iAlpha > 0 && iAlpha < 256)
        {
            agk::SetSpriteTransparency(iSprID, iAlpha);
        }
    }
}

void cGameObject::SetAnimation(int Type, int FrameW, int FrameH, int FPS, int NumFrames)
{
    //Animation
    iAniType = Type;
    iFrameW = FrameW;       //Width of Animation Frame
    iFrameH = FrameH;       //Height of Animation frame
    iFPS = FPS;             //Animation Delay
    iNumFrames = NumFrames; //Number of animation frames
    iAniCount = 0;          //Frame Counter

    agk::SetSpriteAnimation(iSprID, iFrameW, iFrameH, iNumFrames);

    if (iAniType > 0)
    {
        agk::PlaySprite(iSprID, iFPS);
    }
}


int cGameObject::iGetWidth()
{
    if (bInit == true)
    {
        return agk::GetSpriteWidth(iSprID);
    }
    else
    {
        return 0;
    }
}

int cGameObject::iGetHeight()
{
    if (bInit == true)
    {
        return agk::GetSpriteHeight(iSprID);
    }
    else
    {
        return 0;
    }
}

int cGameObject::iGetX()
{
    if (bInit == true)
    {
        return agk::GetSpriteX(iSprID);
    }
    else
    {
        return 0;
    }
}

int cGameObject::iGetY()
{
    if (bInit == true)
    {
        return agk::GetSpriteY(iSprID);
    }
    else
    {
        return 0;
    }
}

int cGameObject::iGetSprID()
{
    if (bInit == true)
    {
        return iSprID;
    }
    else
    {
        return 0;
    }
}

cGameObject::~cGameObject()
{
    if (bInit == true)
    {
        agk::DeleteSprite(iSprID); 
    }
}

派生類頭:

#include "cGameObject.h"

class BrickBall: public cGameObject
{
private:

    bool bHoriDir;
    bool bVertDir;
    int iSpeed;
    bool bPause;    //in case game is paused


public:
    BrickBall(int iSize, int xPos, int yPos, bool bHori, bool bVert, int ImageID);
    virtual void Update() override;
    virtual void Collided(int OtherSpriteToCheck) override;
};

派生類 cpp

#include "BrickBall.h"

BrickBall::BrickBall(int Size, int xPos, int yPos, bool bHori, bool bVert, int ImageID):cGameObject(Size, Size, xPos, yPos, ImageID)
{
    iWidth = Size;
    iHeight = Size;
    iXPos = xPos;
    iYPos = yPos;
    bHoriDir = bHori;
    bVertDir = bVert;
    /*iSprID = agk::CreateSprite(0);
    agk::SetSpriteColor(iSprIdx, 255, 255, 255, 255);
    //agk::SetSpriteSize(iSprIdx, iSize, iSize);
    agk::SetSpriteSize(iSprIdx, 64, 64);
    //agk::SetSpritePosition(iSprIdx, ixPos, iyPos);
    agk::SetSpritePosition(iSprIdx, ixPos, iyPos);
    bInit = true;*/
    iSpeed = 8;

}

void BrickBall::Update()
{
    if (bInit==true)// && BatID > 0)
    {
        //Move Ball
        agk::SetSpriteColor(iSprID, 100, 100, 100, 255);

        agk::PrintC("BallX:");
        agk::Print(iXPos);

        if (bHoriDir == 1)  //Right
        {
            iXPos = iXPos + iSpeed;
            if (iXPos > 1024 - iWidth)
            {
                bHoriDir = 0;
            }
        }
        else
        {
            iXPos = iXPos - iSpeed;
            if (iXPos < 0)
            {
                bHoriDir = 1;
            }
        }

        if (bVertDir == 1)  //down
        {
            iYPos = iYPos + iSpeed;
            if (iYPos > 768 - 64)
            {
                bVertDir = 0;
            }
        }
        else
        {
            iYPos = iYPos - iSpeed;
            if (iYPos < 0)
            {
                bVertDir = 1;
            }
        }

        agk::SetSpritePosition(iSprID, iXPos, iYPos);

        //END Move Ball
        //Bat2Ball Collisions
        /*if (agk::GetSpriteCollision(iSprID, BatID))
        {
            //We have collided. 
            //As Ball is bigger than the gap below the bat must have hit top or sides
            //so just flip the vertcal direction
            if (bVertDir == 1)
            {
                bVertDir = 0;
            }
        }*/
    }

}

void BrickBall::Collided(int OtherSpriteToCheck)
{
    if (agk::GetSpriteCollision(iSprID, OtherSpriteToCheck))
    {
        if (bVertDir == 1)
        {
            bVertDir = 0;
        }
    }
}

我不知道您的錯誤的原因,但我得到了這個確切的錯誤,因為我有一個指向向量的迭代器,然后我更新了向量,然后我嘗試取消引用迭代器(例如訪問 *myIterator)。 我是 C++ 的新手,但似乎如果在獲得迭代器后更改集合,則迭代器不再有效。 您需要將迭代器重新指向它所在的位置。

暫無
暫無

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

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