Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: markbilly on Mon 24/10/2011 15:03:29

Title: Blocking problem
Post by: markbilly on Mon 24/10/2011 15:03:29
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.
Title: Re: Blocking problem
Post by: Khris on Mon 24/10/2011 15:28:18
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();
   }
 }
Title: Re: Blocking problem
Post by: markbilly on Mon 24/10/2011 16:15:39
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.
Title: Re: Blocking problem
Post by: Khris on Mon 24/10/2011 16:41:37
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.
Title: Re: Blocking problem
Post by: markbilly on Mon 24/10/2011 18:30:21
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.

?
Title: Re: Blocking problem
Post by: Calin Leafshade on Mon 24/10/2011 19:09:53
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.
Title: Re: Blocking problem
Post by: Khris on Mon 24/10/2011 19:33:16
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++;
      }
    }
  }
Title: Re: Blocking problem
Post by: markbilly on Mon 24/10/2011 22:23:30
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!
Title: Re: Blocking problem
Post by: markbilly on Tue 25/10/2011 11:13:35
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. :(
Title: Re: Blocking problem
Post by: Khris on Tue 25/10/2011 11:45:44
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.
Title: Re: Blocking problem
Post by: markbilly on Tue 25/10/2011 11:51:00
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.  :-[
Title: Re: Blocking problem
Post by: Khris on Tue 25/10/2011 12:18:04
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++;
     }
   }
 }
Title: Re: Blocking problem
Post by: markbilly on Tue 25/10/2011 14:47:22
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;
Title: Re: Blocking problem
Post by: Khris on Tue 25/10/2011 23:14:51
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.