1

我正在为我正在编写的 GBA 游戏进行一些碰撞检测和处理,并且在将处理部分放入函数时遇到了问题。我正在尝试更改成员变量的值(在本例中Player.global_x),但是将对象传递给函数不允许这样做。相关代码如下:

主文件

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,因为你没有在函数中修改它。在这种情况下是否应该传递值或引用只是优化问题。只有第一个参数需要是(非常量)引用。

于 2014-04-13T20:31:37.337 回答
3

这不起作用,因为您按值传递了对象:

void HandleCollision(sprite obj1, sprite obj2);

相反,您应该通过引用传递它们:

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

如果您像以前一样定义函数(按值传递),则将复制两个参数,并且函数将使用副本。
因此,即使您更改了它们的成员,这些副本也会在函数返回后立即销毁,而在外部,您的原始精灵不会被修改。

另一方面,如果您将函数定义为接受对对象的引用,则不会制作任何副本并且您将能够修改它们。

另请注意,当通过引用传递时,这些对象不会被复制到堆栈中,这意味着更少的内存操作和更好的性能。

最后一点,您的CheckCollision函数有效,因为您不更改精灵,而只需要从中读取,但您确实应该在那里通过引用传递。事实上,在将对象作为参数传递时,您应该始终通过引用传递,因为它更快。如果您不需要修改对象,则应将它们作为常量引用传递:

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

您可以通过引用或使用指针传递参数。如果你有可能传递一个没有值的对象,那么指针实际上就是我的 go to 方法。这一切都取决于你想用它做什么。

于 2014-04-13T20:39:02.507 回答