2 Replies - 443 Views - Last Post: 27 May 2018 - 06:17 PM Rate Topic: -----

#1 Bihar Shooter   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 39
  • Joined: 13-February 18

i shoot once , but more than 1 bullet gets created {SFML ,C++}

Posted 22 May 2018 - 04:03 PM

when player is stationary only 1 bullet gets created by one shot
but when the player is in motion more than 1 bullet gets created by 1 shot
many times when the player is moving and i shoot whilst in motion 7 bullets get created by 1 shot

Here is the code -
Main.cpp
#include <SFML/Graphics.hpp>
#include <SFML/window.hpp>
#include <SFML/System.hpp>

#include <Player.h>

int main()
{
    sf::RenderWindow window(sf::VideoMode(1336,768), "Project Asteroid");

    Player ship(1336,768);

    sf::Clock clock;

    float deltaTime;
    while (window.isOpen())
    {
        sf::Time dt = clock.restart();
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();

            ship.Shooting();
        }

        ship.Update();

        deltaTime = dt.asSeconds();
        ship.GetInput(deltaTime);

        ship.MoveAllBullets(deltaTime * 100);
        ship.CheckAllBulletLifetime();
        ship.DestroyAllBullets();

        ship.NoOfBullets();

        window.clear();
        window.draw(ship.DisplayPlayer());
        for(int i=0;i<ship.noOfBullets;i++)
        {
            window.draw(ship.DisplayBullet(i));
        }
        window.display();
    }

    return 0;
}

 


Player.hpp
 
#ifndef PLAYER_H
#define PLAYER_H

#include <SFML/Graphics.hpp>
#include <SFML/window.hpp>
#include <SFML/System.hpp>

#include <iostream>

#include <vector>
#include <Bullet.h>
class Player
{
    private:
    sf::Vector2f PlayerPos ;                    /*Temporary variable to be used instead of playerSprite.getPosition()*/
    sf::Texture PlayerTexture ;
    sf::Sprite PlayerSprite ;

    std::vector<Bullet>bullets ;
    int k;
    bool shot ;
    public:

    int noOfBullets;
    public:

        Player(float WindowX ,float WindowY);
        void GetInput (float dt);                      /*float dt for deltaTime to smooth out the movement and same fps*/

        void Shooting ();                              /*handling shooting , if button is pressed , bullets.push_back(bullet)*/
        void MoveAllBullets (float dt);
        inline void CheckAllBulletLifetime ()
        {
            for(int i =0;i<noOfBullets;i++)
            {
                bullets[i].DestroyBullet();
            }
        }
        void DestroyAllBullets ();
        sf::Sprite DisplayBullet (int );

        void Update();

        sf::Sprite DisplayPlayer ();
        virtual ~Player();

    //Console Functions :-

        inline void NoOfBullets()
        {
            std::cout<<"No. of Bullets not Destroyed - "<<bullets.size()<<std::endl;

        }
};

#endif // PLAYER_H

 


Player.cpp
 
#include "Player.h"

Player::Player(float WindowX,float WindowY)
{
    Player::PlayerTexture.loadFromFile("textures/ship.png");
    Player::PlayerSprite.setTexture(Player::PlayerTexture);
    Player::PlayerSprite.setPosition(WindowX/2 , WindowY - 80);

    Player::PlayerSprite.setScale(0.13,0.13);
    Player::PlayerSprite.setOrigin(Player::PlayerTexture.getSize().x /2 ,Player::PlayerTexture.getSize().y/2);

    Player::k = 0;

    Player::shot = false;
    //ctor
}

sf::Sprite Player::DisplayPlayer()
{
    return Player::PlayerSprite;
}

void Player::GetInput(float dt)
{
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        Player::PlayerSprite.move(-1 * dt *500,0);
    }

    if(sf::Keyboard::isKeyPressed(sf::Keyboard::D/>))
    {
        Player::PlayerSprite.move(1 * dt *500,0);
    }
}

void Player::Shooting()
{
   /* if(Player::shot == true)
    {
        Player::k++;
        if(k>1)
          int a = k-1;
        int currentPosition  = 0;                                                                                               //Current position of required bullet

        Player::bullets.push_back (Bullet (Player::PlayerSprite.getPosition().x , Player::PlayerSprite.getPosition().y));

        if(Player::bullets.size() > 10)
            Player::bullets.erase(Player::bullets.begin());

            if(Player::k > 1 && Player::bullets.size() > 1)
                currentPosition = Player::bullets.size() + 1;
                else
                    currentPosition = 0;

         //  if(k>1 && Player::bullets.size()>1 && currentPosition > 1)
           //     Player::bullets.erase(Player::bullets.begin() + currentPosition + 1 , Player::bullets.begin() + k);

    }
    else
        Player::k = 0;

*/
        if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            Player::bullets.push_back(Bullet (Player::PlayerSprite.getPosition().x , Player::PlayerSprite.getPosition().y));
        }

        if(Player::bullets.size() > 10)
            Player::bullets.erase(Player::bullets.begin());

}

