0

这是我的代码:

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Text.hpp>
#include <iostream>

using namespace std;

class Game
{
    private:

        bool kratka[9];
        bool tak;

        sf::RenderWindow okno;

        sf::Image ikolo;
        sf::Image ikrzyz;

        sf::Texture tkolo;
        sf::Texture tkrzyz;

        sf::Sprite kolo[9];
        sf::Sprite krzyz[9];

        sf::Sprite minkz;
        sf::Sprite minko;

        sf::Vector2f vec;
        sf::Vector2i mouse;

        sf::Font font;

        sf::Text Gracz1;
        sf::Text Gracz2;

        sf::Text wynik1;
        sf::Text wynik2;

        sf::Texture tkrata;
        sf::Texture spowtorz;

        sf::Sprite powtorz;
        sf::Sprite skrata[9];
        int ikr[9];   // zmienne odpowiadajace za logiczna wartosc kraty
        int rzad[8]; //kombinacje rzedow

        int player1;
        int player2;

        string sp1;
        string sp2;

        void update_licznik();

        static const int krata=150;

        void process();
        void update();
        void render();

        bool jestna(sf::Sprite &sp);
        bool gracz;

    public:
        Game();
        void run();
};

Game::Game():okno(sf::VideoMode(800,600,32),"Kolko i krzyzyk")
{
    tkrata.loadFromFile("sprites/kratka.png");
    ikolo.loadFromFile("sprites/kolo.png");
    ikrzyz.loadFromFile("sprites/krzyz.png");
    spowtorz.loadFromFile("sprites/powtorz.png");
    ikrzyz.createMaskFromColor(sf::Color(255,255,255),0);
    ikolo.createMaskFromColor(sf::Color(255,255,255),0);

    okno.setFramerateLimit(30);

    tkolo.loadFromImage(ikolo);
    tkrzyz.loadFromImage(ikrzyz);

    minkz.setTexture(tkrzyz);
    minkz.setPosition(670,270);
    minkz.setScale(0.7,0.7);

    minko.setTexture(tkolo);
    minko.setPosition(0,270);
    minko.setScale(0.7,0.7);

    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            kolo[3*i+j].setTexture(tkolo);
            krzyz[3*i+j].setTexture(tkrzyz);
            kolo[3*i+j].setPosition(i*150+175,j*150+75);
            krzyz[3*i+j].setPosition(i*150+175,j*150+75);
        }
    }

    font.loadFromFile("sprites/poseiAOE.ttf");
    Gracz1.setFont(font);
    Gracz1.setString("Gracz 1");
    Gracz1.setCharacterSize(70);

    Gracz2.setFont(font);
    Gracz2.setString("Gracz 2");
    Gracz2.setCharacterSize(70);
    Gracz2.setPosition(650,0);

    wynik1.setFont(font);
    wynik2.setFont(font);
    wynik1.setCharacterSize(300);
    wynik2.setCharacterSize(300);
    wynik1.setPosition(25,0);
    wynik2.setPosition(700,0);

    powtorz.setTexture(spowtorz);
    powtorz.setPosition(640,440);

    player2=0;
    player2=0;

    for(int i=0;i<9;i++)
    {
        ikr[i]=0;
        rzad[i]=0;
    }
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            skrata[3*i+j].setTexture(tkrata);
            skrata[3*i+j].setPosition(i*150+175,j*150+75);
        }
    }


}

void Game::update_licznik()
{
    sp1=to_string(player1);
    sp2=to_string(player2);
    wynik1.setString(sp1);
    wynik2.setString(sp2);
}


bool Game::jestna(sf::Sprite &sp)
{
    vec=sp.getPosition();
    mouse=sf::Mouse::getPosition(okno);

    if(mouse.x>vec.x && mouse.x<vec.x+krata && mouse.y>vec.y && mouse.y<vec.y+krata)
        return true;
    else
        return false;
}

