Multiple orders in room event

Started by vrazumijin, Thu 06/06/2024 23:04:21

Previous topic - Next topic

vrazumijin

Hello. Can someone explain me why this works

Code: ags
function room_AfterFadeIn() {

   cGallo.Walk(1000, 1020,  eBlock); 
   cGallo.Walk(400, 1020,  eBlock); 
   cGallo.Walk(1000, 1020,  eBlock); 
   cGallo.Walk(400, 1020,  eBlock); 
   cGallo.Walk(1000, 1020,  eBlock); 
   cGallo.Walk(400, 1020,  eBlock); 
}

but this doesn't?


Code: ags
function room_AfterFadeIn() {

   cGallo.Walk(1000, 1020,  eNoBlock); 
   cGallo.Walk(400, 1020,  eNoBlock); 
   cGallo.Walk(1000, 1020,  eNoBlock); 
   cGallo.Walk(400, 1020,  eNoBlock); 
   cGallo.Walk(1000, 1020,  eNoBlock); 
   cGallo.Walk(400, 1020,  eNoBlock); 
}

in this second version, the character just walks directly to the final point, how can I get a character to execute multiple walk commands without stoping the main action?

thanks

AndreasBlack

#1
Look up SetTimer and eBlock. You can type it in any AGS script then push F1 right after and you'll see the manual explain it and usually there's an example too! Very handy for us beginners! ;) 
Now go into global variables and add an int called Gallo_BG_Walking set it to 0. If you plan to use the NPC (A qualified guess) walking around in the bakground while still being able to control your main character.
Then you can do this. But first you need to set up the Timer. Again look in the manual! :)
I haven't used AGS in a while there's probably an easier way to do this, but this is one way. :)

Code: ags
 

function room_RepExec(){

 if (Gallo_BG_Walking==0)
{
  
  cGallo.Walk(570, 145, eNoBlock, eWalkableAreas); 
  SetTimer(20, 300);
  Gallo_BG_Walking=1; //Now the if statement bellow which checks for Gallo_BG_Walking==1 will be active
                                         //Well...After the Timer has run out
  
  }
  
  if (Gallo_BG_Walking==1 && IsTimerExpired(20)) 


{
  cGallo.Walk(471, 145, eNoBlock, eWalkableAreas);
SetTimer(20, 140);
   Gallo_BG_Walking=2;
 
}

  if (Gallo_BG_Walking==2 && IsTimerExpired(20))


{

  Gallo_BG_Walking=0; //Now he restarts his walking path.
    
}

}

vrazumijin

Thanks so much for your help, I wasnt aware about timers, I'm sure it will be usefull, but its still not working.

Your code only makes the NPC (you were right) to perform the first movement, but it fails to perform the second and just stays still.

I've run into this problem before, I can create global variables, but when I try to change their value through the code I don't seem to be capable of making it work.

Any ideas?

Khris

#3
Try this version:

Code: ags
bool walking_right; // initially false

function room_RepExec()
{
  if (!cGallo.Moving) {
    if (!walking_right) cGallo.Walk(1000, 1020); 
    else cGallo.Walk(400, 1020); 
    walking_right = !walking_right;
  }
}

edit: fixed typo

FortressCaulfield

It's the noblock. Script isn't blocked from progressing, so your char will spend exactly one frame on each of the first 5 commands before doing the second.

There's also a waypoint system you might want to look it.

It seems like you're trying to just make a char walk back and forth. The best way I found is to put something in the room's repeatedly execute, or, if it has to happen even during other blocked animations, in global repeatedly execute always.

Code: ags
if (player.Room == whateverroomthisis)
  if (cGallo.x == 400) cGallo.Walk(1000, 1020);
  else if (cGallo.x == 1000) cgallo.Walk(400,1020);

Something like that
"I can hear you! My ears do more than excrete toxic mucus, you know!"

-Hall of Heroes Docent, Accrual Twist of Fate

vrazumijin

#5
Thanks for your answers, but still not working

I tried your code, FortressCaulfield, phrased like this

