Hi Yall, just wrote some script for a NPC to throw a dart every few seconds, which should be happening in the background without any eBlock but something is causing one to happen (which would ruin the scene)
heres the code:
function room_Load()
{
oThrowDart.Transparency = 100;
SetTimer(1, 280);
}
function room_RepExec()
{
if (IsTimerExpired(1)){
int RandoDart;
cTurtle.Animate(1, 50, eOnce, eNoBlock);
Wait(140);
oThrowDart.Transparency =0;
RandoDart = Random(2);
if (RandoDart == 0) oThrowDart.Move(-100, 155, 8, eNoBlock, eAnywhere);
if (RandoDart == 1) oThrowDart.Move(-100, 240, 8, eNoBlock, eAnywhere);
if (RandoDart == 2) oThrowDart.Move(-100, 350, 8, eNoBlock, eAnywhere);
Wait(80);
oThrowDart.Transparency=100;
oThrowDart.Move(614, 480, 10, eNoBlock, eAnywhere);
Wait(80);
cTurtle.Animate(8, 50, eOnce, eNoBlock);
SetTimer(1, 280);
}
}
(https://33.media.tumblr.com/38cd969c4a0f3f3acc62b71deb9736b7/tumblr_ndy78iDbbD1tdsvaao1_1280.gif)
which as you can see from cTurtle.Animate(1, 50, eOnce, eNoBlock);
until cTurtle.Animate(8, 50, eOnce, eNoBlock);
blocks player actions despite putting eNoBlock's all over the place.
is there any way around this?
thanks in advanace!
Waits are blocking and timers are rather fragile. Try a room variable instead (untested):
int turn;
function room_RepExec()
{
int RandoDart;
turn++;
if(turn == 280)
cTurtle.Animate(1, 50, eOnce, eNoBlock);
else
if(turn == 420)
{
oThrowDart.Transparency = 0;
RandoDart = Random(2);
if(RandoDart == 0) oThrowDart.Move(-100, 155, 8, eNoBlock, eAnywhere);
if(RandoDart == 1) oThrowDart.Move(-100, 240, 8, eNoBlock, eAnywhere);
if(RandoDart == 2) oThrowDart.Move(-100, 350, 8, eNoBlock, eAnywhere);
}
else
if(turn == 500)
{
oThrowDart.Transparency = 100;
oThrowDart.Move(614, 480, 10, eNoBlock, eAnywhere);
}
else
if(turn == 580)
{
cTurtle.Animate(8, 50, eOnce, eNoBlock);
turn = 0;
}
}
Quote from: Gurok on Fri 24/10/2014 13:29:50timers are rather fragile.
A note should be made that calculating loops will make it depend on game speed settings.
Quote from: Crimson Wizard on Fri 24/10/2014 13:33:27
Quote from: Gurok on Fri 24/10/2014 13:29:50timers are rather fragile.
A note should be made that calculating loops will make it depend on game speed settings.
I thought timers and waits were already dependent on game speed settings.
Quote from: Gurok on Fri 24/10/2014 13:37:56
Quote from: Crimson Wizard on Fri 24/10/2014 13:33:27
Quote from: Gurok on Fri 24/10/2014 13:29:50timers are rather fragile.
A note should be made that calculating loops will make it depend on game speed settings.
I thought timers and waits were already dependent on game speed settings.
Yes... really. I forgot they take game loops for delay too.
For a real timer you would need to use DateTime class.
Quote from: Gurok on Fri 24/10/2014 13:29:50
Waits are blocking and timers are rather fragile. Try a room variable instead (untested):
int turn;
function room_RepExec()
{
int RandoDart;
turn++;
if(turn == 280)
cTurtle.Animate(1, 50, eOnce, eNoBlock);
else
if(turn == 420)
{
oThrowDart.Transparency = 0;
RandoDart = Random(2);
if(RandoDart == 0) oThrowDart.Move(-100, 155, 8, eNoBlock, eAnywhere);
if(RandoDart == 1) oThrowDart.Move(-100, 240, 8, eNoBlock, eAnywhere);
if(RandoDart == 2) oThrowDart.Move(-100, 350, 8, eNoBlock, eAnywhere);
}
else
if(turn == 500)
{
oThrowDart.Transparency = 100;
oThrowDart.Move(614, 480, 10, eNoBlock, eAnywhere);
}
else
if(turn == 580)
{
cTurtle.Animate(8, 50, eOnce, eNoBlock);
turn = 0;
}
}
works perfectly. i'll use room variables in future.
thanks very much!
Quote from: Crimson Wizard on Fri 24/10/2014 13:45:01For a real timer you would need to use DateTime class.
AGS can't do anything faster than 1 game frame (game logic loop and drawing loop are tied together ATM), so actually GetGameSpeed is the most accurate for cases like this. You could approximate milliseconds by doing:
int GetApproxMSInGameLoops(int targetMS, RoundDirection dir) // dir default is eRoundNearest
{
float fresult = (IntToFloat(targetMS) / IntToFloat(GetGameSpeed())) / 1000.0; // (ms*40)/1000 for default game speed
return FloatToInt(fresult, dir);
}
Of course a larger increment of time can be exactly precise (seconds = X * GetGameSpeed(), etc.).