C# 碰撞检测和停止运动

C# 碰撞检测和停止运动,c#,.net,collision,C#,.net,Collision,我正在做一个简单的游戏。我设法用箭头键和火让我的角色移动。我在地图上加了一些墙,这些墙是图片框。我成功地检测到碰撞,如下所示: private void timer6_Tick(object sender, EventArgs e){ foreach (PictureBox pic in brick){ if (pic.Bounds.IntersectsWith(pb_sprite.Bounds)){ Console.WriteLine("Coli

我正在做一个简单的游戏。我设法用箭头键和火让我的角色移动。我在地图上加了一些墙,这些墙是图片框。我成功地检测到碰撞,如下所示:

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?!");
        }
    }
}
bool collision = brick.Any(pic => pic.Bounds.IntersectsWith(pb_sprite.Bounds));
switch(rotation)
{
    case "up": 
        canup = !collision;
        break;
    ...
}

它的工作原理与预期一样,但当我撞到物体(墙)时,我会得到“Colision!”回声,这是正常的,这也会停止角色在碰撞发生时所面对的方向上的移动。问题是,当我退出碰撞时,其中一个布尔值保持为false,这会阻止我的角色再次朝同一方向移动。我尝试在else分支中将所有这些bool设置为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?!");
    }
    ...

这将在开始时将所有bool设置为true,而在循环中仅将单个bool设置为false。

我不能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?!");
    }
    ...

这将在开始时将所有bool设置为true,并且在循环中仅将单个bool设置为false。

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


常用的方法是将角色的位置设置回一帧,或者如果你想更准确地说,找出角色穿透砖块的深度(°860°662; 865°),并将其沿其产生的方向移动回原来的距离。

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


常用的方法是通过一帧设置角色的位置,或者如果你想更准确地说,找出角色穿透砖块的深度(°°860ʖ͡°),然后沿着它来自的方向将其移回该数量。

嗯,实际上有一个
Any
函数()

你可以这样使用它:

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?!");
        }
    }
}
bool collision = brick.Any(pic => pic.Bounds.IntersectsWith(pb_sprite.Bounds));
switch(rotation)
{
    case "up": 
        canup = !collision;
        break;
    ...
}

实际上,有一个
Any
函数()

你可以这样使用它:

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?!");
        }
    }
}
bool collision = brick.Any(pic => pic.Bounds.IntersectsWith(pb_sprite.Bounds));
switch(rotation)
{
    case "up": 
        canup = !collision;
        break;
    ...
}

你可以检查你的<代码>运动函数-假设你有一个-而不是在你的<代码>计时器< /代码>中,如果你发现了一个冲突,你不允许这个动作。考虑一个不同的方法:用户输入命令。然后在游戏上下文中评估该命令,该命令要么被批准,要么被拒绝。如果批准,则字符将沿指示方向移动;如果拒绝,什么也不会发生。我认为如果你用这个模式来构造你的游戏,你的许多问题就会消失。你可以检查你的运动函数-假设你有一个-而不是在你的<代码>计时器< /代码>中。如果你发现了一个冲突,你不允许这个动作。考虑一个不同的方法:用户输入命令。然后在游戏上下文中评估该命令,该命令要么被批准,要么被拒绝。如果批准,则字符将沿指示方向移动;如果拒绝,什么也不会发生。我认为,如果你使用这种模式构建游戏,你的很多问题都会消失。同样,使用枚举而不是字符串进行
旋转
可能会有所帮助。同样,使用枚举而不是字符串进行
旋转
可能会有所帮助