GUI Label Marquee

Started by Secret Fawful, Tue 23/04/2013 05:06:04

Previous topic - Next topic

Secret Fawful

I've been working on a GUI that has a Statusline on it. The problem is when I get into longer strings, such as using inventory items on hotspots, the text gets cut off. So I was working on implementing a marquee. I found code to help me get started...but I can't seem to get this to work at all.

Code: AGS

//top of Global Script  
int index;
String labeltext;
  String scroll_text(int i, int width, bool left){
  if (left && index>0)index--;
  else if (!left && index<labeltext.Length-width) 
  index++;
  return labeltext.Substring(index, width);
}


Code: AGS

function repeatedly_execute(){
  GUIControl*gc = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
  index=5;
  // put anything you want to happen every game 
  if (scrollDelay>0)scrollDelay--;
  if(!scrollDelay>0){
    scrollDelay++;
   if(labeltext.Substring(scrollIndex, 150))
     scroll_text(scrollIndex, 150, true);
   else scrollIndex = 0;
  }
  
  if (mouse.Mode == 0){
  //LabelOverHotspot.Text = "Go to @OVERHOTSPOT@";
  labeltext="Go to";
  labeltext.Append(Game.GetLocationName(mouse.x, mouse.y));
  LabelMotherHot.Text=labeltext;}

//etc.
}


Unfortunately, scrolling will not occur. I thought this way I could keep from returning the same substring in rep_ex every time, and now return a different substring so it would scroll....but I figure I'm doing something majorly wrong.

Gilbert

I haven't really read all the codes but I have doubt about this line, and I think it's probably not what you want to do:
Code: AGS

  if(!scrollDelay>0){


The "!scrollDelay>0" condition will be something like this:
1) if scrollDelay is non-zero (be it negative or positive), then !scrollDelay becomes 0, and this the condition will be false.
2) if scrollDelay is 0, then !scrollDelay becomes 1, and the condition is true.

So, this is equivalent to the condition "scrollDelay==0" or just "!scrollDelay".

I'm not quite sure what you are after, but do you want to check whether the variable is negative?
In that case, just use the condition "scrollDelay<0".

Crimson Wizard

Substring function does not change the string you are calling a function for.

This line:
Code: ags

labeltext.Substring(index, width);

will make a NEW string, which will be simply lost, because you do not assign it to anything. 'labeltext' won't be changed at all.

Khris

#3
I have to question this entire endeavor.
Let's keep aside the fact that I loathe having to wait for scrolling text to keep up with my reading speed: even if I didn't, I'm not going to stop my "exploration" of the screen to read scrolling text.

I can think of no worse candidate for a marquee than an action line that changes depending on what's currently under the mouse, as in, every one and a half seconds.

The solution is to either use a smaller font or make use of the fact that labels wrap text and increase its height.
Or change the text in another way: whenever the text is too long, show just the name of the hotspot. This could be implemented as standard, too: GetLocationType is nothing -> "Use peppermint on", over Hotspot -> "Ridiculously huge monkey head"

Secret Fawful

Khris, you make a really really good point. I don't think the marquee would bother me a lot, but after a while that could get tedious. Your method sounds far better. I think part of wanting to implement this was a stubbornness to prove that I could learn to code a marquee in AGS, plus a stubbornness to prove a marquee can be done in AGS (I've seen it done in AGS before).

And that desire to push AGS's limits overrides the practicality of some ideas.

Also, I implemented it like this- but the text won't change when the inventory graphic (30 x 30 res) is over a hotspot.

Code: AGS

//rep_exec
LocationType loc_type = GetLocationType(mouse.x, mouse.y);
//mouse mode
if ((mouse.Mode == 4) && (loc_type != eLocationNothing)){
     Mouse.SaveCursorUntilItLeaves();
  }
  if ((mouse.Mode == 4) && (loc_type==eLocationHotspot)){
      LabelMotherHot.Text = "@OVERHOTSPOT@";
    }
  else if ((mouse.Mode == 4) && (loc_type==eLocationNothing)){
    //LabelOverHotspot.Text = String.Format("Use %s with @OVERHOTSPOT@", player.ActiveInventory.Name);
    LabelMotherHot.Text = String.Format("Use %s with", player.ActiveInventory.Name, 147, 178, 150, 16384);//here you must access the label through its name property, set in the gui editor.
    }


I also tried just using GetLocationType without going through all of this, but it still didn't work, so that's why I did it this way.

Khris

#5
Try this:
Code: ags
  LocationType loc_type = GetLocationType(mouse.x, mouse.y);

  String noun;
  InventoryItem* ii = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  if (ii != null) noun = ii.Name;
  else noun == Game.GetLocationName(mouse.x, mouse.y);
  
  String verb = "";
  if (mouse.Mode == eModeLookat) verb = "Look at";
  if (mouse.Mode == eModeInteract) verb = "Interact with";
  if (mouse.Mode == eModeTalkto) verb = "Talk to";
  if (mouse.Mode == eModeUseinv) verb = String.Format("Use %s with", player.ActiveInventory.Name);
  
  // over hotspot, don't show full action for use inv mode
  if (loc_type != eLocationNothing && mouse.Mode == eModeUseinv) verb = noun;
  else verb = String.Format("%s %s", verb, noun);

  LabelMotherHot.Text = verb;


Edit: code fixed (hopefully)

Secret Fawful

I'm not sure you're aware, but in AGS 3.2, instead of printing null in place of %s, it displays an error instead, stating "One of the string arguments supplied was not a string".

Apparently, earlier versions of AGS do not do this.

Crimson Wizard

Quote from: Secret Fawful on Wed 24/04/2013 05:47:02
I'm not sure you're aware, but in AGS 3.2, instead of printing null in place of %s, it displays an error instead, stating "One of the string arguments supplied was not a string".

Apparently, earlier versions of AGS do not do this.
That's true. This was changed right in one of the latest versions. I remember Technocrat's "Operation Forklift" has problems running on newer engine because of that.

SMF spam blocked by CleanTalk