开发者

Crash, on Console Application, trying to draw enemies, out of bounds (following vid tutorial)

开发者 https://www.devze.com 2023-03-14 10:05 出处:网络
{Hopefully improved my post, please still suggest any other code you need, and once again im sorry for being so clueless, im determined to get past this problem thoughso i truly appreciate your time!!

{Hopefully improved my post, please still suggest any other code you need, and once again im sorry for being so clueless, im determined to get past this problem though so i truly appreciate your time!!!}

**EDIT: thanks to Frank with his reply below, the program now starts and draws the three enemies, but just a few second later crashes, the program code below therefore is still applicable as its basically the move loop and somewhere in there something is still going wrong.

I realise this is extremely obscure and i have tried my best to explain it, but if noone can advise then the few second its up should be enough to complete the tutorial anyway and ill dissect the whole project after its finished and really try and break it down and learn as much as possible.**

Okay, so I run this loop designed to create new enemies, and then draw them onto the screen, it now works, but after a few second crashes. below is the steps the debugging goes through and the call stack at the end if what it displayed after the crash. hope you can help!

this is a video tutorial im following and im stuck, cant find the answer. checked the code over and over again. (the full code is at the bottom of the post (codeblocks,) but i have tried to include as much info as possible in this post)

the function is:

level->addEnemies(3);

which looks like in the main game.cpp:

    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;
    }

the function in full is below, note that when i remove this addEnemies function from the main game loop everything runs perfectly fine with no crash, so it has something to do with the upcoming functions.

    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--;
            }
        }
    }

It gets through this function without any problems it seems.

After this function is goes back to the game loops and executes through fine, goes into timer update without any problems. Here is the timerUpdate function:

    void Game::timerUpdate(void)
    {

        double currentTime = timeGetTime() - lastTime;

         if (currentTime < GAME_SPEED)
            return;

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

        frameCount++;


        lastTime = timeGetTime();
    }

This is the Level->Update() Func:

    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():

    void Enemy::idleUpdate(void)
    {
        if (goal)
            simulateAI();    <------ Goes to this func
    }

simulateAI():

    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))
            {

            }
        }

move function:

    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 func:

    bool Sprite::isValidLevelMove(int xpos, int ypos)
    {
        if (level->level[xpos][ypos] != TILE_WALL)  <-------------THIS LINE CRASHES!!
            return true;

        return false;
    }

I really cant figure out where this goes wrong, and why at the end the call stakc shows such high out of bounds numbers for xpos adn ypos.

Here is the full call stack:

    #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)

which basically tells me xpos and ypos have been mutilated from somehere in thsi proccess and thats causeing the crash im sure because i开发者_开发知识库ts way out of bounds from the [30][20] int array of the width and height of the drawengine.

ANOTHER EDIT:

Here is the Sprite class, if it helps, will edit in more if needed.

    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);

    };

anyway any help and i would be sooooo grateful, i know i must seem totally useless, but i rteally am determined to learn, and any help you guys can provide would be priceless!!!!

full code file (codeblocks) : http://www.mediafire.com/?5xz2seadmagbetb


This might not be the actual problem, but could be related. Your code to create a random position within your Level::addEnemies(int num) function will always return 1 for xpos and ypos.

This is because of the way you apply the casts. You seem to miss parenthesis for your final cast to int. I think you want something like this:

int xpos = int((float(rand() % 100) / 100) * (width - 2)) + 1;

Update:

The code causing the crash is located in your simulateAI() function. With:

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

You calculate the distance between two points, but if the points have the same coordinates, the distance is 0.

Later with: direction.x = direction.x / (mag); you devide by this potential 0 and as a result your coordinates will contain NaN. Within your bool Sprite::move(float x, float y) function you cast these NaNs into an int which will give you some undefined number. With this number you are trying to access your array which will lead to the access violation that crashes your program.

So first thing to do is to check for a zero distance and handle that differently.

0

精彩评论

暂无评论...
验证码 换一张
取 消