Animation pick up an object synchronized with disappearance of the obj (SOLVED)

Started by PERXEO, Wed 12/04/2023 21:46:22

Previous topic - Next topic

PERXEO

I have an animation where a character reaches down to pick up something on the ground, but I can't make the object disappear at just the right moment. The animation is too long and I wish it could know exactly which frame the frame where the object is taken is in, to make a call just at that moment so that it disappears at the right moment. I've sometingh like that:

PERXEO

Code: ags
function oCacerolas_PickUp()
{
 cPerxeo.Walk(1037, 938, eBlock, eWalkableAreas);
  cPerxeo.FaceDirection(eDirectionUpRight);
  cPerxeo.LockView(3);
  cPerxeo.Animate(0, 0, eOnce, eBlock);
  Wait(2);
  oCacerolas.Visible=false;
  player.AddInventory(iCacerolas);
  cPerxeo.Say("I've the pans with me!!!.");
  cPerxeo.LockView(1);
  cPerxeo.UnlockView();
  cPerxeo.FaceDirection(eDirectionUpRight);
  
}

Crimson Wizard

The solution is to run animation non-blocking and then wait until it finishes right in the same function.
If you will additionally check for the current frame, you will know when to do object changes.

Code: ags
cPerxeo.LockView(3);
cPerxeo.Animate(0, 0, eOnce, eNoBlock); // notice eNoBlock
while (cPerxeo.Animating)
{
    if (cPerxeo.Frame == SOME_FRAME)
        oCacerolas.Visible=false;
    Wait(1); // Wait lets engine to update and redraw the scene
}
cPerxeo.UnlockView();
player.AddInventory(iCacerolas);
cPerxeo.Say("I've the pans with me!!!.");

I also removed unnecessary LockView(1), and moved UnlockView right to where animation completes.

Note that if cPerxeo is a player character, you could just write player everywhere. This is recommended to do, in case something changes about the character, or you will have a game where player character may be switched for any reason.

Crimson Wizard

If you are going to have a lot of items picked up like that, I may also suggest to write a global function that does most things. This way you will be able to reduce code duplication - that is write the basic algorithm once, and then just call it with some parameters.

For example:
in GlobalScript.asc
Code: ags
function PickupObject(Object *obj, InventoryItem *itemToAdd, eDirection dirToFace)
{
    player.FaceDirection(dirToFace);
    player.LockView(3);
    player.Animate(0, 0, eOnce, eNoBlock);
    while (player.Animating)
    {
        if (player.Frame == SOME_FRAME)
            obj.Visible=false;
        Wait(1); // Wait lets engine to update and redraw the scene
    }
    player.UnlockView();
    player.AddInventory(itemToAdd);
}

in GlobalScript.ash (header)
Code: ags
import function PickupObject(Object *obj, InventoryItem *itemToAdd, eDirection dirToFace);

Then in the room script you may do this:
Code: ags
function oCacerolas_PickUp()
{
    player.Walk(1037, 938, eBlock, eWalkableAreas);
    PickupObject(oCacerolas, iCacerolas, eDirectionUpRight);
    player.Say("I've the pans with me!!!.");
}

function oAnotherObject_PickUp()
{
    player.Walk(1037, 938, eBlock, eWalkableAreas);
    PickupObject(oAnotherObject, iAnotherObject, eDirectionDown);
    player.Say("I got AnotherObject!");
}

You may add more parameters to this, or reuse existing ones for other purposes. For example, you may use dirToFace parameter to select an animation loop: this will let you to play different animations depending on which direction the character is facing.


SMF spam blocked by CleanTalk