游戏循环碰撞检测性能

时间:2015-07-06 10:24:44

标签: c# xaml windows-10 windows-10-mobile

我正在开发一款Windows 10 2D棋盘游戏,有时会产生连锁反应,其中144个移动物体可能会与36个非移动物体发生碰撞。这是“最糟糕”的可能情况。

每个移动的游戏对象都是由一些非移动的游戏对象创建的。非移动游戏对象“射击”移动游戏对象,当他们与其他非移动游戏对象发生碰撞时会发生一些事情:)

我正在使用故事板移动XAML对象(UserControls),并根据CompositionTarget.Rendering检查与游戏循环的碰撞。

我的电脑上的一切都很好用,但是当我试图在手机上产生这种效果时会出现问题。

我的游戏循环如下:

foreach (var movingGameObject in GameCanvas.Children.OfType<MovingGameObect>())
        {
            if (movingGameObject.Visibility == Visibility.Visible)
                CheckCollision(movingGameObject);
        }

CheckCollision方法如下所示:

        var left = Canvas.GetLeft(movingGameObject);
        var top = Canvas.GetTop(movingGameObject);
        var right = left + movingGameObject.Width;
        var bottom = top + movingGameObject.Height;

        // If left Canvas - remove
        if (left <= 0 || right >= GameCanvas.ActualWidth || top <= 0 || bottom >= GameCanvas.ActualHeight)
        {
            RemoveMovingGameObject(movingGameObject);
            return;
        }
        else
        {
            // Since it can go 4 ways - I check if it moves up, down, right or left
            if (movingGameObject.Way == Way.Left)
            {

                for (/* this is being done max 5 times, I checked it. It gets every possible game object id that may be on the way of moving game object */)
                {
                    if (this._gameObjects[i].IntersectsWith(movingGameObject))
                    {
                        RemoveMovingGameObject(movingGameObject);
                        GameObjectHit(this._gameObjects[i], null);
                        return;
                    }
                }
            }
            else if (movingGameObject.Way == Way.Right)
            {
                //SAME HERE
            }
            // SAME FOR UP and DOWN
        }

GameObjectHit方法检查非移动游戏对象是否必须拍摄另一个移动游戏对象等。因此,当这是非常糟糕的情况时,游戏循环迭代必须检查碰撞,有时会产生另一个移动物体并射击它(它们)。

和IntersectsWith方法:

        var x1 = Canvas.GetLeft(this);
        var y1 = Canvas.GetTop(this);
        var r1 = new Rect(x1, y1, this.ActualWidth, this.ActualHeight);

        var x2 = Canvas.GetLeft(mgo2);
        var y2 = Canvas.GetTop(mgo2);
        var r2 = new Rect(x2, y2, mgo2.ActualWidth, mgo2.ActualHeight);

        r1.Intersect(r2);

        if (!r1.IsEmpty)
            return true;
        else
            return false;`

哦,差点忘了。手机上发生了什么?游戏循环调用时间不够,并且不能足够快地检查碰撞(移动物体只是飞过非移动物体)。

我尽我所能来调整表演。我知道Windows 10 Mobile处于测试版并且它会更快,但是当它变热时,游戏循环被称为~2次,所以这不是系统故障。

1 个答案:

答案 0 :(得分:0)

对于任何在未来挣扎于此问题的人: 是的 - 这是基于XAML的性能问题。

我用MonoGame(XNA)重新编写代码,没有问题。即使在低预算的诺基亚Lumia 635上,一切都运行良好:)

我没有尝试过Win2D选项,但怀疑结果会和MonoGame一样好。

感谢大家的回复。