Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Monsieur OUXX on Fri 15/11/2013 22:38:24

Title: Ideas on how to generate an outline on-the-fly?
Post by: Monsieur OUXX on Fri 15/11/2013 22:38:24
I'm considering ways of faking a font outline when a character speaks.
I was thinking of a solution that's not perfect but might do the trick : displaying 4 (or 8) times the text in black, with 1-pixel shift in every direction,, under the actual coloured text.

How would you do that?

I'm trying this :

1) I created a dummy character, cOutline1, with a transparent view (i.e. it can speak, but it has an invisible body)
2) Its speech color is bright green (for tests, to be sure I'll see it on my screen)
3) I tried the following script:

cOutline1.x = player.x; //test pixel offset
cOutline1.y = player.y-10; //test pixel offset
cOutline1.SayBackground(s);
player.Say(s);


Strangely, when I test, I don't see the .SayBackground sentence. I only see the .Say sentence.
What am I doing wrong?
Title: Re: Ideas on how to generate an outline on-the-fly?
Post by: Monsieur OUXX on Fri 15/11/2013 23:24:54
The script above was faulty in many ways, so here is a new version :



  //we force the speech animation
  c.StopMoving();
  c.LockView(c.SpeechView);
  c.Animate(c.Loop, 4, eRepeat , eNoBlock); //make sure this is non-blocking
 
 
  cOutline1.ChangeRoom(c.Room); //just to make sure they're in the same room
  cOutline1.x = c.x; //we position the fake outline
  cOutline1.y = c.y-10;
  Wait(1);
  cOutline1.Say("");  //so that if wait time is skipped, the character stops talking
  c.Say("");  //so that if wait time is skipped, the character stops talking


  cOutline1.SayBackground(s); //we make both the outline and the character say the same thing
  c.SayBackground(s); //we need to use saybackground here, because "say" interrupts the previous saybackground
  WaitMouseKey((s.Length/Game.TextReadingSpeed + 1) * GetGameSpeed()); //so wait time can be skipped
 
  cOutline1.Say("");  //so that if wait time is skipped, the character stops talking
  c.Say("");  //so that if wait time is skipped, the character stops talking
 
  c.UnlockView();
  Wait(1);




However there is still an issue :
When I click to interrupt the sentence, the character says the sentence AGAIN. But this time the sentence does not appear in the same place!?! (like 10 pixels lower). And if I click somewhere before he's finished talking, now he can walk while talking. Terrible.
Title: Re: Ideas on how to generate an outline on-the-fly?
Post by: Crimson Wizard on Fri 15/11/2013 23:29:46
There's a way to control background speech overlay:

Code (ags) Select

Overlay *o = cCharacter.SayBackground(...);
<...>
o.Remove();
Title: Re: Ideas on how to generate an outline on-the-fly?
Post by: Monsieur OUXX on Fri 15/11/2013 23:35:15
Quote from: Crimson Wizard on Fri 15/11/2013 23:29:46
There's a way to control background speech overlay

Cool, that will come handy to make the outline look better.
But my main issue right now is sync'ing the speech view, and the appearance and disappearance of the real text and the outline (as explained in my second post)
Title: Re: Ideas on how to generate an outline on-the-fly?
Post by: Crimson Wizard on Fri 15/11/2013 23:55:14
Quote from: Monsieur OUXX on Fri 15/11/2013 23:35:15
But my main issue right now is sync'ing the speech view, and the appearance and disappearance of the real text and the outline (as explained in my second post)
I mean, you can replace this
Code (ags) Select

cOutline1.SayBackground(s); //we make both the outline and the character say the same thing
c.SayBackground(s); //we need to use saybackground here, because "say" interrupts the previous saybackground
<...>
cOutline1.Say("");  //so that if wait time is skipped, the character stops talking
c.Say("");  //so that if wait time is skipped, the character stops talking

with this:
Code (ags) Select

Overlay *o1 = cOutline1.SayBackground(s); //we make both the outline and the character say the same thing
Overlay *o2 = c.SayBackground(s); //we need to use saybackground here, because "say" interrupts the previous saybackground
<...>
// Remove both overlays at once
o1.Remove();
o2.Remove();
Title: Re: Ideas on how to generate an outline on-the-fly?
Post by: Monsieur OUXX on Sat 16/11/2013 00:05:11
Thanks Crimson. I've actually found the solution.

The difficulty (and the reaosn why your solution wouldn't work as-is -- that's also what I tried in the first place) was in the small prints of SayBackground. It's interrupted by any "Say" AND it doesn't animate the speech. that's a pain in the ass to use.

But everything is solved with  game.bgspeech_stay_on_display


  game.bgspeech_stay_on_display = 1; //to make sure that a "Say" won't discard a "SayBackground"
 
  cOutline1.ChangeRoom(c.Room); //just to make sure they're in the same room
  cOutline1.x = c.x; //we position the fake outline
  cOutline1.y = c.y-10;
  Wait(1);
 
  Overlay* o = cOutline1.SayBackground(s); 
  c.Say(s);  //by using "Say", we benefit of the animated character.

  if (o.Valid != 0)
    o.Remove(); //we remove the overlay so that the outline disappears at the same time as the actual text



Now it works perfectly.

Title: Re: Ideas on how to generate an outline on-the-fly?
Post by: Ghost on Sat 16/11/2013 00:52:25
Quote from: Monsieur OUXX on Fri 15/11/2013 22:38:24
I was thinking of a solution that's not perfect but might do the trick : displaying 4 (or 8) times the text in black, with 1-pixel shift in every direction,, under the actual coloured text.

Maybe off-topic, but I remember CJ mentioning that automatic font outlines *are* generated that way by AGS itself. That was way back in the days of 2.7x though.
Title: Re: Ideas on how to generate an outline on-the-fly?
Post by: David Ostman on Sat 16/11/2013 10:04:25
Yep.

Which is why if using upscaled pixel fonts we get the upper outline instead of the (probably) desired bottom outline.

(http://i.imgur.com/8EEXJxg.png)

Maybe we should be able to control how many pixels the outline font is shifted.