2011-06-18 20 views
0

でのスプライトの画像の高さは、ちょっと私はこのコード行にある例外のルート突き止めてきたばかり:奇妙な例外がスローさ:SFML

>= obj2->GetPosition().y + (obj2->GetCenter().y - obj2->GetImage()->GetHeight())) 

をしかし、私はそれを引き起こしていただきました!に見当もつかない..... 2つのスプライトポインタを取る関数内に奇妙な部分があり、GetImage() - > GetHeight()はオブジェクト1では機能しますが、オブジェクト2では2回目ではありません...

助けてください!私はなぜこれが起こっているのだろうか考えていない!おかげ

すべてのコード:(私は、以前の投稿のコードの行を検索)

#include<SFML/Graphics.hpp> 
#include<SFML/System.hpp> 
#include<cmath> 
#include<vector> 
# define M_PI 3.14159265358979323846 
enum{xXx= 0, yYy= 1}; 
enum{ScreenWidth=800, ScreenHeight=600}; 

sf::RenderWindow Window; 

template<typename T/*, typename T2*/> 
bool CheckCollision(T* obj1, T* obj2){ 
    bool xColl=false,yColl=false; 
    // check if any part of object 1 is between object 2's top and bottom 
    if(obj1->GetPosition().y + (obj1->GetCenter().y - obj1->GetImage()->GetHeight()) 
    <= obj2->GetPosition().y + (obj2->GetImage()->GetHeight() - obj2->GetCenter().y) 

    && obj1->GetPosition().y + (obj1->GetImage()->GetHeight() - obj1->GetCenter().y) 
    >= obj2->GetPosition().y + (obj2->GetCenter().y - obj2->GetImage()->GetHeight())) 
     yColl= true; 
    // check if any part of object 1 is between object 2's left and right 
    if(obj1->GetPosition().x + (obj1->GetCenter().x - obj1->GetImage()->GetWidth()) 
    <= obj2->GetPosition().x + (obj2->GetImage()->GetWidth() - obj2->GetCenter().x) 

    && obj1->GetPosition().x + (obj1->GetImage()->GetWidth() - obj1->GetCenter().x) 
    >= obj2->GetPosition().x + (obj2->GetCenter().x - obj2->GetImage()->GetWidth())) 
     xColl= true; 

    if(xColl==true && yColl==true) return true; 
    else return false; 
}; 


template<typename T> 
void CalculateMove(T Time, T Speed, T Angle, T& buffX, T& buffY) 
{ //Make the degrees positive 
    if(Angle<0) Angle= 360+Angle; 

    //determine what quadrant of circle we're in  
    unsigned int Quadrant= 1;  
    if(Angle>=90) Quadrant= 2;  
    if(Angle>=180) Quadrant= 3;  
    if(Angle>=270) Quadrant= 4; 

    //anything above 90 would be impossible triangle 
    Angle= (float)(Angle-(int)Angle)+(float)((int)Angle%90); 

    // calculates x and y based on angle and Hypotenuse 
    if((int)Angle!=0){ 
     if(Quadrant==2 || Quadrant==4) Angle=90-Angle; //The unit circle triangle is flipped otherwise, causing x and y to be switched 
     buffY= sin(Angle/180 * M_PI)/ (1.f/(Speed*Time)); 
     buffX= sin((180-Angle-90)/ 180 * M_PI)/ (1.f/(Speed*Time));} 

    else{// Movement is a straight line on X or Y axis 
     if(Quadrant==1 || Quadrant==3) buffX= Speed*Time; 
     if(Quadrant==2 || Quadrant==4) buffY= Speed*Time;} 

    //Quadrant Factor (positive or negative movement on the axis) 
    switch(Quadrant){ 
    case 1: break; 
    case 2: buffX=-buffX; break; 
    case 3: buffX=-buffX; buffY=-buffY; break; 
    case 4: buffY=-buffY; break;} 
}; 

template<typename T> 
struct MoveData{ 
    float X,Y; 
    T* Object; 
    MoveData(float x, float y, T* object):X(x), Y(y), Object(object){}; 
}; 

///////////////////////////////////////// Mysprite //////////////////////////////// 
class mySprite : public sf::Sprite 
{ 
private: 
    float velocity; 
    float angle; 

public: 
    // all the values needed by the base class sprite(); 
    mySprite(
     const sf::Image& Img, 
     const sf::Vector2f& Position = sf::Vector2f(0, 0), 
     const sf::Vector2f& Scale = sf::Vector2f(1, 1), 
     float Rotation = 0.f, 
     const float Angle= 0.f, 
     const float Velocity= 0.f, 
     const sf::Color& Col = sf::Color(255, 255, 255, 255)): 
     Sprite(Img, Position, Scale, Rotation, Col){ 
     angle= Angle; 
     velocity= Velocity;}; 

