Removing Overlays after a set time

Started by sven, Tue 18/07/2006 14:36:15

Previous topic - Next topic

sven

Maybe I'm just too stupid to do it, but this is giving me a headache...I'm trying to create a simple end credit-like room where text messages are visible for a set time, then there's a pause of a set length etc. I cannot use wait() since I want the palyer to be able to interact with the GUI, and I cannot for the life of me figure out how to do it with overlays.

If I just say Overlay* foo.Overlay = CreateTextual(thingy); in the "player enters room after fadein"-script, then set a timer and try to remove the overlay in repeatedly_execute, the repeatedly_execute script complains that foo is not defined. So I'm trying to define the Overlays at the beginning of the script (see following example code), but then the game crashes with a null pointer error. I'm sure I' missing something glaringly obvious, but I'd appreciate if somebody could tell me what it is  :P

Code: ags
// room script file
Overlay* c1Overlay;
Overlay* c2Overlay;
Overlay* c3Overlay;

#sectionstart room_b  
function room_b() {
  // script for Room: Repeatedly execute
if (IsTimerExpired(1)==1) {
  c1Overlay.Remove();
}  

if (IsTimerExpired(2)==1) {
  c2Overlay.Remove();
} 

if (IsTimerExpired(3)==1) {
  c3Overlay.Remove();
} 
}
#sectionend room_b  



#sectionstart room_c  
function room_c() {
  // script for Room: Player enters room (after fadein)

c1Overlay.CreateTextual(50,50,120,1,14,"Wall wall");
SetTimer(1, 100);

c2Overlay.CreateTextual(50,50,120,1,14,"Wull wull");
SetTimer(2, 100);

c3Overlay.CreateTextual(50,50,120,1,14,"Will will");
SetTimer(3, 100);
#sectionend room_c    
}

strazer

The syntax is
Code: ags

  c1Overlay = Overlay.CreateTextual(50,50,120,1,14,"Wall wall");

CreateTextual is a static function and ideally shouldn't even be able to be used the way you did. This could probably be improved in AGS.

See, with
Code: ags

  c1Overlay.CreateTextual(50,50,120,1,14,"Wall wall");

you create the overlay, but you assign it to no pointer. Thus c1Overlay remains empty and
Code: ags

  c1Overlay.Remove();

produces the error.

sven

#2
Thanks for the quick reply - I suspected something like that, but that brings me back to my initial problem: if I do it like this...

Code: ags

#sectionstart room_b  
function room_b() {
  // script for Room: Repeatedly execute
if (IsTimerExpired(1)==1) {
  c1Overlay.Remove();
  }  
}
#sectionend room_b  

#sectionstart room_c 
function room_c() {
  // script for Room: Player enters room (after fadein)
Overlay* c1Overlay = Overlay.CreateTextual(50,50,120,1,14,"Wargl!");
SetTimer(1, 100); 
}
#sectionend room_c  


...then the repeatedly_execute complains that c1.Overlay is undefined - that's why I tried to define the overlays at the beginning, which apparently does not work either. Is there any other way to have overlays appear and disappear after a defined time?

strazer

Quote from: sven on Tue 18/07/2006 15:04:55that's why I tried to define the overlays at the beginning, which apparently does not work either.

Why not? That's exactly what you have to do.
If you use a pointer across several functions, you have to define it outside of all functions so they all have access to it.
Aside from the bit below, the code in your first post looked good to me. If you fix the CreateTextual usage, what is the error message you get?

From the code in your first post:
Code: ags

SetTimer(3, 100);
#sectionend room_c   
}

That looks suspicious. It should be
Code: ags

SetTimer(3, 100);
}
#sectionend room_c   

sven

That last one was one line too many I removed when I cleaned up the code before posting :P

Thanks for your hints, I've now finally figured out the correct syntax for what i want to do...well the first part, anyway. Here's what my sample script looks like now:

Code: ags
// room script file
Overlay* c1Overlay;
Overlay* c2Overlay;
Overlay* c3Overlay;

#sectionstart room_b  // DO NOT EDIT OR REMOVE THIS LINE
function room_b() {
  // script for Room: Repeatedly execute
if (IsTimerExpired(1)==1) {
  c1Overlay.Remove();
  c2Overlay = Overlay.CreateTextual(50,50,120,1,14,"Wull wull");
  SetTimer(2, 100);
}  

if (IsTimerExpired(2)==1) {
  c2Overlay.Remove();
  c3Overlay = Overlay.CreateTextual(50,50,120,1,14,"Will will");
  SetTimer(3, 100); 
} 

if (IsTimerExpired(3)==1) {
  c3Overlay.Remove();
} 
}
#sectionend room_b  // DO NOT EDIT OR REMOVE THIS LINE

