I'm having trouble with using callroomscript when calling a function that has integers in it.
I get errors when trying to call animateoverlay().
function animateoverlay(Overlay* selectedoverlay, int Xposition, int Yposition, int startsprite,int endsprite, int transparent, int repeatoronce)
{
selectedoverlay=Overlay.CreateGraphical(Xposition, Yposition, startsprite,transparent);
selectedoverlay.Remove();
startsprite+=1;
if(startsprite!=endsprite)
{
CallRoomScript(animateoverlay(Overlay* selectedoverlay,int Xposition,int Yposition,int startsprite,int endsprite,int transparent,int repeatoronce));
}
else
{
if(repeatoronce==repeat)
{
startsprite=0;
}
if(repeatoronce==once)
{
selectedoverlay.Remove();
}
}
At first I tried a simple CallRoomScript(animateoverlay());
But it wasn't enough parameters.
Then I tried CallRoomScript(animateoverlay(Overlay* selectedoverlay,int Xposition,int Yposition,int startsprite,int endsprite,int transparent,int repeatoronce)); ,but it had a parse error in expression near int.
What am I doing wrong.
Also does anyone know a better way of animating overlays?
Thanks.
What is it you are trying to do with CallRoomScript here, how is it related to animating the overlay?
CallRoomScript is called with 1 parameter: an integer number. You are placing a function call there instead, or so it seems. Are you trying to pass a return value from function animateoverlay into CallRoomScript? Or are you trying to call this function from within the room script?.... I am puzzled.
Also, I think you need to fix the order of the first two lines, like this:
if (selectedoverlay != null)
selectedoverlay.Remove(); // remove previous overlay if it exists
selectedoverlay=Overlay.CreateGraphical(Xposition, Yposition, startsprite,transparent);
Otherwise your overlay will be removed right after creation.
I was assuming that custom functions don't automatically loop.Do they?I haven't actually tested this yet where it gets past the errors so I don't know.I was trying to get it to loop until its finished animating from startsprite to endsprite.So I want the function to loop until a set condition.I did loop a function before but it was only one without any parameters.
Quote
if (selectedoverlay != null)
selectedoverlay.Remove(); // remove previous overlay if it exists
selectedoverlay=Overlay.CreateGraphical(Xposition, Yposition, startsprite,transparent);
Thanks that helps some.
Quote from: Pajama Sam on Sat 23/04/2022 01:20:51
I was assuming that custom functions don't automatically loop.Do they?I haven't actually tested this yet where it gets past the errors so I don't know.I was trying to get it to loop until its finished animating from startsprite to endsprite.So I want the function to loop until a set condition.I did loop a function before but it was only one without any parameters.
Ah, okay, that explains your intent.
May you tell, why do you use Overlays for animation? Overlays have to be animated manually in script, but there's also GUI buttons that have Animate command that does everything for you.
If you're positive that you really must animate an overlay, first of all you got to decide if this function will be blocking or non-blocking as they have to be dealt with differently. Are you intending to call this function repeatedly from somewhere, or want the whole animation to happen inside the function, and then return to whatever place you called it?
Why do you pass Overlay pointer in it, does it have any meaning? Problem is, this pointer "selectedoverlay" will be considered a local variable in this function, and any changes to it will be lost as soon as the function ends.
I would use overlays for temporary visual animations that are too time consuming to make objects just for something that lasts for a moment.
The function should be non-blocking.I don't know how to do that.
I want the whole animation to happen inside the function.
////////////////////////////////////////////////////////////////////////// (overlay,Xposition,Yposition,startsprite,endsprite,transparent,repeatoronce)
So if I had an overlay called "blah"and I would type animateoverlay(blah ,320 , 320 ,2 ,13 ,true ,once)
There are two global integers called repeat and once.
repeat=1
once=0
So if repeatoronce was input as once the function should repeat until it finishes animating and if repeatoronce was input as repeat the function should keep looping forever.Although I don't think I will ever need to repeat it forever.I would at least like for it to run through the sprites once.
The first time the overlay is created its sprite number should equal 2(the startsprite) and add 1 until it reaches 13(endsprite).
You probably already knew all that but at least I hope I made it evinced.
Can't it create the overlay again when it finishes?
Hmm,
non-blocking functions are more complicated, because in this case whole animation simply cannot happen inside this function. Instead, you need to call it from "repeatedly_execute" using some timer between calls and condition that tells you that animation is going on. Also you have to store all parameters somewhere, in global variables, while overlay is animating.
To clarify:
1) if the animation is blocking, then whole animation, and its loop, may happen inside one function.
2) if the animation is non-blocking, then the function should only do one step, but be called repeatedly from somewhere else (for example, "repeatedly_execute" or other similar function).
The example of a
blocking animation:
Spoiler
Overlay* animateoverlay_blocking(Overlay* selectedoverlay, int Xposition, int Yposition, int startsprite, int endsprite, int transparent, int delay)
{
// loop while startsprite have not reached endsprite
while (startsprite != endsprite)
{
// destroy previous and create new overlay with a new sprite
if (selectedoverlay != null)
selectedoverlay.Remove();
selectedoverlay = Overlay.CreateGraphical(Xposition, Yposition, startsprite, transparent);
Wait(delay); // wait some time
startsprite++; // choose next sprite
}
return selectedoverlay;
}
This function may be used like:
someoverlay = animateoverlay_blocking(someoverlay, 100 /*x*/, 50 /*y*/, 1 /*start sprite*/, 10 /*end sprite*/, true /*transparent*/, 5 /*delay*/);
For
non-blocking animation you need to save the animation's information somewhere first, because it's going to be used repeatedly. If you have only 1 overlay animated at a time, then you just need few global vars to store these, but if you want to have a number of them animating simultaneously, then you need array of those vars. I also suggest creating a custom struct to group these variables.
Following is an example of single animated overlay, but it may be relatively easy expanded into multiple simultaneous overlays:
struct AnimatedOverlay
{
Overlay *over;
int x, y;
int startsprite, endsprite;
int delay;
int timer;
int transparent;
};
AnimatedOverlay animover; // single animated overlay
// This functions starts animation and save parameters
function animateoverlay_begin(int x, int y, int startsprite, int endsprite, int transparent, int delay)
{
animover.x = x;
animover.y = y;
animover.startsprite = startsprite;
animover.endsprite = endsprite;
animover.transparent = transparent;
animover.delay = delay;
animover.timer = delay; // set timer to delay value
if (animover.over != null)
animover.over.Remove();
animover.over = Overlay.CreateGraphical(x, y, startsprite, transparent);
}
// This function continues existing animation (or ends it)
function animateoverlay_step()
{
if (animover.over == null)
return; // not active
animover.timer--; // countdown timer
if (animover.timer > 0)
return; // delay not finished yet
// choose next sprite
animover.startsprite++;
if (animover.startsprite != animover.endsprite)
{
// destroy previous and create new overlay with a new sprite
animover.over.Remove();
animover.over = Overlay.CreateGraphical(Xposition, Yposition, startsprite, transparent);
// start the delay again
animover.timer = animover.delay;
}
else
{
// we're done here
animover.over.Remove(); // optionally remove overlay...
// if you like to keep it, then remove this command
}
}
Then you need to place a call to animateoverlay_step() into "repeatedly_execute" (or room's RepExec event).
function repeatedly_execute()
{
// if animated overlay exists, then do the step
if (animover.over != null)
animateoverlay_step();
}
The animation starts like
animateoverlay_begin(100 /*x*/, 50 /*y*/, 1 /*start sprite*/, 10 /*end sprite*/, true /*transparent*/, 5 /*delay*/);
Thanks for showing me all that.
About return;. I'm new to it and the manual confuses me on that part.
To be clear.Return can make it go back to the beginning of the function.Am I
right?
Quote from: Pajama Sam on Sat 23/04/2022 05:57:37
About return;. I'm new to it and the manual confuses me on that part.
To be clear.Return can make it go back to the beginning of the function.Am I
right?
Not to the beginning, but to outside. It returns to the place where you called it from and continues from there. It's the way to return some value, or skip the rest of the function and exit early.