-2

I have created a class takeDommage for apply a number or dmg and activate a countdown for create the invincibility frame.

And i us my "int pv; in my class so then i check the "int pv;" he didn't move What's wrong ? pv is initialized before main and it's working then i do pv-=1; manually Oo

main :

    //{ Include
#include <SFML/Graphics.hpp>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include<vector>
#include <collision.h>



//}

//{ Constantes
//Constantes ecran
    int tailleEcranX = 1280;
    int tailleEcranY = 720;

//Constantes perso
    int scalePerso = 3;
    int tailleSpriteX = 32;
    int tailleSpriteY = 48;
    int speed(4);
    int speedSprinte(10);
    int milieuSpriteX = (tailleSpriteX/2)*scalePerso;
    int milieuSpriteY = (tailleSpriteY/2)*scalePerso;

    int pv = 100;
    unsigned int pvMax = 100;

    int eSpeed = 1;
//}

//{ Initialisation

//Initiation des dessins
    sf::RenderWindow window;
    sf::RectangleShape rect;
    sf::Texture perso;
    sf::Texture ennemis;
    sf::Sprite sprite_perso;
    sf::Sprite sprite_ennemis;
    sf::View view;
    sf::RectangleShape rectCol;

    sf::RectangleShape pvBar;
    sf::RectangleShape pvMaxBar;

    enum Dir{Down,Left,Right,Up};

    sf::Vector2i anim (1,Down);

#include "gestion_clavier.h"
#include <takeDommage.h>




//}

//{ Main

int main()
{
    //{ Positionnement des objets

        window.create(sf::VideoMode(tailleEcranX , tailleEcranY), "The Game I");
        window.setPosition(sf::Vector2i(500,250));
        window.setFramerateLimit(120);

    //Fond d'ecran
        rect.setFillColor(sf::Color(110,155,255));
        rect.setSize(sf::Vector2f(tailleEcranX-10,tailleEcranY-10));
        rect.setPosition(5,5);
        rect.setOutlineColor(sf::Color(255,255,255));
        rect.setOutlineThickness(3);

    //rectangle de collision test
        rectCol.setFillColor(sf::Color(0,0,200));
        rectCol.setSize(sf::Vector2f(50,50));
        rectCol.setPosition(400,500);
        rectCol.setOutlineColor(sf::Color(255,255,255));
        rectCol.setOutlineThickness(1);



    //Bar pv
        pvBar.setFillColor(sf::Color(20,255,30));
        pvBar.setPosition(20,20);
        pvMaxBar.setFillColor(sf::Color(0,0,0));
        pvMaxBar.setPosition(20,20);
        pvMaxBar.setOutlineColor(sf::Color(255,255,255));
        pvMaxBar.setOutlineThickness(2);

    //Perso
        sprite_perso.setTexture(perso);
        sprite_perso.setPosition(tailleEcranX/2-milieuSpriteX,tailleEcranY/2-milieuSpriteY);
        sprite_perso.setScale(scalePerso,scalePerso);

    //Ennemis
        sprite_ennemis.setTexture(ennemis);
        sprite_ennemis.setPosition(tailleEcranX/2-milieuSpriteX,tailleEcranY/2-milieuSpriteY);
        sprite_ennemis.setTextureRect(sf::IntRect(anim.x*tailleSpriteX,anim.y*tailleSpriteY,tailleSpriteX,tailleSpriteY));
        sprite_ennemis.setScale(scalePerso,scalePerso);


    //Ennemis
        sf::RectangleShape enemy;
        enemy.setFillColor(sf::Color(200,0,0));
        enemy.setSize(sf::Vector2f(50.f, 50.f));

        takeDommage obj;

    //Clock
        sf::Clock time;
        //sf::Clock takeDammageClock;


    //}

    //{Chargement des Sprites


        if (!perso.loadFromFile("link/srpite.png",sf::IntRect(0,0,96,192)))
        {
            std::cout<<"erreur chargement player image"<<std::endl;
        }

        if (!ennemis.loadFromFile("link/srpite.png",sf::IntRect(288,0,96,192)))
        {
            std::cout<<"erreur chargement player image"<<std::endl;
        }


    //}




    //{ Game Loop

        while (window.isOpen())
        {
            sf::Event event;
            while (window.pollEvent(event))
            {
                if (event.type == sf::Event::Closed)
                    window.close();
            }

    //Stat avec rafrechisement

            //Bar pv
                pvMaxBar.setSize(sf::Vector2f(4*pvMax,10));
                pvBar.setSize(sf::Vector2f(4*pv,10));
            //Perso
                sprite_perso.setTextureRect(sf::IntRect(anim.x*tailleSpriteX,anim.y*tailleSpriteY,tailleSpriteX,tailleSpriteY));

            //Ennemy
                std::vector<sf::RectangleShape> enemies;
                enemies.push_back(sf::RectangleShape(enemy));
                int enemySpawnTimer = 0;


    ProcessInput();


    //gestion_clavier();


                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Z)||sf::Keyboard::isKeyPressed(sf::Keyboard::S)||sf::Keyboard::isKeyPressed(sf::Keyboard::D)||sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
                {
                    if (time.getElapsedTime().asMilliseconds()>= 50)
                    {
                                anim.x++;
                        if(anim.x*tailleSpriteX >= perso.getSize().x)
                           anim.x=0;

                            time.restart();
                    }
                }


    //Boucle Pv

                if(pv>=pvMax)
                {
                    pv=pvMax;
                }

                if(pv<=0)
                {
                    pv=0;
                }



    //ENEMIES

                if(enemySpawnTimer < 50)
                    enemySpawnTimer++;

                if (enemySpawnTimer >= 50)
                {
                    enemy.setPosition((rand() % int(window.getSize().x - enemy.getSize().x)), 0.f);
                    enemies.push_back(sf::RectangleShape(enemy));

                    enemySpawnTimer = 0;
                }

                for (size_t i = 0; i < enemies.size(); i++)
                {
                    enemies[i].move(0, eSpeed);

                    if (enemies[i].getPosition().y > window.getSize().y)
                        enemies.erase(enemies.begin() + i);
                }



    //Collision
                if(Collision::PixelPerfectTest(sprite_perso,sprite_ennemis))
                {
                    //std::cout<<"collision pp"<<std::endl;
                     obj.prendreDegat(50 ,pv);
                    //std::cout<<pv<<std::endl;
                }


    //Dessinage
                window.draw(rect);
                window.draw(rectCol);
                window.draw(sprite_perso);
                window.draw(sprite_ennemis);

                window.draw(pvMaxBar);
                window.draw(pvBar);


    //Boucle dessinage

                for (size_t i = 0; i < enemies.size(); i++)
                {
                    window.draw(enemies[i]);

                }

                window.display();
                window.clear();


    }

    //}


    return 0;
}

