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