Code: ags
function room_RepExec()
{
if (player.Room == 6){
  if (cGallo.x == 400){ 
          cGallo.Walk(1000, 1020);
          }
  
  else if (cGallo.x == 1000) {
          cGallo.Walk(400, 1020);
          }

}
}

And the character performs the walking animation while staying at the starting position. I don't get it.

Khris, thank u for your input too, but in your code the movement of the NPC would depend on the main characters move, and I need the NPC to move regardless what the character does. I tried your code anyway just to find out, but it doesnt compile (Error (line 22): undefined symbol 'walking_right'), and I dont know the proper way to phrase it.


In case you are interested, the NPC is a rooster ("gallo" is spanish for rooster) wandering in the background of a farm. I thought this kind of think would be the easiest thing to do...

Snarky

#6
Khris made a small mistake in his code. It should be:

Code: ags
bool walking_right; // initially false

function room_RepExec()
{
  if (!cGallo.Moving) {
    if (!walking_right) cGallo.Walk(1000, 1020); 
    else cGallo.Walk(400, 1020); 
    walking_right = !walking_right;
  }
}

Quote from: vrazumijin on Sat 08/06/2024 03:54:24I tried your code anyway just to find out, but it doesnt compile (Error (line 22): undefined symbol 'walking_right'), and I dont know the proper way to phrase it.

Are you sure you included the first line of code in the example?

Quote from: vrazumijin on Sat 08/06/2024 03:54:24I thought this kind of think would be the easiest thing to do...

It's not hard to do. The problem is that it's easy to get it slightly wrong. So it's useful to understand why the different proposals break.

With FortressCaulfield's version, first of all the recommendation to put it in global repeatedly_execute_always() is wrong. You cannot call blocking functions from repeatedly_execute_always(). Since it is anyway only supposed to run within one room, you should (as you have done) put it in room_RepExec(), which is the room-equivalent of repeatedly_execute(), and then you don't need to check that you're in the right room either.

Second, I would first wonder whether there is a walkable area where cGallo is standing. If not, the character won't be able to walk using this command, and this may explain why it's just moving in place there.

Third, since it doesn't use non-blocking walk, I would expect the game to freeze while it is running (which is all the time in the room), so the player won't be able to do anything.

Finally, if you do turn on the non-blocking parameter in this version, it will break because it doesn't check whether the character is already moving before commanding it to walk (it checks the coordinate, but that won't change immediately when the walk starts). Therefore, it will keep commanding the character to walk every game cycle, and this will reset the walk (the internal counter that tells it when to actually start moving) so that it never actually moves.

AndreasBlack's code looks correct (apart from horrendously wrong indentation and formatting of the {} braces), but it will introduce a pause of some seconds between each walk. If you want the next movement to begin as soon as the last one is complete, you should replace all the IsTimerExpired() checks with !cGallo.Moving.

As for the idea that you're unable to set global variables, that's certainly not the case: the likely explanation is that some code that you assume is running never actually runs.

Khris

Thanks @Snarky, I tested my code with the player character and forgot to change it :)

@vrazumijin Leaving aside my player/cGallo mistake, the bool is defined right there in the first line of my snippet, and you were supposed to also put that in your own room script obviously.

vrazumijin

Quote from: Khris on Sat 08/06/2024 09:55:42Leaving aside my player/cGallo mistake, the bool is defined right there in the first line of my snippet, and you were supposed to also put that in your own room script obviously.

Yeah, that was the problem, i mistakenly did not copy your first line. I dont want this particular NPC to respond to the characters movement, but its something I also wanted to know how to do for another part of the game. Thanks a lot

Quote from: Snarky on Sat 08/06/2024 07:11:25AndreasBlack's code looks correct (apart from horrendously wrong indentation and formatting of the {} braces), but it will introduce a pause of some seconds between each walk. If you want the next movement to begin as soon as the last one is complete, you should replace all the IsTimerExpired() checks with !cGallo.Moving.


That works. Thank U so much. Also,  your comprehensive explanation has been of much help


this community is great. thanks all

SMF spam blocked by CleanTalk