takeDommage.h :

      #ifndef TAKEDOMMAGE_H
#define TAKEDOMMAGE_H

    #include <SFML/Graphics.hpp>
    #include <string>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>


class takeDommage
{
    public:
        takeDommage();
        void prendreDegat(int Dommage, int pv);

        //virtual ~takeDommage();

    protected:
        sf::Clock takeDammageClock;
        int Dommage;

    private:
};

#endif // TAKEDOMMAGE_H

takeDommage.cpp :

#include "takeDommage.h"

takeDommage::takeDommage()
{

}

void takeDommage::prendreDegat(int Dommage, int pv)
{

    if(takeDammageClock.getElapsedTime().asSeconds()>3)
        {
            std::cout << "bite" << std::endl;
            pv -= Dommage;
            takeDammageClock.restart();
        }
}
Jules
  • 15
  • 4
  • 5
    Incomplete code so I can't give a proper answer, but it is likely because in `void takeDommage::prendreDegat(int Dommage, int pv)` `int pv` passes `pv` by value. This makes a copy of the parameter passed in, so `pv -= Dommage;` reduces a local variable. The original source variable, which may or may not be the global variable `pv`, is unaffected. – user4581301 Sep 28 '18 at 21:20
  • 2
    Suggested reading: [What's the difference between passing by reference vs. passing by value?](https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) – user4581301 Sep 28 '18 at 21:22
  • *I have created a class takeDommage for apply a number or dmg and activate a countdown for create the invincibility frame.* -- I suggest to properly learn the C++ language before starting to learn about frameworks that use C++. Frameworks assume you know the language already. – PaulMcKenzie Sep 28 '18 at 21:26
  • show us where you calling `takeDommage::prendreDegat(int Dommage, int pv)` doesnt your main has more code into it? – Yucel_K Sep 28 '18 at 21:30
  • right now you have my all main code – Jules Sep 28 '18 at 21:37
  • Regarding @Yucel_K' s comment, please read [mcve]. If I am correct about pass by reference vs pass by value, you only need a few lines of code to demonstrate the problem. The true beauty of the MCVE is the act of crafting one almost always exposes the error and enables you to understand and fix it. While they are very useful to us answering questions, they are more useful to you as they eliminate the need for the question in the first place. – user4581301 Sep 28 '18 at 21:39
  • 1
    Here is an MCVE demonstrating your problem: https://ideone.com/1cvVdT – user4581301 Sep 28 '18 at 21:45
  • @Paul I need to challenge me and see progression for learning so i tried to start with sfml because it's look easy for many thing and for the moment the SFML motivated me more than blocked. – Jules Sep 28 '18 at 21:58
  • ًWaht do you expect? The `pv` is a global and initialized to `100` but in the class you are decrementing a local variable. `pv` not the outer. Remember Passing by value will create a local variable and any change to this variable won't affect the original. You can pass by Reference or by Pointer to solve this: `void prendreDegat(int Dommage, int& pv);` – Raindrop7 Sep 28 '18 at 22:05

1 Answers1

-1
 if(Collision::PixelPerfectTest(sprite_perso,sprite_ennemis))
 {
     //std::cout<<"collision pp"<<std::endl;
     obj.prendreDegat(50 ,pv);
     //std::cout<<pv<<std::endl;
 }

you are passing the pv by value.

this causes the void takeDommage::prendreDegat(int Dommage, int pv) to make a local copy of of the pv and decrements the value by Dommage.

what you have to do is pass it by reference. in c++ you do that by Type&

so in your case you change your takeDommage to void takeDommage::prendreDegat(int Dommage, int& pv)

since the pv is now passed by reference, any operation you make in takeDommage::prendreDegat will affect the global pv.

Edit: passing the global variables is not considered a good code practice. But im not going to go into details into that since you just starting c++. Try moving your std::cout<<pv<<std::endl from your main and place it into void takeDommage::prendreDegat(int Dommage, int pv) without making changes and see what happens.

Yucel_K
  • 688
  • 9
  • 17
  • thanks you all, i will read all the doc & topic you linked me :) – Jules Sep 28 '18 at 21:52
  • 1
    @Jules Additional helpful reading: [Variable Shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) tl;dr, when you reuse an identifier, the most recent definition replaces and hides all of the previous definitions. – user4581301 Sep 28 '18 at 22:15
  • @user4581301, its like unknitting a sweater. learning one thing causes to learn 100 new terms in c++ T_T. on an additional note. his pv parameter doesn't get shadowed out since his takeDommage.h doesn't know anything about global pv – Yucel_K Sep 28 '18 at 22:22
  • Touché! You have me. – user4581301 Sep 28 '18 at 22:34