Hello.
I previously had a static array where i entered the max amount of bullets as the size of array, for example 100. But i guess this isn't such a good approach for many things where the array size varies, so i heard vectors were a good option instead of arrays because you don't need to memory manage them like with a dynamic array.
But now i need some help in how i'm supposed to use the vector. This is what i have so far. it crashes when it goes into the function newBullet. The problem right now is that the bullet will not be affected by the box2d world. Gravity for example wont affect it.
struct sBox{
b2BodyDef myBodyDef;
b2Body* body;
b2PolygonShape boxShape;
b2FixtureDef boxFixtureDef;
sf::RectangleShape Rect;
};
struct sBullet{
int airTime;
sf::Vector2f targetVector;
float toTargetAngle;
float speed;
sBox box;
sf::Sprite Sprite;
};
struct sCharacter{
std::vector<sBullet> bullet;
sf::Vector2f targetVector;
float toTargetAngle;
int castTime;
float degreeAngle;;
int bulletCooldown;
};
sCharacter character;
void newBullet(sCharacter *character, int PPM, b2World *world, sf::Texture *Texture, sf::Vector2i worldMouseClick, sf::Vector2f position, sf::Vector2f boxSize){
sBullet bullet;
character->bullet.push_back(bullet); //+1 to array
//Calculate bullet path and angle
character->bullet.back().targetVector.x = worldMouseClick.x - position.x;
character->bullet.back().targetVector.y = worldMouseClick.y - position.y;
character->bullet.back().toTargetAngle = atan2(character->bullet.back().targetVector.y, character->bullet.back().targetVector.x);
//Bullet duration and cooldown
character->bullet.back().airTime = 500;
character->bulletCooldown = 20;
//Set box2d value + spawn body
character->bullet.back().box.myBodyDef.type = b2_kinematicBody; //this will be a kinematic body
character->bullet.back().box.myBodyDef.position.Set(position.x/PPM, position.y/PPM); //set the starting position
character->bullet.back().box.myBodyDef.angle = 0; //set the starting angle
character->bullet.back().box.body = world->CreateBody(&character->bullet.back().box.myBodyDef);
character->bullet.back().box.boxShape.SetAsBox(boxSize.x/PPM/2, boxSize.y/PPM/2);
character->bullet.back().box.boxFixtureDef.shape = &character->bullet.back().box.boxShape;
character->bullet.back().box.boxFixtureDef.density = 1;
character->bullet.back().box.body->CreateFixture(&character->bullet.back().box.boxFixtureDef);
character->bullet.back().box.body->SetActive(true);
//Set bullet sprite
character->bullet.back().Sprite.setTexture(Texture[9]);
character->bullet.back().Sprite.setOrigin(character->bullet.back().Sprite.getLocalBounds().width -20, character->bullet.back().Sprite.getLocalBounds().height / 2);
};
int main(int argc, char** argv){
b2Vec2 gravity(0, 0); //normal earth gravity, 9.8 m/s/s straight down!
b2World* world = new b2World(gravity);
world->SetAllowSleeping(true);
//Bullet Cast time
if (character.castTime >= 0){
character.castTime -= 1;
}
//Bullet Cooldown
if (character.bulletCooldown > 0){
character.bulletCooldown -= 1;
}
//Start bullet cast
if (mouseOnInventory == false && itemMousePos == -1 && itemOnMouse == -1 && leftButtonDown == 1 && character.castTime == -1 && character.bulletCooldown == 0 && character.currentMana >= character.bullet[0].manaCost){
worldMouseClick = worldMouse; //Save click pos
character.castTime = 20;
character.currentMana -= character.bullet[0].manaCost;
//Set only character angle
character.targetVector.x = worldMouseClick.x - Character.getPosition().x;
character.targetVector.y = worldMouseClick.y - Character.getPosition().y;
character.toTargetAngle = atan2(character.targetVector.y, character.targetVector.x);
character.degreeAngle = character.toTargetAngle * 180 / PI;
}
//Fire bullet
if (character.castTime == 0){
newBullet(&character, PPM, world, Texture, worldMouseClick, Character.getPosition(), sf::Vector2f(40, 40));
character.bullet.back().box.body->SetTransform(b2Vec2(Character.getPosition().x/PPM, Character.getPosition().y/PPM), character.bullet.back().toTargetAngle);
}
//Set bullet pos
for (int i = 0; i < character.bullet.size(); i++){
character.bullet[i].box.body->SetLinearVelocity(b2Vec2(cos(character.bullet[i].toTargetAngle)*character.bullet[0].speed, sin(character.bullet[i].toTargetAngle)*character.bullet[0].speed));
}
//Remove bullet after a certain time
for (int i = 0; i < character.bullet.size(); i++){
if (character.bullet[i].airTime > 0)
character.bullet[i].airTime -= 1;
else{
character.bullet[i].box.body->SetActive(false);
character.bullet.erase(character.bullet.begin() + i-1);
}
}
//Box2d
float32 timeStep = 1/60.0; //the length of time passed to simulate (seconds)
int32 velocityIterations = 10; //how strongly to correct velocity
int32 positionIterations = 6; //how strongly to correct position
//Update world. This needs to come after you set positions and before you try to get current positions values.
world->Step(timeStep, velocityIterations, positionIterations);
//Set positon of sprites.
for (int i = 0; i < character.bullet.size(); i++){
character.bullet[i].Sprite.setPosition(character.bullet[i].box.body->GetPosition().x*PPM, character.bullet[i].box.body->GetPosition().y*PPM);
character.bullet[i].Sprite.setRotation(character.bullet[i].box.body->GetAngle()*RADTODEG);
}
}