用C#中的墙避免障碍

我正在努力避免一些障碍。 但不知何故,事情并不顺利。 我已经使用了“编程游戏人工智能的例子”一书在c#中与XNA结合创建一个simular函数。

这就是我现在正在做的事情:

public Vector2 ObstacleAvoidance(List<Obstacle> obstacles) { //the detection box length is proportional to the agent's velocity Owner.DetectionBox = Owner.MinDetectionBoxLength + ((Owner.Speed() / Owner.MaxSpeed) * Owner.MinDetectionBoxLength); //tag all obstacles within range of the box for processing TagObstaclesWithinViewRange(Owner); //this will keep track of the closest intersecting obstacle (CIB) BaseGameEntity ClosestIntersectingObstacle = null; //this will be used to track the distance to the CIB double DistToClosestIP = Double.MaxValue; //this will record the transformed local coordinates of the CIB Vector2 LocalPosOfClosestObstacle = new Vector2(); foreach (Obstacle curOb in obstacles) { //if the obstacle has been tagged within range proceed if (curOb.Tag) { //calculate this obstacle's position in local space Vector2 LocalPos = HelperMethods.PointToLocalSpace(curOb.Position, Owner.Heading, Owner.Side, Owner.Position); //if the local position has a negative x value then it must lay //behind the agent. (in which case it can be ignored) if (LocalPos.X >= 0) { //if the distance from the x axis to the object's position is less //than its radius + half the width of the detection box then there //is a potential intersection. double ExpandedRadius = curOb.BoundingRadius + Owner.BoundingRadius; if (Math.Abs(LocalPos.Y) < ExpandedRadius) { //now to do a line/circle intersection test. The center of the //circle is represented by (cX, cY). The intersection points are //given by the formula x = cX +/-sqrt(r^2-cY^2) for y=0. //We only need to look at the smallest positive value of x because //that will be the closest point of intersection. double cX = LocalPos.X; double cY = LocalPos.Y; //we only need to calculate the sqrt part of the above equation once double SqrtPart = Math.Sqrt(ExpandedRadius * ExpandedRadius - cY * cY); double ip = cX - SqrtPart; if (ip <= 0.0) { ip = cX + SqrtPart; } //test to see if this is the closest so far. If it is keep a //record of the obstacle and its local coordinates if (ip < DistToClosestIP) { DistToClosestIP = ip; ClosestIntersectingObstacle = curOb; LocalPosOfClosestObstacle = LocalPos; } } } } } //if we have found an intersecting obstacle, calculate a steering //force away from it Vector2 SteeringForce = Vector2.Zero; if (ClosestIntersectingObstacle != null) { //the closer the agent is to an object, the stronger the //steering force should be double multiplier = 1.0 + (Owner.DetectionBox - LocalPosOfClosestObstacle.X) / Owner.DetectionBox; //calculate the lateral force SteeringForce.Y = (float) ((ClosestIntersectingObstacle.BoundingRadius - LocalPosOfClosestObstacle.Y) * multiplier); //apply a braking force proportional to the obstacles distance from //the vehicle. double BrakingWeight = 0.2; SteeringForce.X = (float) ((ClosestIntersectingObstacle.BoundingRadius - LocalPosOfClosestObstacle.X) * BrakingWeight); } //finally, convert the steering vector from local to world space return HelperMethods.VectorToWorldSpace(SteeringForce, Owner.Heading, Owner.Side); } 

当我看到墙壁时,我仍然通过它而不是改变方向。 这与这个特定的代码行有关:

 double ExpandedRadius = curOb.BoundingRadius + Owner.BoundingRadius; if (Math.Abs(LocalPos.Y) < ExpandedRadius) 

当我看到墙壁时,我应该进入这个,如果我还没有穿过墙壁。

curOb =墙壁和他的boudingradius是12.5。 所有者=玩家,他的边界半径也是12.5。 LocalPos.Y的值是120,这是正确的,因为墙的y位置是在这个确切的位置。 我怎样才能解决这个问题,所以我的玩家不会撞到墙上?

电贺

编辑

应许的图片 – 它应该检测到的墙壁,并将其添加到最接近的碰撞障碍,但它不 承诺的图片

根据你的评论,我的阅读是错误的。 我以为LocalPos是相对于玩家的,因为我认为这就是HelperMethods.PointToLocalSpace应该做的事情。 但是如果LocalPos仍然是世界坐标系,那么你在问题结尾处的描述就可以把它拿走。

你的陈述:

 if (Math.Abs(LocalPos.Y) < ExpandedRadius) 

可以像这样翻译成英文:

 if the wall's vertical position on the screen is less than the bounding distance... 

比较一个绝对的位置和一个相对的距离不应该是很直观的。

这应该是问玩家和墙之间的距离是否小于ExpandingRadius

 double playerDistance = /* Calculate distance between player and wall */ if (playerDistance < ExpandedRadius)