Putting an image behind a Display text window? [CRUDELY SOLVED]

Started by Scavenger, Wed 16/01/2013 22:56:40

Previous topic - Next topic

Scavenger

I'm trying to put a semitransparent image behind my text windows, but it's not working out. I stole the code from my previous game, which appeared to work at least a little, but this time, no luck at all. GetTextWidth seems to choke on really short or multiline images.

Code: AGS
function DisplayText (String text)
{
  DynamicSprite* sGuiBG = DynamicSprite.Create (320, 200, false);
  int width = 10+ GetTextWidth (text, 0);
  if (width > 256) width = 256; // the fixed width. change this value as preferred
  int height = GetTextHeight(text, 0, width);
  sGuiBG.ColouriseArea ((System.ScreenWidth - width) / 2, (System.ScreenHeight - height) / 2, width, height);
  Overlay* oGuiBG = Overlay.CreateGraphical ((System.ScreenWidth - width) / 2, (System.ScreenHeight - height) / 2, sGuiBG.Graphic, true);
  DisplayAt((System.ScreenWidth - width) / 2, (System.ScreenHeight - height) / 2, width, text);
  oGuiBG.Remove ();
  sGuiBG.Delete ();
}


Produces:

(I know it's a little unreadable, I'm working on that too, but that's out of the scope of this question)

I actually don't know how to make a background plate work for a vanilla display command, but I'd like to, as well as one for a DisplayAt, so it's more flexible. I'm a little over my head here, I think.

Khris

You're adding 10 to the width, then calculate the height based on that ( wrong ) value. And you aren't adding the width of the border to those dimensions.
Actually, the screenshot is exactly what I would expect.
Code: ags
  int width = GetTextWidth (text, 0);
  if (width > System.ViewportWidth) width = System.ViewportWidth;
  int height = GetTextHeight(text, 0, width);
  border_size = 5;
  width += border_size*2;
  height += border_size*2;
  ...

This should come much closer. I'm aware that GetTextWidth isn't terribly reliable, but I believe it's only off if you're using an outlined font.

Crimson Wizard

I remember when I just came to these forums, I reported one bug. I think that may be related, or just useful to know.
http://www.adventuregamestudio.co.uk/forums/index.php?topic=36567.msg479661

Scavenger

Okay, trying with THIS code:

Code: AGS
function DisplayText (String text)
{
  DynamicSprite* sGuiBG = DynamicSprite.Create (320, 200, false);
  int width = GetTextWidth (text, 0);
  if (width > 256) width = 256; // So the image doesn't fill the screen and look ugly, also stops ColouriseArea freaking out.
  int height = GetTextHeight(text, 0, width);
  int border_size = 6; // Each piece of the text window is 6 pixels in width/height.
  width += border_size*2;
  height += border_size*2;
  sGuiBG.ColouriseArea ((System.ScreenWidth - width - border_size) / 2, (System.ScreenHeight - height - border_size) / 2, width, height);
  Overlay* oGuiBG = Overlay.CreateGraphical ((System.ScreenWidth - width - border_size) / 2, (System.ScreenHeight - height - border_size) / 2, sGuiBG.Graphic, true);
  DisplayAt((System.ScreenWidth - width) / 2, (System.ScreenHeight - height) / 2, width, text);
  oGuiBG.Remove ();
  sGuiBG.Delete ();
}


Gets me....



Adding in Crimson Wizard's fix solves the vertical problem (which is friggen awesome!), but not the horizontal. What I'm suspecting is happening is AGS is reporting a larger than max number (256) because of the two long words in a row. This truncates the Colourised overlay down to 256 pixels, but by the time it's done a DisplayAt, AGS has put the offending word on a newline instead.

How do I take THAT into account?

Khris

Yeah, I was afraid something like this would happen.
The only way I see is doing everything yourself. Split the message into lines, draw the border and the text yourself. Maybe you can rely on GetTextWidth at some points, to lighten the workload, but if you want a stable system, you'll have to do everything yourself.

Crimson Wizard

A minor thing, by the way, I think this calculation is a bit wrong:
Code: ags

(System.ScreenWidth - width - border_size) / 2, (System.ScreenHeight - height - border_size) / 2,

You are adding border_size (multiplied by 2) to width and height just before this, so there's no reason to subtract that even more.

Crimson Wizard

#6
Sorry for double post. I was curious and looked in the engine code. DisplayAt function does not use the width you gave her to break text into lines, but (width-6) for some reason.
I can't get the sense of all that is going on there atm, but I wonder, will that be a working hack to give width + 6 to DisplayAt?

E: Actually nevermind :-/. There more things to take into account than just those 6 pixels, such as resolution multiplier for instance.

Scavenger

#7
Quote from: Crimson Wizard on Thu 17/01/2013 14:12:07
A minor thing, by the way, I think this calculation is a bit wrong:
Code: ags

(System.ScreenWidth - width - border_size) / 2, (System.ScreenHeight - height - border_size) / 2,

You are adding border_size (multiplied by 2) to width and height just before this, so there's no reason to subtract that even more.
That's for setting the coordinates, not the height/width of the box, without it the background box is just drawn out of sync with the border.

Quote from: Crimson Wizard on Thu 17/01/2013 14:49:28
Sorry for double post. I was curious and looked in the engine code. DisplayAt function does not use the width you gave her to break text into lines, but (width-6) for some reason.
I can't get the sense of all that is going on there atm, but I wonder, will that be a working hack to give width + 6 to DisplayAt?

Adding 6 does nothing to the background box shooting off to the side - it merely messes up the already working ones. Tried both adding 6 to only DisplayAt, and to every width calculation after the initial one.

This is a little frustrating. I don't want to have to build my own text window function, I don't think I'm a good enough programmer to do so. There must be a reason why AGS is choking on this function, and I hope it's actually my code and not something within the engine. I mean, I could work around it by not using two long words in a row every time I write the function, but that's silly.

You guys have been an invaluable help so far, I don't think I could have gotten even this far without your insights. But this last bit is just stumping me to death.

EDIT: Oh, duh. I can just put a corrective variable in there to shorten the width if I need to. A dirty fix, but it'll do.

Khris

Did some testing and what I found was that while GetTextWidth/Height isn't terribly reliable in conjunction with DisplayAt(), it's much more accurate if used together with DrawingSurface.DrawStringWrapped().

Although this doesn't really help unless you were to draw the entire thing yourself, I guess.


SMF spam blocked by CleanTalk