#sectionstart room_c  // DO NOT EDIT OR REMOVE THIS LINE
function room_c() {
  // script for Room: Player enters room (after fadein)

c1Overlay = Overlay.CreateTextual(50,50,120,1,14,"Wall Wall");
SetTimer(1, 100);

}
#sectionend room_c  // DO NOT EDIT OR REMOVE THIS LINE


(for the record, the problem I mentioned earlier was caused by me using "Overlay* c1Overlay = blahblah" in the room_c section, which of course leads to an error message  "Overlay c1Overlay already defined" or similar)

Ok...now I'm able to have overlays appear and disappear after a set time while the player can still control the mouse. I'm still trying to figure out how to wait a set time between the messages, but I think I'll eventually find out :)

One final question, am I correct to assume that when using this method, I am in effect limited to 20 overlays because there's only 20 timers? That's not too many for the kind of sequence I had in mind...

strazer

#5
You don't need to use the built-in timers, you can script your own. Try this:

Code: ags

// room script file

Overlay* theOverlay;
int MyTimer = 0;

#sectionstart room_b  // DO NOT EDIT OR REMOVE THIS LINE
function room_b() {
  // script for Room: Repeatedly execute

  if (MyTimer == 100) { // 2.5 seconds after fade-in
    theOverlay = Overlay.CreateTextual(50, 50, 120, 1, 14,"Wall wall"); // display 1st message
  } 
  else if (MyTimer == 200) theOverlay.Remove(); // remove message after another 2.5 secs
  else if (MyTimer == 250) { // wait about 1 sec between messages
    theOverlay = Overlay.CreateTextual(50, 50, 120, 1, 14,"Wull wull"); // display 2nd message
  }
  else if (MyTimer == 350) theOverlay.Remove();
  else if (MyTimer == 400) {
    theOverlay = Overlay.CreateTextual(50, 50, 120, 1, 14,"Will will");
  }
  else if (MyTimer == 500) theOverlay.Remove();
  // and so on

  if (MyTimer < 10000) MyTimer++; // count timer up

}
#sectionend room_b  // DO NOT EDIT OR REMOVE THIS LINE


(At the default game speed, 40 game loops equal 1 second.)

The repeatedly_execute function starts running after the room has faded in, so you don't need the second function anymore.

Edit:

Oh, right. Thanks KhrisMUC!

Khris

#6
EDIT: Strazer was faster :)
But there's a problem with the code:
Mytimer won't reach 101 due to the last "else if" which ought to be an "if".

Using one Overlay and one Timer:

Code: ags
// global script
Overlay*ovla;
int seq[30];
int index=0;
String text;
int param=0;

function settext() {
param++;
if (param=1) text="Wall wall";
if (param=2) text="Wull wull";
if (param=3) text="Will will";
...
}

// player enters screen (before fadein)
seq[1]=100;
seq[2]=-40;
seq[3]=100;Ã,  Ã, // define sequence; positive value: show text, negative v.: pause
seq[4]=-40;
seq[5]=100;
...
seq[25]=0;

// rep_ex
int s;
if (index==0 || IsTimerExpired(1)) {
Ã,  if (ovla.Valid) ovla.Remove();
Ã,  index++;
Ã,  s=seq[index];
Ã,  if (s==0) return;Ã,  // end sequence
Ã,  if (s>0) {
Ã,  Ã,  settext();
Ã,  Ã,  ovla=Overlay.CreateTextual(50,50,120,1,14,text); Ã, // show text
Ã,  }
Ã,  else s=s*-1; Ã,  Ã, // wait

Ã,  SetTimer(1, s);
}


Didn't test it, but should work.

sven

Thanks both of you, that was really helpful. Being able to script my own timers takes care of lots of problems (not only with the end credits, but some stuff I was not quite sure how to do in other areas of the game). Thanks a lot!

monkey0506

It seems that this problem has already been resolved, however, I think that the PersistentSpeech module could (have) provide(d) you some assistance.

In any case it's a bit easier with the module...

SMF spam blocked by CleanTalk