Hi,
I have this function, which I want to be able to repeat in a loop. It needs to do its thing without blocking - so the player can click on things at the same time.
Basically all it's doing is moving a line of text down the page - 1 pixel every second - until it gets to a certain y value.
This is the code I tried to write so it didn't block:
function ScrollSentence(int speed = 40)
{
int timer = 0;
sentence = Overlay.CreateTextual(134, 36, 80, Game.SpeechFont, 15, "Sentence 1");
while (sentence.Y < 108) {
timer++;
if (timer == speed) {
sentence.Y++;
timer = 0;
}
}
sentence.Remove();
}
Except that doesn't work just locks the game up. The only way to fix it is to add a Wait(1) - but that destroys the point.
function ScrollSentence(int speed)
{
int timer = 0;
//determine what "sentence one" from lists
sentence = Overlay.CreateTextual(134, 36, 80, Game.SpeechFont, 15, "Sentence 1");
while (sentence.Y < 108) {
timer++;
if (timer == 40) {
sentence.Y++;
timer = 0;
}
Wait(1);
}
sentence.Remove();
}
Help - this is integral to getting the game working! Thanks, Mark.
You need to restructure everything; it'll never work that way. You need global variables and the moving has to be done inside repeatedly_execute.
Overlay*sentence;
int overlay_speed, overlay_timer;
void ScrollSentence(int speed, String message) {
sentence = Overlay.CreateTextual(134, 36, 80, Game.SpeechFont, 15, message);
overlay_speed = speed;
overlay_timer = 0;
}
// inside repeatedly_execute
if (sentence.Valid) {
overlay_timer++;
if (overlay_timer >= overlay_speed) {
sentence.Y++;
overlay_timer = 0;
if (sentence.Y == 108) sentence.Remove();
}
}
OK, that makes sense!
Yep, it works. For now at least ;) Thanks, Khris.
EDIT: Scrub that! Now if I try and use the function in a loop itself, the game hangs.
I didn't test this but you're not supposed to call ScrollSentence in a loop.
If you want multiple lines scrolling independently, that requires a bit more work.
Currently, if you call the function a second time while there's already an overlay on the screen, what should happen is the first one simply disappears. Like I said I didn't test this though.
The basic idea for multiple lines is to use an array of Overlays and deal with them one after another in rep_ex.
Ideally though the game would use just one Overlay, putting its graphic together using a DynamicSprite and .DrawString.
OK, well basically what I want to do is have three Overlays scrolling down a "page". When each of them reaches the bottom, they need to be created back at the top again. Repeat.
The way I'm looking at it now, I think this is impossible in AGS.
?
certainly not impossible, my friend!
Khris! sort the gentleman out!
I would but I am currently naked and need to get dressed.
Do excuse the state of my penis, i'm just so happy to see all of you.
LOL @ Calin ;D
Why would it be impossible...?
Try this:
Overlay*sentence[3];
int overlay_speed, overlay_timer;
void ScrollSentence(int speed) {
sentence[0] = Overlay.CreateTextual(134, 36, 80, Game.SpeechFont, 15, "Text 1");
sentence[1] = Overlay.CreateTextual(134, 56, 80, Game.SpeechFont, 15, "Text 2");
sentence[2] = Overlay.CreateTextual(134, 76, 80, Game.SpeechFont, 15, "Text 3");
overlay_speed = speed;
overlay_timer = 0;
}
// inside repeatedly_execute
if (sentence[0].Valid) {
overlay_timer++;
if (overlay_timer >= overlay_speed) {
overlay_timer = 0;
int i;
while (i < 3) {
sentence[i].Y++;
if (sentence[i].Y == 108) sentence[i].Y = 36;
i++;
}
}
}
Several years using AGS and I am still a terrible scripter. I learn something new everyday!
I'll try that, Khris. Thanks again. :)
EDIT: You genius! Works a charm!
OK, so I have tried to change this so the game creates a text overlay every time interval at y = 36, scrolls it down to y = 108 and removes it.
It should cycle through this process, using up a String array speech[] as the text for the Overlay array speech_overlay[]. Obviously I used the Overlay array because several Overlays will be visible at once.
Problem is it gives me a "Invalid overlay ID specified" error.
String speech[18];
Overlay*speech_overlay[18];
int overlay_speed, overlay_timer, overlay_Y_speed, overlay_Y_timer;
int speech_start = 0;
void ScrollSentence(int speed) {
speech_start = 1;
overlay_Y_speed = speed;
overlay_Y_timer = 0;
overlay_speed = speed;
overlay_timer = 0;
}
//in repeatedly_execute
function repeatedly_execute()
{
if (speech_start == 1) {
overlay_timer++;
if (overlay_timer >= overlay_speed) {
int i = 0;
overlay_timer = 0;
speech_overlay[0] = Overlay.CreateTextual(134, 36, 80, Game.SpeechFont, 15, speech[0]);
while (speech_overlay[0].Y < 108) {
overlay_Y_timer++;
if (overlay_Y_timer >= overlay_Y_speed) {
speech_overlay[0].Y++;
overlay_Y_timer = 0;
if (speech_overlay[0].Y == 108) speech_overlay[0].Remove();
}
i++;
}
}
}
This is turning out to be a massive nightmare. :(
Again, you can't do it that way.
That while loop inside rep_ex, even if we fix the error, will block the entire game.
The rep_ex itself IS the only while loop you need.
I'm still not entirely sure what it is you want to do.
I get that you want text to scroll from y = 36 to 108. When is a line added? Arbitrarily throughout the game?
Just tell us what you want the player to see, without using any AGS terms.
Sentence 4
Sentence 3
Sentence 2
Sentence 1
...
That, scrolling down the screen between y = 36 and 108. So obviously when Sentence 1, for example, goes off the bottom, Sentence 5 will appear at the top and so on. The sentences are stored as elements in as Strings in speech[].
Sorry, I have been very poor in my explanations - this whole exercise is really frustrating me. :-[
So there are supposed to be only four sentences on the screen at a time? As in, their Y coords are 18 apart?
Overlay*sentence[18];
int overlay_speed, overlay_timer, overlay_y = 35;
bool run_sequence;
void ScrollSentence(int speed) {
speech[0] = "..."; // you can set those elsewhere
speech[1] = "...";
...
overlay_speed = speed;
overlay_timer = 0;
run_sequence = true;
}
// inside repeatedly_execute
if (run_sequence) {
overlay_timer++;
if (overlay_timer >= overlay_speed) {
overlay_timer = 0;
overlay_y++; // y coord of sentence[0]
int i, y;
while (i < 18) {
y = overlay_y - i*18; // calculate overlay's y
if (y == 36) sentence[i] = Overlay.CreateTextual(134, 36, 80, Game.SpeechFont, 15, speech[i]);
else if (y > 36 && y < 108) sentence[i].Y = y;
else if (y == 108) {
sentence[i].Remove();
if (i == 17) run_sequence = false; // last overlay has just been removed
}
i++;
}
}
}
Thanks for all the help, you'll definitely need a credit at this rate!
Still giving a null pointer reference error.
On this line:
else if (y > 36 && y < 108) sentence[i].Y = y;
Found the error: in the second line of my code, replace the 36 with a 35.
Otherwise the first overlay's Y starts out at 37 and thus the overlay isn't created.