Example #1
0
void PathfindingBehavior::MoveTo(RuntimeScene & scene, float x, float y)
{
    if ( parentScene != &scene ) //Parent scene has changed
    {
        parentScene = &scene;
        sceneManager = parentScene ? &ScenePathfindingObstaclesManager::managers[&scene] : NULL;
    }

    path.clear();

    //First be sure that there is a path to compute.
    int targetCellX = GDRound(x/(float)cellWidth);
    int targetCellY = GDRound(y/(float)cellHeight);
    int startCellX = GDRound(object->GetX()/(float)cellWidth);
    int startCellY = GDRound(object->GetY()/(float)cellHeight);
    if ( startCellX == targetCellX && startCellY == targetCellY ) {
        path.push_back(sf::Vector2f(object->GetX(), object->GetY()));
        path.push_back(sf::Vector2f(x, y));
        EnterSegment(0);
        pathFound = true;
        return;
    }

    //Start searching for a path
    //TODO: Customizable heuristic.
    ::SearchContext ctx(*sceneManager, allowDiagonals);
    ctx.SetCellSize(cellWidth, cellHeight).SetStartPosition(object->GetX(), object->GetY());
    ctx.SetObjectSize(object->GetX()-object->GetDrawableX()+extraBorder,
                      object->GetY()-object->GetDrawableY()+extraBorder,
                      object->GetWidth()-(object->GetX()-object->GetDrawableX())+extraBorder,
                      object->GetHeight()-(object->GetY()-object->GetDrawableY())+extraBorder);
    if (ctx.ComputePathTo(x, y))
    {
        //Path found: memorize it
        const ::Node * node = ctx.GetFinalNode();
        while (node) {
            path.push_back(sf::Vector2f(node->pos.x*(float)cellWidth, node->pos.y*(float)cellHeight));
            node = node->parent;
        }

        std::reverse(path.begin(), path.end());
        path[0] = sf::Vector2f(object->GetX(), object->GetY());
        EnterSegment(0);
        pathFound = true;
        return;
    }

    //Not path found
    pathFound = false;
}
Example #2
0
void PathBehavior::Reverse()
{
    float tempTimeOnSegment = timeOnSegment;
    std::reverse(path.begin(), path.end());
    EnterSegment(path.size() - currentSegment - 2);
    timeOnSegment = totalSegmentTime - tempTimeOnSegment;
}
Example #3
0
/**
 * Called at each frame before events :
 * Position the object on the path
 */
void PathBehavior::DoStepPreEvents(RuntimeScene & scene)
{
    if(!isPathLoaded)
    {
        LoadPath(scene);
        Reset();
    }

    //  add to the current time along the path
    timeOnSegment += static_cast<double>(scene.GetTimeManager().GetElapsedTime())
        / 1000000.0 * speed;

    //  if I reached the end of this segment, move to a new segment
    if (timeOnSegment >= totalSegmentTime && currentSegment < path.size())
        EnterSegment(currentSegment + 1);

    //Position object on the segment
    sf::Vector2f newPos;
    if ( !path.empty() && currentSegment < path.size()-1 )
        newPos = offset + path[currentSegment] + (path[currentSegment + 1] - path[currentSegment]) * (timeOnSegment / totalSegmentTime);
    else
    {
        if ( stopAtEnd && !path.empty()) newPos = path.back() + offset;
        else if (reverseAtEnd)
        {
            std::reverse(path.begin(), path.end());
            EnterSegment(0);
            if (!path.empty()) newPos = path.front() + offset;
        }
        else
        {
            EnterSegment(0);
            if (!path.empty()) newPos = path.front() + offset;
        }
    }

    object->SetX(newPos.x);
    object->SetY(newPos.y);

    return;
}
Example #4
0
void PathBehavior::DoStepPostEvents(RuntimeScene & scene)
{
    if(!isPathLoaded)
    {
        LoadPath(scene);
        Reset();
    }
    if(futureSegment != -1)
    {
        EnterSegment(futureSegment);
        futureSegment = -1;
    }
    if(futurePosition != -1)
    {
        timeOnSegment = futurePosition * totalSegmentTime;
        futurePosition = -1;
    }
}
Example #5
0
void PathfindingBehavior::DoStepPreEvents(RuntimeScene & scene)
{
    if ( parentScene != &scene ) //Parent scene has changed
    {
        parentScene = &scene;
        sceneManager = parentScene ? &ScenePathfindingObstaclesManager::managers[&scene] : NULL;
    }

    if ( !sceneManager ) return;

    if (path.empty() || reachedEnd) return;

    //Update the speed of the object
    float timeDelta = static_cast<double>(scene.GetTimeManager().GetElapsedTime()) / 1000000.0;
    speed += acceleration*timeDelta;
    if ( speed > maxSpeed ) speed = maxSpeed;
    angularSpeed = angularMaxSpeed; //No acceleration for angular speed for now

    //Update the time on the segment and change segment if needed
    timeOnSegment += speed*timeDelta;
    if (timeOnSegment >= totalSegmentTime && currentSegment < path.size())
        EnterSegment(currentSegment + 1);

    //Position object on the segment and update its angle
    sf::Vector2f newPos;
    float pathAngle = object->GetAngle();
    if ( currentSegment < path.size()-1 ) {
        newPos = path[currentSegment] + (path[currentSegment + 1] - path[currentSegment]) * (timeOnSegment / totalSegmentTime);
        pathAngle = atan2(path[currentSegment+1].y - path[currentSegment].y,
                          path[currentSegment+1].x - path[currentSegment].x)*180/3.14159+angleOffset;
    }
    else
        newPos = path.back();

    object->SetX(newPos.x);
    object->SetY(newPos.y);

    //Also update angle if needed
    if ( rotateObject )
        object->RotateTowardAngle(pathAngle, angularSpeed, scene);
}
Example #6
0
void PathBehavior::Reset()
{
    EnterSegment(0);
}