【问题标题】:Reversing the direction of an object after a collision碰撞后反转对象的方向
【发布时间】:2011-05-03 19:15:04
【问题描述】:

Edit2:新问题见下文。

我正在创建一个 Windows Phone 7 游戏,但遇到了一些困难。我正在尝试做的是使用转换为弧度的触摸屏坐标以一定角度向上发射物体。那部分工作正常。

但是,我无法弄清楚如何使对象从侧壁反弹。我让它在早期的实现中工作,它只是在与墙壁碰撞时否定 Y 值的问题。不幸的是,这一次可没那么容易。当物体撞击墙壁时,它会从墙壁反弹一小段距离,然后再次改变方向朝向墙壁。

我如何构建我的代码,以免它被推到墙上?

谢谢。

//Move bubble
public void MoveBubble(Bubble b, double radians)
{
    if (b.stop == false)
    {
        {
            //Move bubble 'up'
            Y = (float)(speed * Math.Cos(radians));
            X = (float)(speed * Math.Sin(radians));
    }

    b.bubblePosX += X;
    b.bubblePosY += Y;

    //Problem area
    if(b.bubblePosY <= 0)
        Y-=Y;

    if(b.bubblePosY >= 350)
        Y-=Y;
}


//Calculate Angle
private void CalculateAngle(int touchX, int touchY)
{
    radians = (Math.Atan2(touchX - bubbleStart.X, touchY - bubbleStart.Y));
}

Edit2:只是想添加最新的代码。现在球完美地从墙上反弹,但我遇到了将方向 bool 初始化为 true 的问题。有时,当发射物体时,角度是相反的。如何将初始布尔值设置为适当的真/假值?

    //Move bubble
    public void MoveBubble(Bubble bubble, Vector2 distance)
    {
        if (bubble.stop == false)
        {
            float velocityX = speed * distance.X;
            float velocityY = speed * distance.Y;

            bubble.X += velocityX;

            if (direction == true)
                bubble.Y += velocityY;

            if (direction == false)
                bubble.Y -= velocityY;

            if (bubble.Y <= 0)
                direction = !direction;

            if (bubble.Y >= 350)
                direction = !direction;
        }
    }

【问题讨论】:

    标签: c# visual-studio-2010 windows-phone-7 xna


    【解决方案1】:

    你没有否定 Y 值,你只是从它自身中减去它的值。也许你的意思是写:

    Y = -Y;
    

    还是我错过了什么?

    【讨论】:

    • 按照我的代码结构方式,您的建议是将对象固定在向上移动时撞到的墙上。这至少是一点进步。为帮助干杯。
    • 这种“粘连”问题是众所周知的。除了否定 Y 值,还需要将气泡移回“非碰撞”位置。即如果 (b.bubblePosY > 350) { Y = -Y; b.bubblePos.Y = 350; }
    • 尽管我尽了最大的努力,但这对我也不起作用。仍然粘在墙上。谢谢马特。
    【解决方案2】:

    您没有反转气泡移动的方向。在那一刻改变方向的最合适的解决方案是:

    public void MoveBubble(Bubble b, double radians)
    {
        if (b.stop == false)
        {
            {
               //Move bubble 'up'
                Y = (float)(speed * Math.Cos(radians));
                X = (float)(speed * Math.Sin(radians));
            }
    
            b.bubblePosX += X;
    
            //Problem area
            if(b.bubblePosY <= 0 || b.bubblePosY >= 350)
                b.bubblePosY -= Y;
            else
                b.bubblePosY += Y;
        }
    }
    

    该部分代码将只为下一帧向后移动气泡,为了让气泡绝对改变其移动方向,您必须重新计算弧度以获得气泡发现碰撞和旧触摸的点点。

    在恢复中,在每个碰撞点,您都必须重新计算获得气泡的方向,如果您以此为目标,则可以解决整个问题,在发生碰撞时反映方向。

    我正在寻找一些我拥有的代码,但我发现我丢失了它,但我希望我的解释能有所帮助。

    再见

    【讨论】:

    • 谢谢。我做了一个方向布尔值,就可以了。不过我现在有一个新问题。我不知道如何初始化它而不干扰碰撞检测。
    • 链接到我的新代码和问题以供参考:stackoverflow.com/questions/5869071/…
    【解决方案3】:

    您必须更改位置速度。

    如果位置为(0, -1),速度为(1, -1),不能有负值,则必须切换y值(以弥补速度) 到 (0, 1) 并将速度更改为负数 (1, 1)。

    所以,loc(ation) 和 vel(ocity) 必须改变,例如:

    loc(0, 1), vel(0, -1)  // OK
    
    loc(0, 0), vel(0, -1)  // switch vel to y=-y; (so -1 becomes 1)
    
    loc(0, -2), vel(1, -3) // switch loc to it's positive value, loc(0, 2)
                           // and the vel to it's opposite (1, 3)
    
    loc(-1, -3), vel(-2, -4) // loc is set to (1, 3) an vel to (2, 4)
                             // since both X and Y have been breached
    

    【讨论】:

    • 我也试过这个,但我无法让它工作。我怀疑代码存在更根本的错误。一旦撞到墙上,它仍然会在向上移动时粘在墙上。我盯着这个看太久了。谢谢。
    【解决方案4】:

    这样做(假设 X 和 Y 是速度):

    if(b.bubblePosY <= 0 && Y < 0)
        Y = -Y;
    
    if(b.bubblePosY >= 350 && Y > 0)
        Y = -Y;
    

    您的代码中发生的情况是您的气泡卡在墙上。上面的代码仅在气泡移动到墙壁时反映气泡的方向。一旦它移出墙,它就会忽略那面墙。

    此外,与其从位置差计算角度然后将其转换回方向向量,不如尝试简单地对位置差进行归一化以获得方向向量(单位向量;长度 = 1):

    Vector2.Normalize(new Vector2(touchX - bubbleStart.X, touchY - bubbleStart.Y))
    

    您应该在帧之间存储速度矢量或方向矢量,这样当您反射气泡时,它会一直沿该方向移动,直到再次被反射。

    【讨论】:

    • 由于方法的设置方式,第一段代码不起作用。它仍然只是拥抱墙壁。我知道这是相对较小的事情,但我有一个完整的心理障碍。我采用了您的想法来使用矢量,这是一种更直接的方法。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 2018-12-11
    • 1970-01-01
    相关资源
    最近更新 更多