void Player::MoveAllBullets(float dt)
{
    for(int i =0;i<Player::bullets.size();i++)
    {
        Player::bullets[i].MoveBullet(dt);
    }
}

void Player::DestroyAllBullets()
{
    for(int i=0;i<Player::bullets.size();i++)
    {
        if(Player::bullets[i].Destroy == true)
            Player::bullets.erase(Player::bullets.begin() + i);
    }
}

void Player::Update()
{
        Player::noOfBullets = Player::bullets.size();
        Player::PlayerPos = Player::PlayerSprite.getPosition();

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
                Player::shot = true;
        else
                Player::shot = false;
}

sf::Sprite Player::DisplayBullet(int BulletNo)
{
        return Player::bullets[BulletNo].DisplayBullet();
}


Player::~Player()
{
    //dtor
}




Bullet.hpp

#ifndef BULLET_H
#define BULLET_H

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/window.hpp>

class Bullet
{
private:
    sf::Texture bulletTexture ;
    sf::Sprite bulletSprite ;
  public:
    bool Destroy ;

    public:
        Bullet(float Xp, float Yp);
        sf::Sprite DisplayBullet ();

        void MoveBullet (float dt);
        void DestroyBullet ();

        virtual ~Bullet();

};

#endif // BULLET_H
 


Bullet.cpp
#include "Bullet.h"

Bullet::Bullet(float Xp ,float Yp)
{
    Bullet::bulletTexture.loadFromFile("textures/bullet.png");
    Bullet::bulletSprite.setTexture(Bullet::bulletTexture);

    Bullet::bulletSprite.setOrigin(Bullet::bulletTexture.getSize().x/2,Bullet::bulletTexture.getSize().y/2);
    Bullet::bulletSprite.setPosition(Xp,Yp);
    Bullet::bulletSprite.setScale(0.1 ,0.1);

    Bullet::Destroy = false;
    //ctor
}

sf::Sprite Bullet::DisplayBullet()
{
    return Bullet::bulletSprite;
}

void Bullet::MoveBullet(float dt)
{
    Bullet::bulletSprite.move(0,-10 * dt);
}

void Bullet::DestroyBullet()
{
    if (Bullet::bulletSprite.getPosition().y<0)
        Bullet::Destroy = true ;

}

Bullet::~Bullet()
{
    //dtor
}
 


pardon my english
please help
thanks in advance

Is This A Good Question/Topic? 0
  • +

Replies To: i shoot once , but more than 1 bullet gets created {SFML ,C++}

#2 Martyr2   User is offline

  • Programming Theoretician
  • member icon

Reputation: 5360
  • View blog
  • Posts: 14,258
  • Joined: 18-April 07

Re: i shoot once , but more than 1 bullet gets created {SFML ,C++}

Posted 27 May 2018 - 03:21 PM

Are you sure you are not creating multiple bullets even when they are not moving? The sprites perhaps are stacked on top of one another. Since each time you are pressing the mouse a bullet is created based on the position of the player, all the bullets would have the same exact player coordinates, but are still created. I bet if you were to watch the number of bullets in your vector, you would see that even though the player is standing still, all bullets still are being created.

Right now you are creating bullets with no checking if perhaps a bullet was already created and at the exact same coordinates. Ideally you would want where if they clicked two times really really fast that only one bullet would be created. however if they clicked with a second or so in between, this would give the first bullet a chance to move away from the player before allowing another bullet to be created.

From what I am guessing is that you are just creating bullets at extra fast speed (basically the speed of your game loop) and they are sharing the same coordinates. The only reason you see it while moving is because the player coordinates are changing just enough to place each bullet at a slightly different location during creation.

I hope you get what I am saying. :)
Was This Post Helpful? 0
  • +
  • -

#3 Bihar Shooter   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 39
  • Joined: 13-February 18

Re: i shoot once , but more than 1 bullet gets created {SFML ,C++}

Posted 27 May 2018 - 06:17 PM

i got what you said
i have a little function in Player.hpp that(displays no. of bullets present in bullet vector) checks the no. of bullets , when i shoot , no. of bullets created are different every time , many times it is 4 or 5
when i am standing still the bullets created are mostly 2-3 , many times 1
when in motion the bullets created are 4-5 and many times 7

i am checking how many bullets are being created
but how are 4-5 bullets created in single shot doesn't make any sense to me

UPDATE-

Strangely , when i wrote exact same code but this time used MouseAim and kept the player only stationary , the bullets are working just fine , 1 bullet created in 1 shot
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1