Muhu. Muhuhaha. UWAHAHAHAHAHAHA!!
Back before the site nuke, back when I first got into Sphere something like two years ago, I wanted to make Chrono Trigger-style text boxes, where the text prints out like a typewriter, but you can walk around while it does so.
A newbie, I tried using a for loop. Naturally, it prevented movement until the text had finished printing.
Fast forward a year. I start messing around with Canvas. The CT text problem haunts me. I decide to create a function that emulates the functionality of a for loop, without locking up the system. I succeed.
And now, I've converted it to Sphere.
First of all, here's the code. I warn you, this is "just works" code. Don't blame me if it's so messy and inefficient that you vomit.
main.js
var font = GetSystemFont();
var LoopPlease = 0;
var LoopCount = -1;
var LoopEnd = 0;
var CurrentText = "";
function LoopChecker(){
switch (true){
case (LoopPlease == 0):
break;
case (LoopPlease == 1 && LoopCount > LoopEnd):
LoopPlease = 0;
break;
case (LoopPlease == 1 && LoopCount < 0):
LoopCount = 0;
case (LoopPlease == 1 && LoopCount <= LoopEnd):
LoopCount ++;
LoopThis();
break;
}
}
function FiveLoop(ThisFunction,ThisManyTimes){
LoopPlease = 1;
LoopThis = ThisFunction;
if (LoopEnd = 0){
LoopEnd = ThisManyTimes;
}
else{}
}
function TypeWrite(){
LoopEnd = CurrentText.length;
PrintThis = CurrentText.substr(0,LoopCount);
font.drawTextBox(0,0,256,128,0,PrintThis);
}
function game() {
CreatePerson("player1", "spWar.rss", false);
AttachInput("player1");
SetRenderScript("LoopChecker()");
MapEngine("test_map.rmp", 60);
}
In test_map.rmp, an Entity's On Activate (Touch)
CurrentText = "Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies.";
FiveLoop(TypeWrite);
Things I Already Know...
1) The text disappears the second it finishes displaying. That's fine, this is just a proof of concept, to show that you can have a character walk around while text is printing. Displaying the full text for a given amount of time or until the player gives input can be added later.
2) There's no way to modulate the speed at which the text displays. Well, other than to change the framerate of the Map Engine. Again, this can be dealt with later.
3) The FiveLoop function is only capable of passing argumentless functions stored in variables.
Questions I Have...
1) Why is the FiveLoop function only capable of passing argumentless functions stored in variables? If you were to change TypeWrite to...
function TypeWrite(SomeText){
LoopEnd = SomeText.length;
PrintThis = SomeText.substr(0,LoopCount);
font.drawTextBox(0,0,256,128,0,PrintThis);
}
And changed the On Touch entity's code to...
FiveLoop(TypeWrite("Hello, world!"));
The game crashes when you touch the entity, complaining...
"LoopThis is not a function."
Or, alternatively, if you add this to main.js...
var SayHello = TypeWrite("Hello, world!");
And have the entity's code as...
FiveLoop(SayHello);
...you get the same error. LoopThis is not a function.
Even if you just add empty parenthesis to the otherwise-working entity code...
CurrentText = "Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies.";
FiveLoop(TypeWrite());
...it complains that LoopThis is not a function.
Why do all those things churn out the same error?
2) If I put the entity's code on On Activate (Talk) instead of touch, it doesn't work. No idea why; I've got input attached and I tried pressing all four of Sphere's buttons -- A, B, X and Y.
3) When everything's working fine and I touch the entity and it types the text and I can walk around while it does it, if I wait until it's finished and then touch the entity again, it won't print the text again. Why? (Also, if there's a second entity with a different CurrentText trying to FiveLoop, only the first one I touch will work, then neither will work after that.)
4) Notice that none of my code uses FlipScreen();
So then why does it work? Normally, if you try to draw text without using FlipScreen(), nothing happens. Is it because it's running in SetRenderScript, so that's automatically flipping it?
Thanks so much to anyone who can help me figure this stuff out ^_^