碰撞检测和停止运动

Collision detection and stop movement

我正在制作一个简单的游戏。我设法用箭头键和开火让我的角色移动。我在地图上添加了一些墙,它们是图片框。我设法检测到这样的碰撞:

private void timer6_Tick(object sender, EventArgs e){
    foreach (PictureBox pic in brick){
        if (pic.Bounds.IntersectsWith(pb_sprite.Bounds)){
            Console.WriteLine("Colision!");
            switch (rotation){
                case "up":
                    canup = false;
                    candown = true;
                    canleft = true;
                    canright = true;
                    break;
                case "down":
                    canup = true;
                    candown = false;
                    canleft = true;
                    canright = true;
                    break;
                case "left":
                    candown = true;
                    canup = true;
                    canleft = false;
                    canright = true;
                    break;
                case "right":
                    candown = true;
                    canup = true;
                    canleft = true;
                    canright = false;
                    break;
             }
        }
        else
        {
            Console.WriteLine("No colision?!");
        }
    }
}

它按预期工作,但是当我撞到物体(墙)时,我得到 "Colision!" 回声,没关系,这也停止了在碰撞发生时角色所面对的方向的移动。问题是当我退出碰撞时,其中一个布尔值保持为假,这会阻止我的角色再次向同一方向移动。我尝试在 else 分支中将所有这些 bools 设置为 true 但是因为即使有碰撞也有五堵墙 else 分支执行了 5 次中的 4 次。我需要某种 "any" 函数来检查是否没有或任何墙壁正在被击中。

我不是 100% 确定您的意思,但我认为这可能会有所帮助:

canup = true;
candown = true;
canleft = true;
canright = true;
foreach (PictureBox pic in brick)
{
    if (pic.Bounds.IntersectsWith(pb_sprite.Bounds))
    {
        Console.WriteLine("Colision!");
        switch (rotation)
        {
            case "up":
                canup = false;
                break;
            case "down":
                candown = false;
                break;
            case "left":
                canleft = false;
                break;
            case "right":
                canright = false;
                break;
        }
    }
    else
    {
        Console.WriteLine("No colision?!");
    }
    ...

这会在开始时将所有布尔值设置为真,并且仅在循环内将单个布尔值设置为假。

有没有可能,你只是停止你的角色,而不是解决碰撞?砖块和角色在彼此内部,毕竟要触发碰撞。它们需要移到彼此之外才能再次无碰撞。

常用的方法是把角色的位置往后拉一帧,或者如果你想更精确的话,找出角色在砖块里钻了多深(͡° ͜ʖ ͡°)然后沿着它来自那个数量的方向。

嗯,实际上有一个 Any 函数 (https://msdn.microsoft.com/en-us/library/bb534972(v=vs.110).aspx)。

你可以像这样使用它:

bool collision = brick.Any(pic => pic.Bounds.IntersectsWith(pb_sprite.Bounds));
switch(rotation)
{
    case "up": 
        canup = !collision;
        break;
    ...
}