Author Topic: Background NPCs walk and wait  (Read 278 times)

Background NPCs walk and wait
« on: 30 Jul 2020, 17:03 »
Hi all

I'm wanting NPC characters to walk around in the background, wait for a little while and then move to a new point. I was wandering if there is Wait(#) but a wait that doesn't block. Or would I require timers? I'm just asking because I can't find anything in the manual but could just be searching for the wrong thing...

Would would be the best practice??

Re: Background NPCs walk and wait
« Reply #1 on: 30 Jul 2020, 17:43 »
I did this exact thing once, but unfortunately I didn't end up using it and deleted my code :-\

I do remember that I did indeed use timers. The logic I used was to check in repeatedly_execute_always whether the character is walking or not, and if it's stopped + there is no timer already running, start a timer. You would also check if the timer has expired and in that case, move the character to the next waypoint.

Would this be enough to get you started?

Cassiebsg

  • Cavefish
  • Fleeing the Cylon tyrrany...
    • Cassiebsg worked on one or more games that won an AGS Award!
    •  
    • Cassiebsg worked on one or more games that was nominated for an AGS Award!
Re: Background NPCs walk and wait
« Reply #2 on: 30 Jul 2020, 18:00 »
Yes, that is basically it.
Define your point A, B, C, etc. They all have a x,y coord. Then get them moving to A with Noblock, and check in rep_exec if they are moving and if not if they have reached the destiny (if they haven't reached the destiny, just move them to it again, otherwise start a wait or animation, or whatever they should be doing while there.  Then send the NPC to point B, check if he's moving and if he's reached the destiny... repeat the process. :)

I did this in my game "Out of Gas".

Once I had the code up, it took me about 10 minutes to add an NPC, including creating the NPC, render it, import the sprites, add a new character with the corresponding views and adding him to the room and the walking path.  ;)

If you can't figure it out by your self, I can post the code later.
There are those who believe that life here began out there...

Re: Background NPCs walk and wait
« Reply #3 on: 30 Jul 2020, 21:37 »
Thanks guys, I don't need to see any code, I was just curious if there were different ways. Timers will suffice  (nod)

Cheers

Re: Background NPCs walk and wait
« Reply #4 on: 31 Jul 2020, 01:47 »
Ok, I may need a little help as this isn't going well haha

Code: Adventure Game Studio
  1. // room script file
  2. function room_AfterFadeIn()
  3. {
  4.   SetTimer(1, 200);
  5. }
  6.  
  7.  
  8. function room_RepExec()
  9. {
  10.   if (!cMan1.Moving)
  11.   {
  12.     if (IsTimerExpired(1) && cMan1.x==327)
  13.     {
  14.       cMan1.Walk(564, 372, eNoBlock, eWalkableAreas);
  15.       cMan1.FaceDirection(eDirectionUp, eNoBlock);
  16.       SetTimer(1, 200);
  17.     }
  18.     if (IsTimerExpired(1) && cMan1.x==564)
  19.     {
  20.       cMan1.Walk(418, 406, eNoBlock, eWalkableAreas);
  21.       cMan1.FaceCharacter(cFemale4, eNoBlock);
  22.       cFemale4.FaceCharacter(cMan1, eNoBlock);
  23.       SetTimer(1, 240);
  24.     }
  25.     if (IsTimerExpired(1) && cMan1.x==418)
  26.     {
  27.       cMan1.Walk(563, 372, eNoBlock, eWalkableAreas);
  28.       cMan1.FaceDirection(eDirectionUp, eNoBlock);
  29.       SetTimer(1, 240);
  30.     }
  31.     if (IsTimerExpired(1) && cMan1.x==563) //Start Location
  32.     {
  33.       cMan1.Walk(327, 487, eNoBlock, eWalkableAreas);
  34.       cMan1.FaceDirection(eDirectionDown, eNoBlock);
  35.       SetTimer(1, 240);
  36.     }
  37.   }
  38. }
  39.  

That's what I have in my room script, it's probably terrible but I'm no coder....and as predicted my NPC is doing some odd things.
« Last Edit: 31 Jul 2020, 02:01 by The creature »

Re: Background NPCs walk and wait
« Reply #5 on: 31 Jul 2020, 05:38 »
The problem you have here is that you're triggering the walk command and then immediately facing another direction and triggering the timer, so all these commands get run right one after the other. Like I said at first, you need to check if the timer is running, and if it's not, then start it. And you need to do things like facing a certain direction on arrival, not on departure, so to say.

