C# 游戏循环碰撞检测性能

C# 游戏循环碰撞检测性能,c#,xaml,windows-10,windows-10-mobile,C#,Xaml,Windows 10,Windows 10 Mobile,我正在做一个Windows102D棋盘游戏,有时候会产生连锁反应,144个移动的物体会与36个不移动的物体碰撞。这是可能出现的“最坏”情况 每个移动的游戏对象都是由一些非移动的游戏对象创建的。非移动的游戏对象“射击”移动的游戏对象,当它们与其他非移动的游戏对象碰撞时会发生一些事情:) 我正在使用故事板移动XAML对象(用户控件),并基于CompositionTarget.Rendering检查与游戏循环的冲突 在我的电脑上一切都很好,但当我试图在手机上产生这种效果时,问题就出现了 我的游戏循环如

我正在做一个Windows102D棋盘游戏,有时候会产生连锁反应,144个移动的物体会与36个不移动的物体碰撞。这是可能出现的“最坏”情况

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

我正在使用故事板移动XAML对象(用户控件),并基于CompositionTarget.Rendering检查与游戏循环的冲突

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

我的游戏循环如下所示:

foreach (var movingGameObject in GameCanvas.Children.OfType<MovingGameObect>())
        {
            if (movingGameObject.Visibility == Visibility.Visible)
                CheckCollision(movingGameObject);
        }
        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
        }
哦,差点忘了。电话里发生了什么事?游戏循环被调用的次数不够,并且它没有足够快地检查碰撞(移动的对象只是通过非移动的对象飞行)


我尽我所能去争取一场演出。我知道Windows 10 Mobile是beta版,速度会更快,但gameloop在变热时每秒被调用约2次,因此这不是系统故障。

对于将来遇到此问题的人: 是-这是一个基于XAML的性能问题

我用MonoGame(XNA)重新编写了代码,没有问题。即使在低成本的诺基亚Lumia 635上,一切都运行正常:)

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


谢谢大家的回复

对于将来遇到此问题的任何人: 是-这是一个基于XAML的性能问题

我用MonoGame(XNA)重新编写了代码,没有问题。即使在低成本的诺基亚Lumia 635上,一切都运行正常:)

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


谢谢大家的回复

我想你的问题是我在控制中,而不是在碰撞检测循环中。您是否测量了循环在设备上执行所需的时间?一个技巧:你调用了很多依赖属性和附加属性,例如
Canvas.GetLeft
Canvas.ActualWidth
如果你的循环太慢,尝试缓存这些值。我更改了一些依赖属性和附加属性,但我不能真正删除“Canvas.GetLeft”和“Canvas.GetTop”,因为这个对象一直在移动。我可以根据故事板的进度来计算位置,但我怀疑它会更快。调用属性的改变并没有令人遗憾地提高速度……你的游戏循环执行多长时间?使用
秒表
测量或使用VS内置性能工具,当基本无事可做时,游戏循环需要1-2毫秒才能运行,当有许多移动对象时,甚至需要400毫秒。。。在这个400毫秒的过程中,所有东西都处于不同的位置,甚至可能会错过一些碰撞……不幸的是,对于XAML来说,这不是一个好的用例。你看过Win2D吗?我想你的问题是我在控件中,而不是在碰撞检测循环中。您是否测量了循环在设备上执行所需的时间?一个技巧:你调用了很多依赖属性和附加属性,例如
Canvas.GetLeft
Canvas.ActualWidth
如果你的循环太慢,尝试缓存这些值。我更改了一些依赖属性和附加属性,但我不能真正删除“Canvas.GetLeft”和“Canvas.GetTop”,因为这个对象一直在移动。我可以根据故事板的进度来计算位置,但我怀疑它会更快。调用属性的改变并没有令人遗憾地提高速度……你的游戏循环执行多长时间?使用
秒表
测量或使用VS内置性能工具,当基本无事可做时,游戏循环需要1-2毫秒才能运行,当有许多移动对象时,甚至需要400毫秒。。。在这个400毫秒的过程中,所有东西都处于不同的位置,甚至可能会错过一些碰撞……不幸的是,对于XAML来说,这不是一个好的用例。你看过Win2D吗?
        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;`