1

私が書いているGBAゲームの衝突検出と処理を行っていますが、処理部分を関数に入れる際に問題が発生しています。メンバー変数 (この場合は ) の値を変更しようとしていますがPlayer.global_x、オブジェクトを関数に渡すと、これが機能しません。関連するコードは次のとおりです。

main.cpp

bool CheckCollision(sprite obj1, sprite obj2){
    int obj1_top = obj1.global_y;
    int obj1_bottom = obj1.global_y + (obj1.height-1);
    int obj1_left = obj1.global_x;
    int obj1_right = obj1.global_x + (obj1.width-1);
    int obj2_top = obj2.global_y;
    int obj2_bottom = obj2.global_y + (obj2.height-1);
    int obj2_left = obj2.global_x;
    int obj2_right = obj2.global_x + (obj2.width-1);

    if(obj1_right < obj2_left){     // if obj1 is left of obj2
        return false;
    }
    if(obj1_left > obj2_right){     // if obj1 is right of obj2
        return false;
    }
    if(obj1_bottom < obj2_top){     // if obj1 is above obj2
        return false;
    }
    if(obj1_top > obj2_bottom){     // if obj1 is below obj2
        return false;
    }

    return true;
}

void HandleCollision(sprite obj1, sprite obj2){
    if(obj1.direction == RIGHT){
        Player.global_x -= (obj1.global_x + obj1.width) - obj2.global_x;    // This works but is not modular
        obj1.global_x -= (obj1.global_x + obj1.width) - obj2.global_x;      // This does not work
    }
}

void CheckAllPossibleCollisions(){
    bool collision = false;
    for(int i=0; i<(WallsVector.size()); i++){
        collision = CheckCollision(Player, WallsVector.at(i));
        if(collision==true){
            // This piece of code works, but would incur repetition of code for each different type of game object
            /*if(Player.direction == RIGHT){
                Player.global_x -= ((Player.global_x+Player.width) - WallsVector.at(i).global_x);
            }*/
            HandleCollision(Player, WallsVector.at(i));
        }
    }
}

オブジェクトを渡すときは関数は正常に機能しますが、変数を変更するときCheckCollision()は機能しません。HandleCollision()

これに役立つコメントをいただければ幸いです。ありがとうございます。

4

3 に答える 3

5

パラメータを値で渡しています。つまり、関数は独自のコピーを取得します。参照を渡す必要があるようです:

void HandleCollision(sprite& obj1, const sprite& obj2)

ここでconstは、関数内で変更しないため、2 番目のパラメーターを としてマークしたことに注意してください。この場合、値を渡すか参照を渡すかは、最適化の問題にすぎません。最初のパラメーターのみが (非定数) 参照である必要があります。

于 2014-04-13T20:31:37.337 に答える
3

オブジェクトを値渡ししたため、機能しません。

void HandleCollision(sprite obj1, sprite obj2);

代わりに、それらを参照渡しする必要があります。

void HandleCollision(sprite& obj1, sprite& obj2);

関数を定義した場合 (値渡し)、2 つの引数がコピーされ、関数はそのコピーを使用します。
そのため、メンバーを変更しても、これらのコピーは関数が戻るとすぐに破棄され、外部では元のスプライトは変更されません。

一方、オブジェクトへの参照を受け入れるように関数を定義すると、コピーは作成されず、それらを変更できます。

また、参照渡しの場合、これらのオブジェクトがスタックにコピーされないという事実は、メモリ操作が少なくなり、パフォーマンスが向上することにも注意してください。

最後の注意として、CheckCollisionスプライトを変更せずにスプライトから読み取るだけでよいため、関数は機能しますが、実際にはそこにも参照渡しする必要があります。実際、オブジェクトを引数として渡すときは、参照渡しの方が速いため、常に参照渡しを行う必要があります。オブジェクトを変更する必要がない場合は、それらを定数参照として渡す必要があります。

bool CheckCollision(const sprite& obj1, const sprite& obj2);
于 2014-04-13T20:53:41.380 に答える