Collision detection of two objects against a single bullet

Started by
7 comments, last by sidbhati32 4 years, 12 months ago

Hey,

So I have got this asteroid type game and today I encountered a new issue while testing this game.

What happened was that two asteroids were close to each other and I shot a bullet at them. The asteroids were so close to each other that a single bullet could collide to both of them.

It collided and my game crashed there itself. I figured out it happened because two asteroids and one bullet collided in the same frame.

This is the code -

```void Collision::DoCollisions(Game *game) const
{
    for (ColliderList::const_iterator colliderAIt = colliders_.begin(), end = colliders_.end();
        colliderAIt != end;
        ++colliderAIt)
    {
        ColliderList::const_iterator colliderBIt = colliderAIt;
        for (++colliderBIt; colliderBIt != end; ++colliderBIt)
        {
            Collider *colliderA = *colliderAIt;
            Collider *colliderB = *colliderBIt;
            if (CollisionTest(colliderA, colliderB))
            {
                game->DoCollision(colliderA->entity, colliderB->entity);
            }
        }
    }
}```

 

```

void Game::DoCollision(GameEntity *a, GameEntity *b)
{
    Ship *player = static_cast<Ship *>(a == player_ ? a : (b == player_ ? b : 0));
    Bullet *bullet = static_cast<Bullet *>(IsBullet(a) ? a : (IsBullet(b) ? b : 0));
    Asteroid *asteroid = static_cast<Asteroid *>(IsAsteroid(a) ? a : (IsAsteroid(b) ? b : 0));
    Bullet *bulletMode = static_cast<Bullet *>(IsBulletMode(a) ? a : (IsBulletMode(b) ? b : 0));

    if (player && asteroid)
    {
        player->playerCollided = true;
        //AsteroidHit(asteroid);
        //DeletePlayer();
    }

    if (bullet && asteroid)
    {
        collidedBullets.push_back(bullet);
        collidedAsteroid.push_back(asteroid);
        //AsteroidHit(asteroid);
        //DeleteBullet();
    }

    if(bulletMode && asteroid)
    {
        collidedBulletMode.push_back(bulletMode);
        collidedAsteroid.push_back(asteroid);
    }
}```

 

```

void Game::CollisionResponse()
{
    if(player_->playerCollided == true)
    {
        DeletePlayer();
    }

    else
    {
    if(!collidedAsteroid.empty())
    {
        for(AsteroidList::const_iterator collidedAsteroidIt = collidedAsteroid.begin(), end = collidedAsteroid.end(); collidedAsteroidIt != end ; ++collidedAsteroidIt )
        {
            AsteroidHit(*collidedAsteroidIt);
        }

        collidedAsteroid.clear();
    }
    
    if(!collidedBullets.empty())
    {
    for (BulletList::const_iterator bulletIt = collidedBullets.begin(), end = collidedBullets.end() ; bulletIt!=end; ++bulletIt)
    {
        DeleteBullet(*bulletIt);
    }
    
        collidedBullets.clear();
    }

    if(!collidedBulletMode.empty())
    {
        for (BulletList::const_iterator bulletIt = collidedBulletMode.begin(), end = collidedBulletMode.end() ; bulletIt!=end; ++bulletIt)
        {
            DeleteBulletMode(*bulletIt);
        }
        collidedBulletMode.clear();
    }
}
    }```

 

 

in my game->docollision() -

whenever an asteroid and a bullet used to collide, the collided objects get collected in collidedasteroids and collidedbullets respectively. When two asteroids collided with the same bullet, the two asteroids got collected safely in collidedAsteroid but the single bullet got collected in collidedBullets twice, so when the deletion was happening, the second time iteration of the bullet couldn't find the respective bullet and it got crashed.

 

How am I supposed to approach this problem now?

 

Thanks

Advertisement

For each visible bullet check for collisions if theres collision you add data to the stack then if theres another collision with same bullet you add new col info to the stack. In other words for each visible bullet check collision against all asteroids and do whatever you do there?

Also i think using dynamic array for bullets is not the way one should ever do. Instead i would define a static array of bullets where the size is your predefined maximum if visible bullets (they surely wont exceed 100] where bullet class will hold bool visible, and you will check for which of new bullet index you want to use with


int Find_first_free()
{
for (int i=0; i < BULLET_COUNT; i++)
	if (!BULLETS[i].visible) return i;

return 0;
}

 

@_WeirdCat_

Yes, correct.

Anyways I thougt of this ->

void Game::DoCollision(GameEntity *a, GameEntity *b)
{
    Ship *player = static_cast<Ship *>(a == player_ ? a : (b == player_ ? b : 0));
    Bullet *bullet = static_cast<Bullet *>(IsBullet(a) ? a : (IsBullet(b) ? b : 0));
    Asteroid *asteroid = static_cast<Asteroid *>(IsAsteroid(a) ? a : (IsAsteroid(b) ? b : 0));
    Bullet *bulletMode = static_cast<Bullet *>(IsBulletMode(a) ? a : (IsBulletMode(b) ? b : 0));

    if (player && asteroid)
    {
        player->playerCollided = true;
        //AsteroidHit(asteroid);
        //DeletePlayer();
    }

    if (bullet && asteroid)
    {
        if(bullet->bulletCollided == false)
        {
        bullet->bulletCollided = true;
        collidedBullets.push_back(bullet);
        }

        if(asteroid->asteroidCollided == false)
        {
        asteroid->asteroidCollided = true;
        collidedAsteroid.push_back(asteroid);
        }
        //AsteroidHit(asteroid);
        //DeleteBullet();
    }

    if(bulletMode && asteroid)
    {
        if(bulletMode->bulletCollided == false)
        {
        bulletMode->bulletCollided = true;
        collidedBulletMode.push_back(bulletMode);
        }

        if(asteroid->asteroidCollided == false)
        {
        asteroid->asteroidCollided = true;
        collidedAsteroid.push_back(asteroid);
        }
    }
}

 

Would it work?

Bro I wrote many changes in this code. Take help from it, I doubt you can still solve it. Lol

2 minutes ago, sidbhati32 said:

Bro I wrote many changes in this code. Take help from it, I doubt you can still solve it. Lol

You already opened a thread regarding the same topic:

 

From what I read there you are trying to cheat a possible employee by letting others solve the test given to you. So same test still not capable of solving it?

@DerTroll @Ankit Singh I agree with you guys.

 

This code belongs to SUMO digital and this guy is posting it here publicly.

And it was five months ago. That chance has probably long faded.

 

edit: I'm with @Lactose and @Wyrframe on this one. Probably not checking/setting nullptr or #badc0de address variant.

2 hours ago, fleabay said:

Learn to program.

EDIT: This is not a troll post but an honest answer to a person who is applying for a job that requires programming skills and does't seem to have them. Changed "code" to program.

I agree with your things but the thing is about what kind of questions you ask? This guy comes up and asks me the whole solution for a part. How am I supposed to answer? I did my own research work and did changes to that code before asking it. 

Also, there were no replies on that post which means I didn't get help here but I was still able to solve the answers. 

An offline test means you can use the net but this doesn't mean to come up with the whole damn question. I did my work before. 

The guy who reported the issue made a new account and tried to pull my ass off when I wasn't able to help him? That's called time death. Should have used to do more research. 

 

Thanks anyways

This topic is closed to new replies.

Advertisement