Se lanzó una extraña excepción: obtener la altura de una imagen de sprites en SFML

Oye, he rastreado la raíz de una excepción que se encuentra en esta línea de código:

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

pero no tengo ni idea de qué lo está causando ... la parte extraña está en la función, que toma dos punteros de sprite, la función GetImage () -> GetHeight () funciona para el objeto 1, pero no una segunda vez para el objeto 2 ...

¡Por favor ayuda! ¡No tengo ni idea de por qué pasaría esto! Gracias

todo el código: (busque la línea de código que publiqué anteriormente)

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

preguntado el 18 de junio de 11 a las 02:06

1 Respuestas

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.

El constructor está haciendo una copia superficial. En la lista de inicializadores, solo está haciendo una referencia al argumento. Pero la vida de obj termina después de la llamada a MoveBuff::AddMove. Asi que, MoveData::Object va colgando. Y la desreferenciación es lo que le causa la excepción. En su lugar, haz una copia profunda.

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.

Respondido el 18 de junio de 11 a las 06:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.