【问题标题】:How to check for specific collision points如何检查特定的碰撞点
【发布时间】:2014-11-30 18:49:02
【问题描述】:

我正在为 C# 开发一个小型乒乓球游戏。我对如何进行碰撞有大致的了解,但是我在指定桨叶上的特定位置时遇到了困难。

我有一个球在表格周围反弹(从墙上反弹),它也可以从桨上反弹。然而,当它从桨上反弹时,它总是以相同的角度反弹。

我想做的是指定桨的部分(例如,左角、右角、中间),并根据它碰到桨的位置我想改变角度。

如果有人能帮助我弄清楚如何指定控件的各个部分(在本例中为图片框),我将不胜感激。

编辑:对不起,我相信我不是很清楚。我想知道的是如何检查球击中桨的位置。

我不会实现任何基于物理的花哨的角度反射,我只会分配直接值。

我知道你可以使用 ball.Bounds.IntersectsWith(paddle.bounds),但这只是任何碰撞。是否可以指定“与左边缘、右边缘相交”等内容?

再次抱歉,造成混淆。

编辑 2:希望这能解决一些问题,这是我的代码,用于从当前的桨中弹起。桨只是一个图片框,而“球”只是图片框内的一个图像。

**pcbPluto 是“球”。

        //bounce off user/ai paddles 
        if (this.pcbPluto.Bounds.IntersectsWith(this.pcbUser.Bounds))
        {
            //if it hits user's paddle, reverse y direction
            intDirectionY *= -1;
        }
        else if (this.pcbPluto.Bounds.IntersectsWith(pcbComputer.Bounds))
        {
            //if it hits computer's paddle, reverse direction
            intDirectionY *= -1; 
        }

如您所见,在击中用户或计算机的桨时,我只是反转垂直运动。这样做的问题是,无论球在哪里撞击球拍,角度都是静态的。

我想做的是,如果球击中球拍的某些区域,角度会有所不同。例如,如果它撞到边缘,它可能会以更陡的角度出去,如果它撞到中间部分,可能是 30 度等。

再次抱歉,造成混淆。

最后一次编辑:成功了!下面是我用来指定球击中图片框的“位置”的方法,并在此基础上更改了反射角度。

public void AiBallBouncer()
    {
        //variable declaration and assignment
        double dblComputerRelativeLocation = 0;

        dblComputerRelativeLocation = Math.Abs((((double)pcbComputer.Left - (double)pcbAsteroid.Left) / (double)pcbAsteroid.Width));

        //check for if the ball bounces on the paddles
        if (pcbAsteroid.Bounds.IntersectsWith(pcbComputer.Bounds))
        {
            //check for which angle of reflection to use 

            if (dblComputerRelativeLocation <= 0.1)
            {
                //reverse direction
                intDirectionY *= -1;

                //set new angle 
                intAngle = 30;

                //increase speed 
                intSpeed += 2;
            }
            else if (dblComputerRelativeLocation <= 0.2)
            {
                //reverse direction 
                intDirectionY *= -1;

                //set new angle 
                intAngle = 35;
            }
            else if (dblComputerRelativeLocation <= 0.4)
            {
                //reverse direction
                intDirectionY *= -1;

                //set new angle 
                intAngle = 50;

                //set speed back to normal
                intSpeed = 5;
            }
            else if (dblComputerRelativeLocation <= 0.6)
            {
                //reverse direction
                intDirectionY *= -1;

                //set new angle 
                intAngle = 60;

                //set speed back to normal
                intSpeed = 5;
            }
            else if (dblComputerRelativeLocation <= 0.8)
            {
                //reverse direction
                intDirectionY *= -1;

                //set new angle 
                intAngle = 50;
            }
            else if (dblComputerRelativeLocation <= 0.9)
            {
                //reverse direction
                intDirectionY *= -1;

                //set new angle 
                intAngle = 35;
            }
            else if (dblComputerRelativeLocation <= 1.0)
            {
                //reverse direction
                intDirectionY *= -1;

                //set new angle 
                intAngle = 30;

                //increase speed 
                intSpeed += 2;
            }
        }
    }

【问题讨论】:

  • 你可以在数学上做到这一点,如果你在碰撞前取球的角度并根据入射角改变它。完全反射后,您只需 180 度 - 那个角度。
  • 绝对不是编程题,属于物理/数学论坛。一旦你有了公式,试着去实现它。如果您对实施有任何具体问题,请返回此处。
  • 您需要什么样的帮助?您还没有清楚地说明您的代码是如何工作的并首先检测到冲突。我想,如果您可以得出结论,它会发生碰撞,那么确认它在哪里发生碰撞应该不会太难。但是,如果没有代码显示您所做的事情(或至少是伪代码或更多细节),我不确定我们能做什么。例如什么是球?什么是蝙蝠?作为最后的想法,你能否将你的蝙蝠组合成三个物体粘合在一起,然后检查每个部分是否发生碰撞......

标签: c#


【解决方案1】:

我可以说,在开发游戏时,优先考虑“看起来正确”和“感觉正确”,而不是数学上的正确性(例如,如果您从两个相同游戏盒的图形卡中获得渲染形状 - 不管它们是什么 -你会看到看起来完全一样的绿色阴影,实际上在某些位上有所不同;并且形状在数学上并不相同)。

所以不要找到确切的碰撞点并尝试对其进行分类; (只是一个建议)只需将桨分成一个网格(我会说 7x7 就足够了;并选择奇数)并将这些部分分类为左边缘、右边缘等。自然会排除一些正方形。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多