void Game::process()
{
    sf::Event zdarzenie;
    while(okno.pollEvent(zdarzenie))
    {
        for(int i=0;i<9;i++)
        {
            if(zdarzenie.type==sf::Event::MouseButtonPressed && jestna(skrata[i]) && ikr[i]==0)
            {
                gracz=!gracz;
                if(gracz)
                    ikr[i]++;
                else
                    ikr[i]--;
            }   
            if(zdarzenie.type==sf::Event::MouseButtonPressed && jestna(powtorz))
            {
                for(int i=0;i<9;i++)
                {
                    ikr[i]=0;
                }
            }
        }

        if(zdarzenie.type==sf::Event::Closed)
            okno.close();
    }
}

void Game::update()
{
    update_licznik();
    rzad[0]=ikr[0]+ikr[1]+ikr[2];
    rzad[1]=ikr[0]+ikr[3]+ikr[6];
    rzad[2]=ikr[2]+ikr[5]+ikr[8];
    rzad[3]=ikr[6]+ikr[7]+ikr[8];
    rzad[4]=ikr[3]+ikr[4]+ikr[5];
    rzad[5]=ikr[1]+ikr[4]+ikr[7];
    rzad[6]=ikr[0]+ikr[4]+ikr[8];
    rzad[7]=ikr[2]+ikr[4]+ikr[6];
    for(int i=0;i<8;i++)
    {
        if(rzad[i]==3)
        {
            player1++;
            rzad[i]=0;
            for(int i=0;i<9;i++)
                ikr[i]=0;

        }
        if(rzad[i]==-3)
        {
            player2++;
            rzad[i]=0;
            for(int i=0;i<9;i++)
                ikr[i]=0;
        }
    }
}

void Game::render()
{
    okno.clear();
    for(int i=0;i<9;i++)
    {
        okno.draw(skrata[i]);
        if(ikr[i]==1)
            okno.draw(kolo[i]);
        if(ikr[i]==-1)
            okno.draw(krzyz[i]);
    }
    okno.draw(Gracz1);
    okno.draw(Gracz2);
    okno.draw(wynik1);
    okno.draw(wynik2);
    okno.draw(powtorz);
    okno.draw(minkz);
    okno.draw(minko);
    okno.display();
}

void Game::run()
{
    while(okno.isOpen())
    {
        process();
        update();
        render();
    }
}

int main()
{
    Game game;
    game.run();
    return 0;
}

每次运行此代码时,都会出现以下异常:

Unhandled exception at 0x505D4361 (msvcr110d.dll) in Gra1.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC
4

1 回答 1

-2

它崩溃的地方主要是什么,你应该用调试器弄清楚,但是看看代码,有很多错误。

上面的代码甚至不应该编译,因为它SFML/Text.hpp不是一个有效的标头。

using namespace std;主要是一件坏事,如果它在全球范围内完成,那么这样做是完全错误的。命名空间的存在是为了 a) 防止名称冲突和 b) 明确类的来源,因此在大多数情况下,您不应该是using命名空间。

每个变量都需要初始化。如果它是一个具有默认构造函数的类,则无需执行任何操作,但如果它是 anint或 an bool,则必须对其进行初始化,否则您将运行具有未定义行为的应用程序,这意味着它可能随时崩溃。由于您使用的是类,因此您应该在构造函数的初始化列表中初始化变量,就像您对窗口所做的那样。

正如 ch0kee 在评论中指出的那样,rzad会发生溢出。不幸的是,应用程序可能仍会继续运行,因为访问数组中最后一个元素之后的元素可以保证是一个有效的指针,如果将 0 分配给它,在某些情况下可能会很幸运。即使“指针”有效,您也不应写入或读取其基础内容。std::vector您可以通过使用或使用 C++11来防止此类问题,std::array它将数据与其大小相结合,从而允许进行准确且无错误的边界检查。

Inproccess()并且update()您正在使用for循环来迭代数组,但是您多次使用 index variable i,从而使另一个索引黯然失色。您应该始终为嵌套循环使用不同的索引,不仅可以使用更高层的索引,还可以减少混淆。

最后,您可能希望用英语编写变量名称。使用您的母语进行编程是可以的,但是一旦您向非母语的人寻求帮助,其他人就会难以理解您的应用程序的含义。

如果你解决了上面所说的一切,它不应该再崩溃了。顺便说一句,在编译时激活更高级别的错误检查是一件很有价值的事情,因为它已经通过警告告诉你很多错误。

于 2013-09-26T11:54:10.720 回答