Unfortunately, as far as I know, AGS has no way to track if a timer is running, so we'll have to use a variable for that ("but what about IsTimerExpired?", you say. The problem with that is that IsTimerExpired only gets checked once, and then the timer is disabled, so it's not a real "is timer running" check). Put this at the top of your room script, outside any functions:

Code: Adventure Game Studio
  1. bool istimerruning = true;

Now set your first timer, like you did in your code:
Code: Adventure Game Studio
  1. function room_AfterFadeIn()
  2. {
  3.   SetTimer(1, 200);
  4. }

And now try this in repeatedly_execute_always, not rep_Exec.

Code: Adventure Game Studio
  1. function repeatedly_execute_always()
  2. {
  3.  
  4.   if (!Man1.Moving) {
  5.    
  6.     if (!istimerruning) {
  7.       if (cMan1.x == 564) {
  8.         cMan1.FaceDirection(eDirectionUp, eNoBlock);
  9.         SetTimer(1, 200);
  10.       }
  11.       if (cMan1.x == 418) {
  12.         cMan1.FaceCharacter(cFemale4, eNoBlock);
  13.         cFemale4.FaceCharacter(cMan1, eNoBlock);
  14.         SetTimer(1, 240);
  15.       }
  16.       if (cMan1.x == 563) {
  17.         cMan1.FaceDirection(eDirectionUp, eNoBlock);
  18.         SetTimer(1, 240);
  19.       }
  20.       if (cMan1.x == 327) {
  21.         cMan1.FaceDirection(eDirectionDown, eNoBlock);
  22.         SetTimer(1, 240);
  23.       }
  24.       istimerruning = true;
  25.     }
  26.    
  27.     if (IsTimerExpired(1)){
  28.       if (cMan1.x == 327) cMan1.Walk(564, 372, eNoBlock, eWalkableAreas);
  29.       if (cMan1.x == 564) cMan1.Walk(418, 406, eNoBlock, eWalkableAreas);
  30.       if (cMan1.x == 418) cMan1.Walk(563, 372, eNoBlock, eWalkableAreas);
  31.       if (cMan1.x == 563) cMan1.Walk(327, 487, eNoBlock, eWalkableAreas);
  32.       istimerruning = false;
  33.     }
  34.    
  35.   }
  36.  
  37. }

The logic here is:
- Is the character moving? If it is, do nothing.

- If not moving, is a timer running?
- If no timer is running, then it means we just got to our destination. In this case, face towards the appropriate direction and now we start the timer and set istimerrunning to true.

- Is the timer expired?
- If it's not, do nothing.
- If it is, set istimerrunning to false and tell the character to move to the next spot.

Let me know if it works!
« Last Edit: 31 Jul 2020, 11:19 by Laura Hunt »

Re: Background NPCs walk and wait
« Reply #6 on: 31 Jul 2020, 08:15 »
The coordinate check should probably use ranges, to prevent the NPC from accidentally ceasing to move.
Fail at Floaty Rog' now!  still having to deal with what games are going through

Re: Background NPCs walk and wait
« Reply #7 on: 31 Jul 2020, 08:56 »
You could also use a small region at every waypoint and check if the NPC is inside it, but why would this be necessary? What could make a NPC stop moving accidentally?

Re: Background NPCs walk and wait
« Reply #8 on: 31 Jul 2020, 14:48 »
Thanks, that works great Laura. Looking at the code it makes perfect sense but it's not something I'd have figured out myself.

So thank you again 💖

Re: Background NPCs walk and wait
« Reply #9 on: 31 Jul 2020, 17:39 »
Happy to know! :)

Earlier today I remembered that the way I did it in my game was not by checking the coordinates but by using four different timers, one for each waypoint. Checking which timer has expired tells you which waypoint you're at, and thus to which one you should go next (if timer 2 has expired, then you need to move to point 3, and so on). The advantage of this is that if the NPC stops before reaching a waypoint for any reason, he won't just stand there forever but he'll head to the next scheduled point once the timer has run out. You could try coding this variant yourself as an exercise if you feel like it!

Re: Background NPCs walk and wait
« Reply #10 on: 31 Jul 2020, 17:49 »
Unfortunately, as far as I know, AGS has no way to track if a timer is running, so we'll have to use a variable for that ("but what about IsTimerExpired?", you say. The problem with that is that IsTimerExpired only gets checked once, and then the timer is disabled, so it's not a real "is timer running" check).

I wrote alternate Timer module a while ago: https://www.adventuregamestudio.co.uk/forums/index.php?topic=55545.0

Among other things it allows to test if timer is active.

Re: Background NPCs walk and wait
« Reply #11 on: 31 Jul 2020, 19:18 »
I'll check out the module CW. it might make things more manageable as I'll need a lot of timers for different NPC's going about.

X