what is causing this eBlock?

Started by Seventeen Uncles, Fri 24/10/2014 13:21:33

Previous topic - Next topic

Seventeen Uncles

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:

Code: ags

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);
  }
}




which as you can see from
Code: ags
cTurtle.Animate(1, 50, eOnce, eNoBlock);
until
Code: ags
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!

Gurok

#1
Waits are blocking and timers are rather fragile. Try a room variable instead (untested):

Code: ags

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;
				}
}
[img]http://7d4iqnx.gif;rWRLUuw.gi

Crimson Wizard

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.

Gurok

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.
[img]http://7d4iqnx.gif;rWRLUuw.gi

Crimson Wizard

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.

Seventeen Uncles

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):

Code: ags

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!


monkey0506

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:

Code: ags
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.).

SMF spam blocked by CleanTalk