这是我的代码:
#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
答案 0 :(得分:-1)
崩溃的地方主要是什么,你应该用调试器搞清楚,但看看代码,有很多错误。
由于SFML/Text.hpp
不是有效的标题,上面的代码甚至不应该编译。
using namespace std;
主要是一件坏事,如果它在全球范围内完成,那么这样做是完全错误的。命名空间用于a)防止名称冲突和b)明确表示类的起源,因此在大多数情况下,您不应该是using
名称空间。
每个变量都需要初始化。如果它是一个带有默认构造函数的类,则不必执行任何操作,但如果它是int
或bool
,则必须对其进行初始化,否则您将运行未定义的应用程序行为,这意味着它可能随时爆炸。由于您正在使用类,因此您应该在构造函数的初始化列表中初始化变量,就像使用窗口一样。
正如ch0kee在评论中指出的那样,rzad
会遇到溢出。不幸的是,应用程序可能仍然继续运行,因为在数组中最后一个元素之后访问元素保证是一个有效的指针,如果你为它指定0,你可能会在某些情况下幸运。即使“指针”有效,您也不应该写入或读取其基础内容。您可以使用std::vector
或C ++ 11 std::array
来阻止此类问题,它将数据与其大小相结合,从而允许进行准确且无错误的边界检查。
在proccess()
和update()
中,您使用for
循环来迭代数组,但是您使用了多次索引变量i
,从而掩盖了其他指数。你应该总是对嵌套循环使用不同的索引,不仅可以使用更高的索引,还可以减少混淆。
最后,您可能希望用英语编写变量名称。使用您的母语进行编程是可以的,但是一旦您向非本地语言的人寻求帮助,另一个人就会在理解您的应用程序的含义时遇到问题。
如果你修复了上述所有内容,它就不会崩溃了。顺便说一下,在编译时激活更高级别的错误检查是有价值的,因为它已经通过警告告诉你很多错误。