    float Velocity(){return velocity;}; 
    void SetVelocity(float newVelocity){velocity=newVelocity;}; 
    float Angle(){return angle;}; 
    void SetAngle(float newAngle){angle=(float)(newAngle-(int)newAngle)+(float)((int)newAngle%360);}; 

    void Update(){ 
     float frameTime= Window.GetFrameTime(); 
     float X=0,Y=0; 
     //SetRotation(angle); 
     CalculateMove(frameTime,velocity,angle,X,Y); 
     Move(X,-Y); 
    }; 

    void Accelerate(float PPS){velocity+=PPS;}; 
    void Turn(float degrees){ 
     angle=(float)((angle+degrees)-(int)(angle+degrees))+(float)((int)(angle+degrees)%360);}; 

    void Reflect(float CollAngle){ 
     SetRotation(-GetRotation()); 
     angle=360-angle; 
     //TODO: factor in the collision angle 
    }; 
}; 

class MoveBuff 
{ 
private: 
    std::vector<MoveData<mySprite>> buff; 

public: 
    void AddMove(mySprite obj, float X, float Y){ 
     MoveData<mySprite> data(X, Y, &obj); 
     buff.push_back(data);}; 

    void TestColl(){ 
     for(unsigned int Object= 0; Object< buff.size(); Object++){ 
      for(unsigned int CollCheck=Object+1; CollCheck<=buff.size()-1; CollCheck++){  
       if(CheckCollision(buff[Object].Object, buff[CollCheck].Object)){ 
        buff[Object].Object->Reflect(0); 
        buff[Object].Object->Reflect(0);}}} 
    }; 

    void Move(){ 
     for(unsigned int I= 0; I<buff.size(); I++) 
      buff[I].Object->Move(buff[I].X, buff[I].Y); 
    }; 
}; 

int main() 
{ 
    Window.Create(sf::VideoMode(ScreenWidth, ScreenHeight), "Pong! by Griffin Howlett", sf::Style::Resize | sf::Style::Close); 

    sf::Image img; 
    img.Create(30,50,sf::Color(255,0,0)); 
    mySprite box(img, sf::Vector2f(400,0), sf::Vector2f(1,1), 0, 270, 100); //TODO: test collision with different speeds 
    box.SetCenter(15,25); 

    sf::Image img2; 
    img2.Create(56.5,80,sf::Color(255,0,0)); 
    mySprite box2(img2, sf::Vector2f(400,400), sf::Vector2f(1,1), 0, 90, 100); 
    box2.SetCenter(25,40); 

    Window.Display(); 

    for(;;){ 
     Window.Clear(); 
     MoveBuff MoveBuff; 
     float frameTime= Window.GetFrameTime(); 
     float X=0,Y=0; 

     CalculateMove(frameTime,box.Velocity(),box.Angle(),X,Y); 
     MoveBuff.AddMove(box,X,Y); 

     CalculateMove(frameTime,box2.Velocity(),box2.Angle(),X,Y); 
     MoveBuff.AddMove(box2,X,Y); 

     MoveBuff.TestColl(); 
     MoveBuff.Move(); 

     Window.Draw(box); 
     Window.Draw(box2); 
     Window.Display(); 
    } 
} 

答えて

1
MoveData(float x, float y, T* object):X(x), Y(y), Object(object){}; // Constructor 
               // ^^^^^^^^^^^^ 
           // Just making a reference to the argument. Shallow copy. 



void AddMove(mySprite obj, float X, float Y){ 

    MoveData<mySprite> data(X, Y, &obj); 
    buff.push_back(data); 

}// => lifetime of the obj ends at this point. 

コンストラクタはシャローコピーを作っています。イニシャライザのリストでは、引数の参照だけです。しかし、MoveBuff::AddMoveへの呼び出し後に、寿命がobjで終了します。だから、MoveData::Objectはぶら下がります。逆参照は例外を引き起こすものです。代わりにディープコピーを作成します。

void TestColl() 
{ 
    for(unsigned int Object= 0; Object< buff.size(); Object++){ 
     for(unsigned int CollCheck=Object+1; CollCheck<=buff.size()-1; CollCheck++){  
      if(CheckCollision(buff[Object].Object, buff[CollCheck].Object)){ 
       // ^^^^^^^^^ This the problem. buff[Object].Object is dangling. 
関連する問題