使用画布在 WPF C# 中跟踪玩家的移动



我试图在WPF c#中使用画布构建原始吃豆人游戏的项目,我被鬼跟踪和运动卡住了。我们的想法是检查鬼魂是否会在下一步移动中穿过墙壁并阻止它。

但很明显我的编程是错误的,鬼魂一直在移动,直到它到达墙壁,然后向后移动一步,然后再次移动到墙壁,等等。

我应该如何修复算法?当然,如果你有任何其他的想法,我很乐意听到。

谢谢!

这是鬼移动的相关代码:

//flags are used to check if the ghosts next move is through a wall
double x1 = Canvas.GetTop(pacman);
double y = Canvas.GetLeft(pacman);
if (Math.Abs(Canvas.GetTop(redGuy) - x1) > Math.Abs(Canvas.GetLeft(redGuy) - y) && (flagUp == false || flagDown == false))
{
if (Canvas.GetTop(redGuy) < x1)
{
if (flagDown == false)
{
Canvas.SetTop(redGuy, Canvas.GetTop(redGuy) + ghostSpeed);
}
else if (flagRight == false || flagLeft == false)
{
if (Canvas.GetLeft(redGuy) < y && flagLeft == false)
{
Canvas.SetLeft(redGuy, Canvas.GetLeft(redGuy) + ghostSpeed);
}
else if (flagRight == false)
{
Canvas.SetLeft(redGuy, Canvas.GetLeft(redGuy) - ghostSpeed);
}
}
}
else
{
if (flagUp == false)
{
Canvas.SetTop(redGuy, Canvas.GetTop(redGuy) - ghostSpeed);
}
else if (flagRight == false || flagLeft == false)
{
if (Canvas.GetLeft(redGuy) < y && flagLeft == false)
{
Canvas.SetLeft(redGuy, Canvas.GetLeft(redGuy) + ghostSpeed);
}
else if (flagRight == false)
{
Canvas.SetLeft(redGuy, Canvas.GetLeft(redGuy) - ghostSpeed);
}
}
}
}
else if (flagRight == false || flagLeft == false)
{
if (Canvas.GetLeft(redGuy) < y)
{
if (flagLeft == false)
{
Canvas.SetLeft(redGuy, Canvas.GetLeft(redGuy) + ghostSpeed);
}
else if (flagUp == false || flagDown == false)
{
if (Canvas.GetTop(redGuy) > x1 && flagUp == false)
{
Canvas.SetTop(redGuy, Canvas.GetTop(redGuy) - ghostSpeed);
}
else if (flagDown == false)
{
Canvas.SetTop(redGuy, Canvas.GetTop(redGuy) + ghostSpeed);
}
}
}
else
{
if (flagRight == false)
{
Canvas.SetLeft(redGuy, Canvas.GetLeft(redGuy) - ghostSpeed);
}
else if (flagUp == false || flagDown == false)
{
if (Canvas.GetTop(redGuy) > x1 && flagDown == false)
{
Canvas.SetTop(redGuy, Canvas.GetTop(redGuy) - ghostSpeed);
}
else if (flagRight == false)
{
Canvas.SetTop(redGuy, Canvas.GetTop(redGuy) + ghostSpeed);
}
}
}
}

我认为你的主要问题在于游戏设计。

不要将UI用作数据存储

使用UI作为数据的表示。

我不确定这是否真的是一个适合SO的答案,但它不适合在注释中。

把你的游戏区域想象成一个正方形的网格。大概是你的吃豆人/播放器的大小。

在内部用一个二维数组表示,所以大致上说Square[100,80]。

给定的吃豆人或鬼有一个正方形,它们使用整数x,y坐标相关联。

如果鬼魂与玩家有相同的坐标,那么他们就会得到他。

你仍然可以在画布上定位精灵,并根据它们的坐标计算它们的位置。另外,该板可以使用一个itemscontrol和一个canvas作为itemspanel来表示。这是一种相当常见的方法,如果您进行搜索,应该能够找到。但是基本上你绑定了一个可观察的集合到itemscontrol的itemssource。该集合有一个视图模型类型来指示它是什么。playerviewmodel, ghostviewmodel, wallviewmodel等。然后使用数据类型将这些模板化到UI中,以匹配视图模型和数据模板。您可以通过公开x、y属性并将它们绑定到画布来定位网格。左边和画布。项容器的顶部属性。使用转换器从平方值计算px值。

如果x和y是px值:

<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=XPos}" />
<Setter Property="Canvas.Top" Value="{Binding Path=YPos}" />
</Style>
</ItemsControl.ItemContainerStyle>

但是正方形会比px大,所以你需要通过转换器进行乘法转换。

您可能认为此模板业务效率低下。但它的可扩展性非常好。对于我们的地图编辑应用你可以做的一件事是绘制树林的轮廓以这种方式转换成屏幕上的一个区域。然后它被树木填满。这里可能有成千上万棵树。

每一个都有一个treevm和一个使用3个模板之一的数据模板。

https://i.stack.imgur.com/pZJVD.png

一旦你有了一个网格,你就可以使用路径算法,如空间a *,如果幽灵向吃豆人移动。我不记得他们是这样做的还是只是随机移动。

如果你对设计游戏感兴趣,那么许多游戏都需要路径,而空间A*可能是最常用的。特别是如果所有方块的成本都是一样的。我们的游戏使用的是可变成本的空间A*。

Amit的页面很好:

http://theory.stanford.edu/amitp/GameProgramming/

最新更新