# BulletManager, reflection from walls

This topic is 1517 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello everybody! I'm trying to solve test task:

Given a list of segments (walls) , given the coordinates of two points on a two-dimensional space . Need to write a class BulletManager, which will include the following functions:

• void Update (float time), where time - global time of update in seconds. Function calculates the trajectory of bullets at a specified time and in contact with the wall, remove it from the list of segments . While hitting the wall, the bullet is reflected.
• void Fire (float2 pos, float2 dir, float speed, float time, float life_time), where pos - the starting position of the bullet in meters , dir - direction , speed - speed in meters per second , time - the shot in seconds , life_time - time to self-destruction bullets . This function adds a bullet in manager for further processing by an update .

Sorry for my English, the text above is google-translated.

I've made it, all is good, except of reflextion: bullet reflects, but not always correctly. Here is my function:

void BulletManager::Update(float time)
{
for (int n = 0; n < bullets.size();)
{
auto bul = bullets.begin() + n;
XMFLOAT2* bulDir = &bul->get()->GetDir();

float x = bul->get()->GetInitPosition().x + (bulDir->x * (time - bul->get()->GetTime()) * bul->get()->GetSpeed());
float y = bul->get()->GetInitPosition().y + (bulDir->y * (time - bul->get()->GetTime()) * bul->get()->GetSpeed());
XMFLOAT2 point = XMFLOAT2(x, y);
bul->get()->SetPosition(point);

//Check bullet life time
if (bul->get()->GetLifeTime() - (time - bul->get()->GetTime()) <= 0.0f)
{
bullets.erase(bul);
n--;
continue;
}

//Check, if bullet collides with sides
for (int i=0; i<SidesCoordList.size(); i++)
{
if ( IsIntersecting(SidesCoordList[i], point, 1.0f) )
{
//Calculating normal vector for current side
float A = abs(SidesCoordList[i].point1.y - SidesCoordList[i].point2.y);
float B = abs(SidesCoordList[i].point2.x - SidesCoordList[i].point1.x);
XMFLOAT2 normal = XMFLOAT2(A, B);
normal = XMFLOAT2(normal.x / Calculations::VecLength(normal), normal.y / Calculations::VecLength(normal));

//Calculating angles to get reflected directional vector
float alpha = atan(A/B);
float beta = acos(bulDir->x);
float gamma = XM_PIDIV2 - (alpha - beta);
float theta = beta + 2*gamma + XM_PI;

//Setting new direction (after reflection)
bul->get()->GetDir() = Calculations::RotateVector(bul->get()->GetDir(), theta);

bul->get()->GetInitPosition() = bul->get()->GetPosition();
bul->get()->GetTime() = time;
}
}
n++;
}
}


What's wrong with my code?

Thanks.

##### Share on other sites

It looks like you're repeating some work when you erase bullets. Since your n++ is at the end of your for loop's contents, the flow is something like this for a size 3 list where the 2nd bullet is too old.

* do bullet[0] work;

* bullet[1] is too old, erase him, --i;

* do bullet[0] work again

* do bullet[1] work (originally bullet[2]);

So you might wind up doing the reflection logic twice, or move twice as fast "skipping" a frame.

And in you're sets at the end, you're using get functions which is weird to me.

// earlier in your code you use this to set position
bul->get()->SetPosition(point);

// Then later in your code you're setting with code like this:
bul->get()->GetTime() = time;


I didn't check the math of your reflection code yet. I'm on vacation! :) Make sure y is going the direction you think it should. By default in drawing, +y is down the screen, but in math +y is up.

If this didn't help, what is the problem you're seeing in you're reflection?

- Eck

##### Share on other sites

It looks like you're repeating some work when you erase bullets

Yeah, I didn't point that. Thanks, I've corrected.

you're using get functions which is weird to me
I store my bullet as smart pointer in vector: vector<shared_ptr<Bullet>>, and I use common get() function: http://www.cplusplus.com/reference/memory/shared_ptr/get/

By default in drawing, +y is down the screen, but in math +y is up
I know, but I use Left-Handed coordinate system, where +y is up. By the way, if I replace my reflection code with function from xnamath.h
XMVector2Reflect(vecBulDir, vecNormal)


all works correctly. But my task is to write my own reflection

##### Share on other sites
If you want a more stable loop in which you will need to delete things, use this:
for (int n = bullets.size(); --n >= 0;)
Then you can avoid hacky n-- code in the loop body, plus it’s faster too.

Also, I’ve recently just explained why std::shared_ptr is bad for your health.  You should drop it and find an alternative or write your own game-friendly shared pointer.

Finally, a reflection vector.
Given an Incident vector I (the direction of the bullet) and the Normal vector N, a Reflect function can be made as follows:

VECTOR Reflect( const VECTOR & I, const VECTOR N ) {
return I - 2.0f * dot( N, I ) * N;
}
This is exactly the same as calling XMVector2Reflect(), so if XMVector2Reflect( vecBulDir, vecNormal ) works, Reflect( vecBulDir, vecNormal ) works.

L. Spiro Edited by L. Spiro

##### Share on other sites

L. Spiro, thanks! Now reflection works fine. Interesting and useful story about shared_ptr