首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >崩溃,在控制台应用程序上,试图吸引敌人,超出界限(以下vid教程)

崩溃,在控制台应用程序上,试图吸引敌人,超出界限(以下vid教程)
EN

Stack Overflow用户
提问于 2011-06-19 14:54:49
回答 1查看 241关注 0票数 0

{希望改进我的帖子,请仍然建议您需要的其他代码,再次为我如此无知而感到抱歉,我决心克服这个问题,所以我真的很感谢您的时间!

**编辑:感谢Frank的回复,程序现在开始,吸引三个敌人,但仅仅几秒钟后崩溃,因此下面的程序代码仍然适用,因为它基本上是移动循环和某处仍然有问题。

我意识到这是非常模糊的,我已经尽了最大的努力来解释它,但是如果没有人能给出建议的话,那么接下来的几秒钟它就应该足够完成这个教程了,并且在它完成后会对整个项目进行剖析,并且真的试着把它分解并尽可能多地学习。**

好的,我运行这个循环来创建新的敌人,然后把它们画到屏幕上,它现在起作用了,但是几秒钟后就崩溃了。下面是调试通过的步骤和在崩溃后显示的调用堆栈。希望你能帮忙!

这是一个视频教程im跟随和im卡住,找不到答案。一遍又一遍地检查代码。(完整的代码位于文章的底部(代码块),但我已经尝试在这篇文章中包含尽可能多的信息)。

其职能是:

代码语言:javascript
复制
     level->addEnemies(3);

在主game.cpp中如下所示:

代码语言:javascript
复制
    bool Game::run(void)
    {
        level = new Level(&drawArea, 30, 20);

        drawArea.createBackgroundTile(TILE_EMPTY, ' ');
        drawArea.createBackgroundTile(TILE_WALL, 219);

        drawArea.createSprite(SPRITE_PLAYER, 1);
        drawArea.createSprite(SPRITE_ENEMY, '$');

        player = new Character(level, &drawArea, 0);

        level->draw();
        level->addPlayer(player);
        level->addEnemies(3);        <-------- SKIPS TO THIS FUNC

        char key = ' ';

        startTime = timeGetTime();
        frameCount = 0;
        lastTime = 0;

        posx = 0;

        player->move(0,0);

        while (key != 'q')
        {
            while (!getInput(&key))
            {
               timerUpdate();
            }
            level->keyPress(key);
        }
        delete player;

        return true;
    }

函数完整如下,请注意,当我从主游戏循环中删除这个addEnemies函数时,一切都运行得很好,没有崩溃,所以它与即将出现的函数有关。

代码语言:javascript
复制
    void Level::addEnemies(int num)
    {
        int i = num;

        while (i > 0)
    {
        int xpos = int(float(rand() % 100) / 100) * (width - 2) + 1;
        int ypos = int(float(rand() % 100) / 100) * (height - 2) + 1;

        if (level[xpos][ypos] != TILE_WALL)
        {
            Enemy *temp = new Enemy(this, drawArea, SPRITE_ENEMY, 
                           (float)xpos, float(ypos));

            temp->addGoal(player);

            addNPC((Sprite *)temp);

            i--;
            }
        }
    }

它似乎没有任何问题地通过了这个函数。

在此功能被退回到游戏循环并执行通过罚款,进入计时器更新没有任何问题。下面是timerUpdate函数:

代码语言:javascript
复制
    void Game::timerUpdate(void)
    {

        double currentTime = timeGetTime() - lastTime;

         if (currentTime < GAME_SPEED)
            return;

        level->update();                   <--------SKIPS TO THIS FUNC

        frameCount++;


        lastTime = timeGetTime();
    }

这是Level->Update() Func:

代码语言:javascript
复制
    void Level::update(void)
    {
    for (Iter = npc.begin(); Iter != npc.end(); Iter++)
        {
            (*Iter)->idleUpdate();      <-------------SKIPS TO THIS FUNC

            if ((*Iter)->isAlive() == false)
            {
                Sprite *temp = *Iter;
                //kill the enemy
                Iter--;
                delete temp;
                npc.remove(temp);
            }
        }
    }

idleUpdate():

代码语言:javascript
复制
    void Enemy::idleUpdate(void)
    {
        if (goal)
            simulateAI();    <------ Goes to this func
    }

simulateAI():

代码语言:javascript
复制
    void Enemy::simulateAI(void)
    {
        vector goal_pos = goal->getPosition();
        vector direction;

        direction.x = goal_pos.x - pos.x;
        direction.y = goal_pos.y - pos.y;

        float mag = sqrt(direction.x * direction.x + direction.y * direction.y);

        direction.x = direction.x / (mag);
        direction.y = direction.y / (mag);

        if (!move(direction.x, direction.y))   <------ SKIPS TO THIS FUNC
        {
            while (!move(rand() % 3 - 1, rand() % 3 - 1))
            {

            }
        }

移动功能:

代码语言:javascript
复制
    bool Sprite::move(float x, float y)
    {

        int xpos = (int)(pos.x +x);
        int ypos = (int)(pos.y +y);

        if (isValidLevelMove(xpos,ypos))      SKIPS TO THIS FUNC
        {
            //.....rest not needed

isValidMove功能:

代码语言:javascript
复制
    bool Sprite::isValidLevelMove(int xpos, int ypos)
    {
        if (level->level[xpos][ypos] != TILE_WALL)  <-------------THIS LINE CRASHES!!
            return true;

        return false;
    }

我真的不知道这是哪里出了问题,以及为什么调用stakc在xpos和ypos中显示出如此高的出界数字。

下面是完整的调用堆栈:

代码语言:javascript
复制
    #0 00402920 Sprite::isValidLevelMove (this=0x791498, xpos=-2147483648, ypos=-2147483648) (sprite.cpp:95)
    #1 00000000 0x00401750 in Enemy::move (this=0x791498, x=-nan(0x400000) (enemy.cpp:21)
    #2 00401892 Enemy::simulateAI (this=0x791498) (enemy.cpp:67)
    #3 004017E5 Enemy::idleUpdate (this=0x791498) (enemy.cpp:46)
    #4 0040226E Level::update (this=0x792e90) (level.cpp:86)
    #5 00401CB8 Game::timerUpdate (this=0x28fec0) (game.cpp:93)
    #6 00401BB5 Game::run (this=0x28fec0) (game.cpp:54)
    #7 0040258D main() (main.cpp:11)

这基本上告诉我,xpos和ypos已经从这个过程中的某个地方被肢解了,这就是造成崩溃的原因,我确信是因为它超出了从绘图引擎的宽度和高度的30 int数组的界限。

另一个编辑:

这里是雪碧类,如果有帮助的话,如果需要的话,会在更多的地方进行编辑。

代码语言:javascript
复制
    enum
    {
        SPRITE_CLASSID,
        CHARACTER_CLASSID,
        ENEMY_CLASSID
    };

    struct vector
    {
        float x;
        float y;
    };

    class Sprite
    {
    public:
        Sprite(Level *l, DrawEngine *de, int s_index, float x = 1, float y = 1, int i_lives = 1);
        ~Sprite();

        vector getPosition(void);
        float getX(void);
        float getY(void);

        virtual void addLives(int num = 1);
        int getLives(void);
        bool isAlive(void);

        virtual void idleUpdate(void);

        virtual bool move(float x, float y);

    protected:
        Level *level;
        DrawEngine *drawArea;

        vector pos;

        int spriteIndex;
        int numLives;

        int classID;

        vector facingDirection;

        void draw(float x, float y);
        void erase(float x, float y);

        bool isValidLevelMove(int xpos, int ypos);

    };

无论如何,任何帮助和我都会非常感激,我知道我必须看起来完全无用,但我决心学习,任何帮助你们可以提供将是无价之宝!

完整代码文件(代码块):http://www.mediafire.com/?5xz2seadmagbetb

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-19 15:31:14

这可能不是实际的问题,但可能是相关的。在Level::addEnemies(int num)函数中创建随机位置的代码将始终返回xposypos1

这是因为您应用转换的方式。您似乎错过了int最后一次角色的括号。我想你想要这样的东西:

代码语言:javascript
复制
int xpos = int((float(rand() % 100) / 100) * (width - 2)) + 1;

更新:

导致崩溃的代码位于您的simulateAI()函数中。通过以下方式:

代码语言:javascript
复制
float mag = sqrt(direction.x * direction.x + direction.y * direction.y);

计算两个点之间的距离,但如果这些点具有相同的坐标,则距离为0

稍后使用:direction.x = direction.x / (mag);,您将不使用这个潜在的0,因此您的坐标将包含NaN。在您的bool Sprite::move(float x, float y)函数中,您将这些NaN转换为一个int,这将给出一些未定义的数字。使用这个数字,您正在尝试访问您的数组,这将导致程序崩溃的访问冲突。

所以,首先要做的是检查一个零距离,并以不同的方式处理。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6403127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档