Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Asteroids: Bullets not working as intended.  (Read 1851 times)

0 Members and 1 Guest are viewing this topic.

Jycerian

  • Newbie
  • *
  • Posts: 49
  • Weakness of attitude becomes weakness of character
    • View Profile
Asteroids: Bullets not working as intended.
« on: April 15, 2014, 11:16:52 am »
PROBLEM1: Image not showing, shows white area instead.
PROBLEM2: Game lags really hard when you keep shooting. (probably due to loading the image over and over every new bullet, no clue how to fix)


Can anyone help me with these problems? This is the first time I try to do something with bullets and really have no clue on how to exactly fix this. If you take the time to reply to my topic please keep in mind I am a beginner so please use a language that a beginner will understand, Thank you in advance.



bullet.h
class Bullet: public sf::Drawable {
        static const float lifetime;
        static const float speed;

        public:
                Bullet(sf::Vector2f position, float angle);
                ~Bullet();

                bool isAlive();
                void kill();
                void update(float frametime);
                void draw(sf::RenderTarget& target, sf::RenderStates states) const;
               

        private:
                bool is_alive;
                float remaining_life;
                sf::Vector2f direction;
                sf::Texture bulletTex;
                sf::Sprite bulletSprite;
};

bullet.cpp
const float Bullet::lifetime = 1000.f;
const float Bullet::speed = 0.9f;

Bullet::Bullet(sf::Vector2f position, float angle):
        is_alive(true),
        remaining_life(lifetime),
        direction(cos(angle * DEG2RAD), sin (angle * DEG2RAD)) {
        bulletTex.loadFromFile("Assets/Images/bullet.png");
        bulletSprite.setTexture(bulletTex);
        bulletSprite.setPosition(position);
}

Bullet::~Bullet() {
}

bool Bullet::isAlive() {
        return is_alive;
}

void Bullet::update(float frametime) {
        if (!is_alive) return;

        remaining_life -= frametime;
        if (remaining_life <= 0) is_alive = false;

        sf::Vector2f distance = direction * speed * frametime;
        bulletSprite.move(distance);
}

void Bullet::draw(sf::RenderTarget& target, sf::RenderStates states) const {
        target.draw(bulletSprite);
}

void Bullet::kill() {
        is_alive = false;
}

level.h
class Level {
        public:
                Level();
                ~Level();
                void onEvent(const sf::Event& event);
                void update(float frametime);
                void draw(sf::RenderTarget& target);
                void start();

        private:
                Background background;
                Spaceship ship;

                std::vector<Bullet> bullets;
};

level.cpp
void Level::onEvent(const sf::Event& event) {
        ship.onEvent(event);

        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
                Bullet bullet(ship.spaceshipSprite.getPosition(), ship.spaceshipSprite.getRotation());
                bullets.push_back(bullet);
        }
}

void Level::update(float frametime) {
        ship.update(frametime);

        std::vector<Bullet>::iterator start_bullets = bullets.begin();
        while (start_bullets != bullets.end()) {
                if (start_bullets->isAlive()) {
                        start_bullets->update(frametime);
                        ++start_bullets;
                } else
                        start_bullets = bullets.erase(start_bullets);
        }
}

void Level::draw(sf::RenderTarget& target) {
        target.draw(background);
        target.draw(ship);

        for(std::vector<Bullet>::iterator it = bullets.begin(); it != bullets.end(); ++it)
                target.draw(*it);
}

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Asteroids: Bullets not working as intended.
« Reply #1 on: April 15, 2014, 11:24:13 am »
PROBLEM1: Image not showing, shows white area instead.
When you push_back the bullet, the location of the bullet including the texture in memory changes, thus invalidating the sprites's pointer, i.e. it points to the old location of the texture.

PROBLEM2: Game lags really hard when you keep shooting. (probably due to loading the image over and over every new bullet, no clue how to fix)
To fix both problems at once, you should use a resource manager and load the textures only once and then pass it as reference to each bullet or other object.

The ResourceHolder of the SFML Game Development book could interest you.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/