【问题标题】:variable in main cpp bug in class类中主要 cpp 错误中的变量
【发布时间】:2018-09-28 21:14:11
【问题描述】:

我已经创建了一个类 takeDommage 来应用一个数字或 dmg 并激活一个倒计时来创建无敌框架。

我是我的“int pv;”在我的班上,所以我检查了“int pv;”他没有动 怎么了 ? pv 在 main 之前初始化并且它正在工作然后我执行 pv-=1;手动哦

主要:

    //{ 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();
        }
}

【问题讨论】:

  • 不完整的代码,所以我无法给出正确的答案,但这可能是因为在void takeDommage::prendreDegat(int Dommage, int pv) int pv 通过值传递pv。这会复制传入的参数,因此pv -= Dommage; 减少了一个局部变量。原始源变量(可能是也可能不是全局变量pv)不受影响。
  • 我创建了一个类 takeDommage 用于应用数字或 dmg 并激活倒计时以创建无敌框架。 -- 我建议在开始之前正确学习 C++ 语言了解使用 C++ 的框架。框架假定您已经了解该语言。
  • 告诉我们你在哪里调用takeDommage::prendreDegat(int Dommage, int pv) 你的主程序没有更多的代码吗?
  • 这是一个 MCVE 演示您的问题:ideone.com/1cvVdT

标签: c++ sfml


【解决方案1】:
 if(Collision::PixelPerfectTest(sprite_perso,sprite_ennemis))
 {
     //std::cout<<"collision pp"<<std::endl;
     obj.prendreDegat(50 ,pv);
     //std::cout<<pv<<std::endl;
 }

您正在按值传递 pv。

这会导致void takeDommage::prendreDegat(int Dommage, int pv) 制作 pv 的本地副本并按 Dommage 递减值。

你要做的就是通过引用传递它。在 C++ 中,你可以通过 Type& 来做到这一点

所以在您的情况下,您将 takeDommage 更改为 void takeDommage::prendreDegat(int Dommage, int&amp; pv)

由于 pv 现在是通过引用传递的,所以您在 takeDommage::prendreDegat 中所做的任何操作都会影响全局 pv

编辑:传递全局变量不是一个好的代码实践。但是由于您刚刚开始使用c ++,因此我不会对此进行详细介绍。尝试将您的 std::cout&lt;&lt;pv&lt;&lt;std::endl 从您的主目录中移出并将其放入 void takeDommage::prendreDegat(int Dommage, int pv) 而不进行任何更改,看看会发生什么。

【讨论】:

  • 谢谢大家,我会阅读您链接我的所有文档和主题:)
  • @Jules 其他有用的阅读材料:Variable Shadowingtl;dr,当您重用标识符时,最新的定义会替换并隐藏所有以前的定义。
  • @user4581301,就像解开毛衣一样。学习一件事会导致在 C++ T_T 中学习 100 个新术语。附加说明。由于他的 takeDommage.h 对全局 pv 一无所知,因此他的 pv 参数不会被隐藏
  • 触摸!你有我。
猜你喜欢
  • 2017-10-17
  • 2022-11-27
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
  • 1970-01-01
  • 2014-06-19
  • 1970-01-01
相关资源
最近更新 更多