Trying to get get an NPC to move around the room randomly in the background.

Started by ShiningRice, Thu 05/04/2018 03:48:47

Previous topic - Next topic

ShiningRice

I want an NPC to move around the room randomly, but I also want it to run in the background. Everytime I change eBlock to eNoBlock it doesn't work. I tried adding a timer to see if that would fix it, but it still doesn't work. I checked all over forums and I couldn't find my answer. Any ideas? Does anyone understand what I am trying to do?

int manY;
int manX;
function room_AfterFadeIn()
{
manX=160;
manY=100;
}
function room_RepExec()
{
if ((cChar1.x == manX) && (cChar1.y == manY) && (IsTimerExpired(1)))
  SetTimer(1,5000);
  manX=Random(280);
  manY=Random(173);
  cChar1.Move(manX, manY, eBlock);
}

Privateer Puddin'

Are you also setting the timer outside of your if? If not, it won't have expired to activate it.

Slasher


Khris

Quote from: Slasher on Thu 05/04/2018 07:55:46
And all Timers must come first in the condition.
That's nonsense, both as a general rule and in this case specifically. If the timer expired before the character has reached her goal, the movement would end for good, since the condition never evaluated to true.

ShiningRice: "it doesn't work" is not a useful problem description. What happens exactly? Does the character never move? Move once?

Slasher


ShiningRice

Sorry for lack of clarification. The character actually moves around randomly, but its at full speed. The timer in the if doesn't even seem to matter. The problem is if I change eBlock to eNoBlock. The cChar1 doesn't move at all and I want to know why.

Khris

So you do have an initial SetTimer call somewhere in the part of the script you didn't post?

ShiningRice

No I do not have an initial SetTimer call somewhere else in the script

Snarky

Note the lack of braces around the if-block...

It becomes easier to see if you format and indent the code correctly:

Code: ags

int manY;
int manX;

function room_AfterFadeIn()
{
  manX=160;
  manY=100;
}

function room_RepExec()
{
  if ((cChar1.x == manX) && (cChar1.y == manY) && (IsTimerExpired(1)))
    SetTimer(1,5000);
  manX=Random(280);
  manY=Random(173);
  cChar1.Move(manX, manY, eBlock);
}


As you can now easily see, only the SetTimer() call is subject to the if-clause â€" manX and manY are randomized every game loop (while the game is not blocking), and the character directed to move to that position. As long as the Move call is blocking, this will have the character moving around all the time. If it is made non-blocking, the character will be redirected to different coordinates before the move gets started, and will probably end up standing still, or possibly shaking slightly.

ShiningRice

So I need to have a pair of braces around all the calls that follow the IF statement?

Snarky

Yes, around all the lines that should only be executed if the if-condition is true, just the same way you have braces around all the lines that belong to a particular function. That's how you group lines together into a "block" of code.

Then you also need to set the timer in room_AfterFadeIn() to start the whole thing off (otherwise the if-condition will never be true and none of it will ever run), and after that it should work either blocking or non-blocking.

(Assuming the character can never be sent to a coordinate outside his walkable area. If that happens, he will stop without reaching it, and will therefore never be sent anywhere else.)

Khris

Code: ags
int manY;
int manX;

function room_AfterFadeIn()
{
  manX=160;
  manY=100;
  SetTimer(1, 1); 
}

function room_RepExec()
{
  if (cChar1.x == manX && cChar1.y == manY && IsTimerExpired(1)) {
    while (true) {
      manX=Random(280);
      manY=Random(173);
      if (GetWalkableAreaAt(manX, manY) > 0) break;  // screen coords!
    }
    cChar1.Move(manX, manY, eBlock);
    SetTimer(1, 50);
  }
}


This should do it.


SMF spam blocked by CleanTalk