Esempio n. 1
0
void GD_API MoveObjects( RuntimeScene & scene )
{
    RuntimeObjList allObjects = scene.objectsInstances.GetAllObjects();

    for (unsigned int id = 0;id < allObjects.size();++id)
    {
        allObjects[id]->SetX( allObjects[id]->GetX() + allObjects[id]->TotalForceX() * static_cast<double>(scene.GetElapsedTime())/1000000.0 );
        allObjects[id]->SetY( allObjects[id]->GetY() + allObjects[id]->TotalForceY() * static_cast<double>(scene.GetElapsedTime())/1000000.0 );

        allObjects[id]->UpdateForce( static_cast<double>(scene.GetElapsedTime())/1000000.0 );
    }

    return;
}
Esempio n. 2
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.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;
}
Esempio n. 3
0
void PlatformerObjectAutomatism::DoStepPreEvents(RuntimeScene & scene)
{
    if ( parentScene != &scene ) //Parent scene has changed
    {
        parentScene = &scene;
        sceneManager = parentScene ? &ScenePlatformObjectsManager::managers[&scene] : NULL;
        floorPlatform = NULL;
    }

    if ( !sceneManager ) return;

    double timeDelta = static_cast<double>(scene.GetElapsedTime())/1000000.0;

    //0.1) Get the player input:

    double requestedDeltaX = 0;
    double requestedDeltaY = 0;

    //Change the speed according to the player's input.
    leftKey |= !ignoreDefaultControls && sf::Keyboard::isKeyPressed( sf::Keyboard::Left );
    rightKey |= !ignoreDefaultControls && sf::Keyboard::isKeyPressed( sf::Keyboard::Right );
    if ( leftKey )
        currentSpeed -= acceleration*timeDelta;
    if ( rightKey )
        currentSpeed += acceleration*timeDelta;

    //Take deceleration into account only if no key is pressed.
    if ( leftKey == rightKey )
    {
        bool wasPositive = currentSpeed>0;
        currentSpeed -= deceleration*timeDelta*(wasPositive ? 1.0 : -1.0);

        //Set the speed to 0 if the speed was top low.
        if ( wasPositive && currentSpeed < 0 ) currentSpeed = 0;
        if ( !wasPositive && currentSpeed > 0 ) currentSpeed = 0;
    }

    if (currentSpeed > maxSpeed) currentSpeed = maxSpeed;
    if (currentSpeed < -maxSpeed) currentSpeed = -maxSpeed;
    requestedDeltaX += currentSpeed*timeDelta;

    //Compute the list of the objects that will be used
    std::set<PlatformAutomatism*> potentialObjects = GetPotentialCollidingObjects(std::max(requestedDeltaX, maxFallingSpeed));
    std::set<PlatformAutomatism*> overlappedJumpThru = GetJumpthruCollidingWith(potentialObjects);

    //Check that the floor object still exists and is near the object.
    if ( isOnFloor && potentialObjects.find(floorPlatform) == potentialObjects.end() )
    {
        isOnFloor = false;
        floorPlatform = NULL;
    }

    //0.2) Track changes in object size

    //Stick the object to the floor if its height has changed.
    if ( trackSize && isOnFloor && oldHeight != object->GetHeight() && !scene.IsFirstLoop() )
        object->SetY(object->GetY()+oldHeight-object->GetHeight());

    oldHeight = object->GetHeight();

    //1) X axis:

    //Shift the object according to the floor movement.
    if ( isOnFloor )
    {
        requestedDeltaX += floorPlatform->GetObject()->GetX() - floorLastX;
        requestedDeltaY += floorPlatform->GetObject()->GetY() - floorLastY;
    }

    //Move the object on x axis.
    double oldX = object->GetX();
    if ( requestedDeltaX != 0 )
    {
        object->SetX(object->GetX()+requestedDeltaX);
        //Colliding: Try to push out from the solid.
        //Note that jump thru are never obstacle on X axis.
        while ( IsCollidingWith(potentialObjects, floorPlatform, /*excludeJumpthrus=*/true) )
        {
            if ( (requestedDeltaX > 0 && object->GetX() <= oldX) ||
                 (requestedDeltaX < 0 && object->GetX() >= oldX) )
            {
                object->SetX(oldX); //Unable to move the object without being stuck in an obstacle.
                break;
            }

            //If on floor: try get up a bit to bypass not perfectly aligned floors.
            if ( isOnFloor )
            {
                object->SetY(object->GetY()-1);
                if ( !IsCollidingWith(potentialObjects, floorPlatform, /*excludeJumpthrus=*/true) )
                    break;
                object->SetY(object->GetY()+1);
            }

            object->SetX(floor(object->GetX())+(requestedDeltaX > 0 ? -1 : 1));
            currentSpeed = 0; //Collided with a wall
        }
    }

    //2) Y axis:

    //Go on a ladder
    ladderKey |= !ignoreDefaultControls && sf::Keyboard::isKeyPressed(sf::Keyboard::Up);
    if (ladderKey && IsOverlappingLadder(potentialObjects))
    {
        canJump = true;
        isOnFloor = false;
        floorPlatform = NULL;
        currentJumpSpeed = 0;
        currentFallSpeed = 0;
        isOnLadder = true;
    }

    if ( isOnLadder )
    {
        upKey |= !ignoreDefaultControls && sf::Keyboard::isKeyPressed(sf::Keyboard::Up);
        downKey |= !ignoreDefaultControls && sf::Keyboard::isKeyPressed(sf::Keyboard::Down);
        if ( upKey )
            requestedDeltaY -= 150*timeDelta;
        if ( downKey )
            requestedDeltaY += 150*timeDelta;

        //Coming to an extremity of a ladder
        if ( !IsOverlappingLadder(potentialObjects) )
        {
            isOnLadder = false;
        }
    }

    //Fall
    if (!isOnFloor && !isOnLadder)
    {
        currentFallSpeed += gravity*timeDelta;
        if ( currentFallSpeed > maxFallingSpeed ) currentFallSpeed = maxFallingSpeed;

        requestedDeltaY += currentFallSpeed*timeDelta;
        requestedDeltaY = std::min(requestedDeltaY, maxFallingSpeed*timeDelta);
    }

    //Jumping
    jumpKey |= !ignoreDefaultControls && (sf::Keyboard::isKeyPressed( sf::Keyboard::LShift ) || sf::Keyboard::isKeyPressed( sf::Keyboard::RShift ) );
    if ( canJump && jumpKey )
    {
        jumping = true;
        canJump = false;
        //isOnFloor = false; If floor is a very steep slope, the object could go into it.
        isOnLadder = false;
        currentJumpSpeed = jumpSpeed;
        currentFallSpeed = 0;
        //object->SetY(object->GetY()-1);
    }

    if ( jumping )
    {
        requestedDeltaY -= currentJumpSpeed*timeDelta;
        currentJumpSpeed -= gravity*timeDelta;
        if ( currentJumpSpeed < 0 )
        {
            currentJumpSpeed = 0;
            jumping = false;
        }
    }

    //Follow the floor
    if ( isOnFloor )
    {
        if ( object->IsCollidingWith(floorPlatform->GetObject()) )
        {
            //Floor is getting up, as the object is colliding with it.
            double oldY = object->GetY();
            int step = 0;
            bool stillInFloor = false;
            do
            {
                if ( step >= floor(abs(requestedDeltaX*slopeClimbingFactor)) ) //Slope is too step ( > max angle )
                {
                    object->SetY(object->GetY()-(abs(requestedDeltaX*slopeClimbingFactor)-(double)step)); //Try to add the decimal part.
                    if ( object->IsCollidingWith(floorPlatform->GetObject()) )
                        stillInFloor = true; //Too steep.

                    break;
                }

                //Try to get out of the floor.
                object->SetY(object->GetY()-1);
                step++;
            }
            while ( object->IsCollidingWith(floorPlatform->GetObject() ) );

            if ( stillInFloor )
            {
                object->SetY(oldY); //Unable to follow the floor ( too steep ): Go back to the original position.
                object->SetX(oldX); //And also revert the shift on X axis.
            }
        }
        else
        {
            //Floor is flat or get down.
            double oldY = object->GetY();
            object->SetY(object->GetY()+1);
            int step = 0;
            bool noMoreOnFloor = false;
            while ( !IsCollidingWith(potentialObjects) )
            {
                if ( step > abs(requestedDeltaX*slopeClimbingFactor) ) //Slope is too step ( > 50% )
                {
                    noMoreOnFloor = true;
                    break;
                }

                //Object was on floor, but no more: Maybe a slope, try to follow it.
                object->SetY(object->GetY()+1);
                step++;
            }
            if ( noMoreOnFloor )
                object->SetY(oldY); //Unable to follow the floor: Go back to the original position. Fall will be triggered next tick.
            else
                object->SetY(object->GetY()-1); //Floor touched: Go back 1 pixel over.
        }

    }

    //Move the object on Y axis
    if ( requestedDeltaY != 0 )
    {
        double oldY = object->GetY();
        object->SetY(object->GetY()+requestedDeltaY);

        //Stop when colliding with an obstacle.
        while (  (requestedDeltaY < 0 && IsCollidingWith(potentialObjects, NULL, /*excludeJumpThrus=*/true)) //Jumpthru = obstacle <=> Never when going up
              || (requestedDeltaY > 0 && IsCollidingWith(potentialObjects, overlappedJumpThru)) ) //Jumpthru = obstacle <=> Only if not already overlapped when goign down
        {
            jumping = false;
            currentJumpSpeed = 0;
            if ( (requestedDeltaY > 0 && object->GetY() <= oldY) ||
                 (requestedDeltaY < 0 && object->GetY() >= oldY) )
            {
                object->SetY(oldY); //Unable to move the object without being stuck in an obstacle.
                break;
            }

            object->SetY(floor(object->GetY())+(requestedDeltaY > 0 ? -1 : 1));
        }

    }

    //3) Update the current floor data for the next tick:
    overlappedJumpThru = GetJumpthruCollidingWith(potentialObjects);
    if ( !isOnLadder )
    {
        //Check if the object is on a floor:
        //In priority, check if the last floor platform is still the floor.
        double oldY = object->GetY();
        object->SetY(object->GetY()+1);
        if ( isOnFloor && object->IsCollidingWith(floorPlatform->GetObject() ) )
        {
            //Still on the same floor
            floorLastX = floorPlatform->GetObject()->GetX();
            floorLastY = floorPlatform->GetObject()->GetY();
        }
        else
        {
            //Check if landing on a new floor: (Exclude already overlapped jump truh)
            std::set<PlatformAutomatism*> collidingObjects = GetPlatformsCollidingWith(potentialObjects, overlappedJumpThru);
            if ( !collidingObjects.empty() ) //Just landed on floor
            {
                isOnFloor = true;
                canJump = true;
                jumping = false;
                currentJumpSpeed = 0;
                floorPlatform = *collidingObjects.begin();
                floorLastX = floorPlatform->GetObject()->GetX();
                floorLastY = floorPlatform->GetObject()->GetY();
                currentFallSpeed = 0;
            }
            else //In the air
            {
                canJump = false;
                isOnFloor = false;
                floorPlatform = NULL;
            }
        }
        object->SetY(oldY);
    }

    //4) Do not forget to reset pressed keys
    leftKey = false;
    rightKey = false;
    ladderKey = false;
    upKey = false;
    downKey = false;
    jumpKey = false;

    //5) Track the movement
    hasReallyMoved = abs(object->GetX()-oldX) >= 1;
}