Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ IOS Box2D-body根据速度波动的点阵列遵循特定路径_C++_Ios_Objective C_Box2d - Fatal编程技术网

C++ IOS Box2D-body根据速度波动的点阵列遵循特定路径

C++ IOS Box2D-body根据速度波动的点阵列遵循特定路径,c++,ios,objective-c,box2d,C++,Ios,Objective C,Box2d,我有一个关于身体的问题,它遵循一条特定的路径。首先,这里介绍了将身体移动到目标点的方法: const float destinationControl = 0.3f; b2Vec2 targetPosition = path[counter]; b2Vec2 missilePosition = _physicalBody->GetPosition(); b2Vec2 diff = targetPosition - missilePosition; float dist = diff.Len

我有一个关于身体的问题,它遵循一条特定的路径。首先,这里介绍了将身体移动到目标点的方法:

const float destinationControl = 0.3f;
b2Vec2 targetPosition = path[counter];
b2Vec2 missilePosition = _physicalBody->GetPosition();
b2Vec2 diff = targetPosition - missilePosition;
float dist = diff.Length();

if (dist > 0)
{

    if(dist < destinationControl){
        ++counter;
        return;
    }

    // compute the aiming direction
    b2Vec2 direction = b2Vec2(diff.x / dist, diff.y / dist);

    // get the current missile velocity because we will apply a force to compensate this.
    b2Vec2 currentVelocity = _physicalBody->GetLinearVelocity();

    // the missile ideal velocity is the direction to the target multiplied by the max speed
    b2Vec2 desireVelocity = b2Vec2(direction.x * maxSpeed, direction.y * maxSpeed);

    // compensate the current missile velocity by the desired velocity, based on the control factor

    b2Vec2 finalVelocity = control * (desireVelocity - currentVelocity);

    // transform our velocity into an impulse (get rid of the time and mass factor)
    float temp = (_physicalBody->GetMass() / normalDelta);

    b2Vec2 finalForce = b2Vec2(finalVelocity.x * temp, finalVelocity.y * temp);

    _physicalBody->ApplyForce(finalForce, _physicalBody->GetWorldCenter());

}
const float destinationControl=0.3f;
b2Vec2 targetPosition=路径[计数器];
b2Vec2导弹位置=_physicalBody->GetPosition();
b2Vec2 diff=目标位置-导弹位置;
浮动距离=差异长度();
如果(距离>0)
{
如果(距离GetLinearVelocity();
//导弹理想速度是指向目标的方向乘以最大速度
b2Vec2 Desievelocity=b2Vec2(方向.x*maxSpeed,方向.y*maxSpeed);
//根据控制因子,按所需速度补偿当前导弹速度
b2Vec2最终定位=控制*(期望水平-当前速度);
//将我们的速度转化为冲量(去掉时间和质量因素)
浮点温度=(_physicalBody->GetMass()/normalDelta);
b2Vec2 finalForce=b2Vec2(finalVelocity.x*temp,finalVelocity.y*temp);
_physicalBody->ApplyForce(finalForce,_physicalBody->GetWorldCenter());
}
数组
path
表示为名称,表示用户触发触摸事件时身体遵循的特定路径

我的问题是变量maxSpeed不是常数。因此,当路径非常短且
maxSpeed
非常高时,身体会在当前目标点上方移动。在身体上方使用我的方法返回到当前目标点,而不聚焦下一点

目前,我有一个恒定的
destinationControl
,它控制身体和当前目标点之间的距离是否短到足以聚焦下一个目标点

重点是增加一个表示目标点索引的计数器

所以我的最后一个问题是:你能想象另一个可能的解决方案吗,因为我的不是很安全。有没有办法确定身体是否在当前目标点上方移动


提前感谢您,并为我的英语不好感到抱歉。

我想您可能需要做的是将您的maxSpeed与可能移动的距离进行比较。当移动距离超过可用距离时,将错位设置为targetPosition并检索路径中的下一个目标位置,然后从maxSpeed中减去已移动的距离

if (maxSpeed > dist)
{
    maxSpeed -= dist;
    misslePosition = targetPosition;
    targetPosition = path[counter + 1];
}
另一个可能的解决方案是在totalDistanceCovered
const float stepDistance(0.1f); //Some relatively small value depending on your units.
float totalDistance(0.0f);
while (totalDistance < maxSpeed)
{
    totalDistance += stepDistance;

    //Perform the same movement logic you already have.
}
const-float步距(0.1f)//一些相对较小的值取决于您的单位。
浮动总距离(0.0f);
同时(总距离<最大速度)
{
总距离+=步距;
//执行与您已有的相同的移动逻辑。
}
---我的原始答案如下---

如果试图与动态目标碰撞,可能需要将_physicalBody的定义设置为子弹

默认情况下,Box2D使用连续碰撞检测(CCD)来防止动态实体穿过静态实体。这是通过将形状从旧位置扫到新位置来实现的。引擎在扫描期间查找新碰撞,并计算这些碰撞的碰撞时间(TOI)。身体移动到其第一个TOI,然后在剩余的时间步长内停止

通常,动态物体之间不使用CCD。这样做是为了保持性能合理。在某些游戏场景中,您需要动态实体来使用CCD。例如,您可能希望向一堆动态砖块发射高速子弹。如果没有CCD,子弹可能穿透砖块


我在进行演示后的一次路径中遇到了类似的问题(下面是示例)

我发现最可行的解决方案是使用两个函数的组合。第一个检测实体是否“接近”他们想要到达的下一个点

bool MovingEntity::IsNearTarget()
{
   Vec2 toTarget = GetTargetPos() - GetBody()->GetPosition();

   if(toTarget.LengthSquared() < GetMinSeekDistanceSquared())
   {
      return true;
   }
   return false;
}
bool MovingEntity::IsNearTarget()
{
Vec2-toTarget=GetTargetPos()-GetBody()->GetPosition();
if(toTarget.LengthSquared()
此实体正在使用“查找”操作从一点移动到另一点。如果接近该点,则函数返回true。它使用距离的平方来避免长度的平方根

第二个函数是每次更新时执行的路径跟踪函数:

void MovingEntity::ExecuteNavigateToPoint()
{
   vector<Vec2>& path = GetPath();
   bool isNearTarget = IsNearTarget();
   bool isNearNavTarget = IsNearTarget(_navigatePos,5.0);

   /* If the state tick timer expires, it means we
    * have spent too long trying to reach the next waypoint
    * and we need to replan on how to get to it.
    */
   if(IsStateTickTimerExpired())
   {
      CCLOG("Tick Timer Expired!!!");
      ChangeState(ST_NAVIGATE_TO_POINT);
   }
   /* If we are close to the navigation target point,
    * just seek to it.
    */
   if(isNearNavTarget || path.size() == 0)
   {  // Must be really close...just seek to it.
      CommandSeek(_navigatePos);
   }
   else if(!IsNodePassable(GetTargetPos(),false))
   {
      ChangeState(ST_NAVIGATE_TO_POINT);
   }
   else
   {  // If we are near the target and there are more points
      // on the list, pop the next point and navigate to it.
      if(isNearTarget && path.size() > 0)
      {  // Still more points on the list.
         GetTargetPos() = path.back();
         path.pop_back();
         ResetStateTickTimer(2*TICKS_PER_SECOND);
         /* If we can't get past the current nodes, replan.
          */
         if(path.size() > 0 && !IsNodePassable(path.back(),false))
         {
            ChangeState(ST_NAVIGATE_TO_POINT);
         }
      }
      ApplyThrust();
      ApplyTurnTorque();
   }
}
void MovingEntity::ExecuteNavigateToPoint()
{
向量&path=GetPath();
bool isNearTarget=isNearTarget();
bool isNearNavTarget=IsNearTarget(_navigatePos,5.0);
/*如果状态勾号计时器过期,则表示我们
*花了太长时间试图到达下一个航路点
*我们需要重新规划如何到达目的地。
*/
如果(IsStateTickTimerExpired())
{
CCLOG(“滴答计时器已过期!!!”;
变更状态(ST_导航至_点);
}
/*如果我们接近导航目标点,
*只要努力做到这一点。
*/
如果(isNearNavTarget | | path.size()==0)
{//一定很近了……只要努力就行了。
CommandSeek(_navigatePos);
}
如果(!IsNodePassable(GetTargetPos(),false))为else
{
变更状态(ST_导航至_点);
}
其他的
{//如果我们接近目标并且有更多的点数
//在列表上,弹出下一个点并导航到它。
if(isNearTarget&&path.size()>0)
{//列表上还有更多的点。
GetTargetPos()=path.back();
path.pop_back();
ResetStateTickTimer(每秒2个滴答声);
/*如果我们过不了难关