NPC wandering around with occasional animations

Started by birenbergg, Tue 19/06/2018 23:54:21

Previous topic - Next topic

birenbergg

Hi.

I'd like to implement the following functionality. An NPC aimlessly wanders around the room â€" from point to point â€" and when he stops at the point, a small animation is played.

I tried something like this to make him wander around, which is working.

Code: ags

if (!cNpc.Moving) {
    int x = Random(Room.Width);
    int y = Random(Room.Height);

    cNpc.Walk(x, y, eNoBlock, eWalkableAreas);
}


But when i try to add the animation part (into several wrong places)...

Code: ags

cNpc.LockView(222);
cNpc.Animate(cNpc.Loop, 0, eOnce, eNoBlock);
cNpc.UnlockView();


..it either stops the character's walking around, or freezes the whole game :-/

Any ideas?..

fernewelten

#1
Here's how I would try to code it:

So, the NPC character has two different “modes” or “states” she can operate in:

  • She's moving
  • She's standing still and animating.

Let's save in a variable what “mode” or “state” she is in.

Code: ags

enum tyNPCState {
        eNPCMoves = 1,
        eNPCAnimates = 2
};

tyNPCState NPCState;


(If you aren't comfortable with enum, then use the following code instead. It does the same thing in a simpler way:
Code: ags

int eNPCMoves = 1;
int eNPCAnimates = 2;

int NPCState; // will contain either eNPCMoves or eNPCAnimates

)

We need the values in  NPCState to be still available when the function ends - so be sure to declare NPCState outside the function body, before the function begins.

Whenever we start the character moving, we will also set NPCState to eNPCMoves.

So when she no longer moves, but still NPCState == eNPCMoves, we know that her moving action has just run out. That's the time to start her animating - and at the same time, we set NPCState to eNPCAnimates.

So later, the time will come when she no longer animates, but still NPCState == eNPCAnimates. This must mean that her animation has just run out. That's the time to start her moving again - and we've reached the end of a cycle that we can repeat indefinitely.

Let's put this into code:
The following should go into the "Repeatedly execute" function of the room.
Code: ags

if (!cNpc.Moving) {
    if (NPCState == eNPCMoves) {
        // The move action must have stopped just now. So startup the animate action:
        cNpc.LockView(222);
        cNpc.Animate(cNpc.Loop, 0, eOnce, eNoBlock);
        // Don't unlock the view just now, because the character is still happily animating away at the moment.

        // Remember in our state variable that our character has just begun the animate mode
        NPCState = eNPCAnimates; 
    }
}
if ((!cNpc.Moving) && (!cNpc.Animating)) {
    if (NPCState == eNPCAnimates) {
        // The Animate action must have run out just now. 
        // So now's a good time to unlock the view - since the character is no longer animating.
        cNpc.UnlockView();

        // Let's make the character walk
        int x = Random(Room.Width-1);
        int y = Random(Room.Height-1);
 
        cNpc.Walk(x, y, eNoBlock, eWalkableAreas);
        // and remember in our state variable that the character has entered her walk mode now.
        NPCState = eNPCMoves;
    }
}



In order to jump-start the cycle, we need to make her move once, at room fade-in, and then she will alternate moving and animating indefinitely on her own.
Code: ags

function room_AfterFadeIn()
{
    [...]
    int x = Random(Room.Width-1);
    int y = Random(Room.Height-1);
 
    cNpc.Walk(x, y, eNoBlock, eWalkableAreas);
    NPCState = eNPCMoves;
    [...]
}


Just my 2 pence,
P.

birenbergg


SMF spam blocked by CleanTalk