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?
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.
There's a way to control background speech overlay:
Overlay *o = cCharacter.SayBackground(...);
<...>
o.Remove();
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)
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
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:
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();
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.
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.
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.