我正在开发一款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次,所以这不是系统故障。
答案 0 :(得分:0)
对于任何在未来挣扎于此问题的人: 是的 - 这是基于XAML的性能问题。
我用MonoGame(XNA)重新编写代码,没有问题。即使在低预算的诺基亚Lumia 635上,一切都运行良好:)
我没有尝试过Win2D选项,但怀疑结果会和MonoGame一样好。
感谢大家的回复。