My question is basically in the topic but I saw in the "how to cure a cold game" that when you had the mouse over lets say paintings (text would show up on the bottom left side of the screen saying what object/hotspot you had the mouse over.
I was just wondering how you do this. Thanks alot for reading and/or helping me out.
Make a GUI, put a label on that GUI, and have the text include the word @OVERHOTSPOT@
Hi Radient thats a good one, I am now at this stage of learning how to do this particular feature and I would like if someone could please expand on this a bit? This gui if it is going to be made in the gui pane, how does it get directed to the particular hotspot and in that particular room? Is any further scripting by the game author needed to be done?
No, you don't need further scripting.
GUIs are room independent, so you don't need to worry about moving it to rooms.
As long as the GUI's visibility is set to normal, it will be visible at all times.
I'll call the GUI "gOverhot".
To move it about on the screen, you need to call the GUI's SetPosition function (or change its coords directly).
This has to be done constantly, so you'd put the code in the repeatedly_execute function of the global script:
//inside rep_ex
int c=System.ViewportWidth-gOverhot.Width;
int x=mouse.x+XOFFSET; if (x<0) x=0; if (x>c) x=c;
c=System.ViewportHeight-gOverhot.Height;
int y=mouse.y+YOFFSET; if (y<0) y=0; if (y>c) y=c;
gOverhot.SetPosition(x, y);
Replace X/YOFFSET with small numbers to set the GUI apart from the mouse cursor a little.
The checks are there to make sure the GUI is always displayed fully on screen.
Thanks KrisMUC
I kind of still don't fully get it, I know its silly that I cant, but I havent done this for a long time, and only just came back to working on my game. I'm not exactly sure where to start with this gui... starting point to ending point though I think the ending point is putting the code in the global script. Where do I start....? Sorry I'm not an experienced programmer, I'm learning but have never studied it professionally.
No worries, here's the step by step:
Create the GUI, resize it to a suitable width and height (e.g. 100x14) and call it "gOverhot". Notice the small properties window? That's where you enter the Scriptname and dimensions and set the visibility to "Normal". Now set the background and border color to 0 to make the GUI invisible.
(Actually, the GUI's contents will still be visible, just not the GUI itself.)
Add a label to it. Using the yellow dots at the corners, resize it so it's roughly as big as the GUI.
In the properties window, set its text to "@OVERHOTSPOT@". You should see that text appear on the label.
(You can enter some other text first to properly place the label.)
The only thing left to do is add the code to the rep_ex function. Just select if from the menu (Script -> repeatedly_execute) and put the text inside the curly brackets.
If you want to deactivate the GUI (e.g. in an options screen or the like), set it's .Visible property to false.
gOverhot.Visible=false;
Upon leaving the options screen, just set it back to "true".
The only downside is the fixed width of the GUI. Thus even with a very short hotspot text, the GUI won't move all the way to the right of the screen.
There's a way to overcome this, but we'll stick to the current method for now.
Or use the Description module ;)
Thank you KrisMUC and SSH!! ;) I am going to try both, always keen to try everything. My head is full of cobwebs, I remember last I spoke of those modules, and I will give that one a go. Many thanks again
Ok I did all you told me to do (but bit confused by the offset x/y instructions, not sure what you mean.. there are a lot of x and ys in the script, which ones should I change to numbers?) and I went to test game but it came back with an error message:
"problem was in: Internal character defines
error line: 81 (in my script thats where I placed, within the rep exe). Variable gOverhot is already defined"
And then.... it interestingly came up with a 2nd error message rite away saying "this error occured in an internal AGS script. This should never happen; try reinstalling the latest AGS" ummm???? Is there a recently upgraded ags program I'm not aware of? I know I've not been here so regularly of late, but havent visited the main ags website to see it so maybe I've missed it. Do you know anything about the 1st error message?
EDIT: Ok I went back and had a look, I put the name Overhot in the script little box, and now I have deleted that bit, yes u didnt mention that so I think I went wrong there lol ;). Anyway that went and the 1st error message didnt pop up, it proceeded to save the game and then a new error message came up - this time
"Problem in: Global script (obviously! lol)
Error line 64 Expected Integer value after "="
(copied and pasted line 64 here for you: int c=System.ViewportWidth-gOverhot.Width;
I tested my code and instructions and everything went smoothly.
(Except that the GUI's name is supposed to be "OVERHOT" and goes into the text box at the top, but you seem to have corrected that by yourself.)
There are a lot of x and ys in the script but only one "XOFFSET" and one "YOFFSET". Those would be rejected by the compiler if you left them in.
The error you got (about "int c=...") suggests that you pasted the code outside a function.
Ok... not sure what out of function area means... I am thinking I should have typed function at the start of the code...? I am not sure what you mean by the offset bit sorry. Where do I replace the x y with small numbers? For example would 3 for x and 3 for y be ok?
No, not at the start.
A piece of code like this always goes into a so-called function. Either a custom one or one of AGS's predefined ones, as in this case:
Quote from: KhrisMUC on Mon 12/11/2007 11:01:52The only thing left to do is add the code to the rep_ex function. Just select if from the menu (Script -> repeatedly_execute) and put the text inside the curly brackets.
After selecting the menu item, the script editor window should appear with the cursor sitting at a line where it says "function repeatedly_execute()"
After that there are two curly brackets { and }, the code goes in between them.
Like this:
function repeatedly_execute() {
// put anything you want to happen every game cycle here
int c=System.ViewportWidth-gOverhot.Width;
int x=mouse.x+XOFFSET; if (x<0) x=0; if (x>c) x=c;
c=System.ViewportHeight-gOverhot.Height;
int y=mouse.y+YOFFSET; if (y<0) y=0; if (y>c) y=c;
gOverhot.SetPosition(x, y);
}
Now look at that code and notice the two all-caps words: XOFFSET & YOFFSET
Replace those with numbers like 3, yes.
Now the x line would say " int x=mouse.x+3; if (..."
Putting a 3 in there makes AGS place the top left corner of the GUI 3 pixels to the right of the mouse.
Putting a 5 in there instead of YOFFSET makes AGS place it 5 pixels
below the current mouse position.
This is done to avoid the cursor overlapping the hotspot text.
Alternatively, don't add those offsets and in the GUI editor, move the label a bit to the right and down.
Thanks for the that. Ok I tried it and I got the error message variable already defined and it took me to the global script where I had pasted the code. I still dont fully understand the function stuff. I have copied and pasted below the current code sequence of the things i have already in the rep_exe for other functions, before the code you gave me goes in. I have tried but still doesnt recognise.
#sectionstart repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() {
// put anything you want to happen every game cycle here
lblTime.Text = String.Format("%02d:%02d, Day %d", GameTime.Hour(),
GameTime.Minute(), GameTime.Day());
// Start of special Following Code
if (cEgo.Moving == false) { // Player has stopped moving (obviously)
if (Follow == 1) { // If Jonah is still flying
// Change state (the 'Follow' variable), and have him fly to Ego
cJonah.FollowCharacter(null);
Follow = 2;
cJonah.Walk(cEgo.x, cEgo.y, eNoBlock);
}
else if (Follow == 2) { // If Jonah is on his way to Ego's shoulder
if (cEgo.Loop == 1 || cEgo.Loop == 0) cJonah.Baseline = cEgo.y -
1; // Or '==2' for the other shoulder
else cJonah.Baseline = cEgo.y + 1;
if (cJonah.Moving == false) { // Jonah is at Ego's location
// Make sure their Loops are always the same
cJonah.Loop = cEgo.Loop;
}
}
}
else { // If Ego is Moving
if (Follow == 2) { // If Jonah is 'at rest'
// Change state (the 'Follow' variable), and have him start flying free
cJonah.FollowCharacter(cEgo,0,0);
Follow = 1;
}
}
// End of special Following Code
}
function show_inventory_window () {
// This demonstrates both types of inventory window - the first part is how to
// show the built-in inventory window, the second part uses the custom one.
// Un-comment one section or the other below.
// ** DEFAULT INVENTORY WINDOW
// InventoryScreen();
// ** CUSTOM INVENTORY WINDOW
gInventory.Visible = true;
// switch to the Use cursor (to select items with)
mouse.Mode = eModeInteract;
// But, override the appearance to look like the arrow
mouse.UseModeGraphic(eModePointer);
}
#sectionend repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE
EDIT:
Hey! can someone please reply????? I am sorry that I have to double post but I don't want to be waiting this long for a reply! PLEASE HELP! Or I will have to post my question into a new topic SORRY! I think its cos this topic is labelled SOLVED at the end thats why but I am not happy no one has answered my question above come on!
EDIT by Ashen: To remove double post. Have patience, and read the rules.
Calm down already.
First of all, the show_inventory_function somehow ended up inside the repeatedly_execute's #sectionstart / #sectionend lines.
The code is properly indented so in the snippet you showed there are only two lines that contain a single } at the very beginning of the line.
Those }s close the respective function opened with "function NAME() {"
Everything between the { and } is considered inside the function and the code I posted earlier still isn't.
Please do the following and do it exactly the way I describe it:
Select all the following code and copy it to the clipboard:
#sectionstart repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() {
// put anything you want to happen every game cycle here
//*****OverHot code start
int c=System.ViewportWidth-gOverhot.Width;
int x=mouse.x+XOFFSET; if (x<0) x=0; if (x>c) x=c;
c=System.ViewportHeight-gOverhot.Height;
int y=mouse.y+YOFFSET; if (y<0) y=0; if (y>c) y=c;
gOverhot.SetPosition(x, y);
//*****end
lblTime.Text = String.Format("%02d:%02d, Day %d", GameTime.Hour(),
GameTime.Minute(), GameTime.Day());
// Start of special Following Code
if (cEgo.Moving == false) { // Player has stopped moving (obviously)
if (Follow == 1) { // If Jonah is still flying
// Change state (the 'Follow' variable), and have him fly to Ego
cJonah.FollowCharacter(null);
Follow = 2;
cJonah.Walk(cEgo.x, cEgo.y, eNoBlock);
}
else if (Follow == 2) { // If Jonah is on his way to Ego's shoulder
if (cEgo.Loop == 1 || cEgo.Loop == 0) cJonah.Baseline = cEgo.y -
1; // Or '==2' for the other shoulder
else cJonah.Baseline = cEgo.y + 1;
if (cJonah.Moving == false) { // Jonah is at Ego's location
// Make sure their Loops are always the same
cJonah.Loop = cEgo.Loop;
}
}
}
else { // If Ego is Moving
if (Follow == 2) { // If Jonah is 'at rest'
// Change state (the 'Follow' variable), and have him start flying free
cJonah.FollowCharacter(cEgo,0,0);
Follow = 1;
}
}
// End of special Following Code
}
#sectionend repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE
function show_inventory_window () {
// This demonstrates both types of inventory window - the first part is how to
// show the built-in inventory window, the second part uses the custom one.
// Un-comment one section or the other below.
// ** DEFAULT INVENTORY WINDOW
// InventoryScreen();
// ** CUSTOM INVENTORY WINDOW
gInventory.Visible = true;
// switch to the Use cursor (to select items with)
mouse.Mode = eModeInteract;
// But, override the appearance to look like the arrow
mouse.UseModeGraphic(eModePointer);
}
In AGS, open the global script and select exactly the same lengthy block you've pasted in your second to last post.
Press Ctrl-V to overwrite it.
This should fix things.
Thank you thank you KrisMUC :) thats one step further for me in learning the programming. I havent forgotten what Ashen taught me dont worry ;). Ok I am going to try code now. Once its established and clear... the next step is how will I "tag" each item in each room with the active code?
And lol yes sorry KrisMUC I realise you would have been in bed, the time difference!! ;) just thought maybe others might help too that was what I was thinking.
Glad to be of help :)
Quote from: gypsysnail on Tue 13/11/2007 06:11:13Once its established and clear... the next step is how will I "tag" each item in each room with the active code?
That's not necessary; the text @OVERHOTSPOT@ is recognised by AGS and automatically and continually replaced by the name of the thing under the mouse.
(Unless you meant something else.)
So once everything regarding the global script is sorted out, it should work as intended immediately, provided you have entered names for all the objects, hotspots, etc.
Oh ok.... what was it meant for? Umm I actually wanted text to show up next to the mouse pointer on anything that I name..... how would this be done? And what is overhotspot actually for? I cant believe I dont know what this means... :O it shows I dont know the term meanings fully yet OMG
Quote from: gypsysnail on Tue 13/11/2007 07:41:59Umm I actually wanted text to show up next to the mouse pointer on anything that I name.....
Did you fix the global script yet? If yes, mission accomplished.
Yep fixed global script and tested game but when I point over things they dont show text - and I knew that would happen because I havent... actually written any texts for particular stuff.. like.... for example if I point my mouse pointer over a car and it says "your car".... where would I do this?
Are you serious...? :)
Look for a textbox labeled "Name:". It's "Full name:" for characters and "Inventory item name:" for inv items.
Yes I'm serious, I told you I'm pretty crappy with programming at this point and its silly cos I told Ashen a year ago the same thing lol. My 3 jobs took me away from ags for so long, but I'm back. ;).
Ok.... I'm not fully sure what you mean by text box and all that.. where are those? :-[
AGS 2.72:
Hotspots: Go to Room Editor -> Areas, selects Hotspots at the dropdown, look immediately below that.
Objects: Go to Room Editor -> Objects, check the right side beneath the three checkboxes
Characters: Select a character and look above the Normal view button
Inventory items: well, I'm sure you'll find it on your own ;)
Yup thats easy!! I can do that lol. Thanks for that. That was all the guidance I needed ;) I'm getting there :P.
EDIT:
Ok... I have done what you told me to do and yes the name... but... when I test the game nothing happens. Whats going wrong do you know?
EDIT by Ashen: To remove ANOTHER double post.
Some basic troubleshooting:
In the GUI Editor, select the GUI and set its border color to 15.
Now test the game. Can you see the border?
If not, make sure that the GUI's visible property is set to normal.
If you can see the border but there's still no text, change the label's text from "@OVERHOTSPOT@" to e.g. "Test".
Test the game. Can you see the word "Test" displayed next to your mouse?
Ok I have tried all that, no still does not work at all. I know one thing, the game (when I test game) starts off in replay mode (and I have no idea how to turn this off) so I press ESC and it stops the replay so I can control the game myself. I had been doing a replay for an exhibition to automatically make the game character etc move and do things automatically as it was to be displayed on the wall out in the city. Now I dont know how to stop or get rid of this replay.....? Maybe this replay causes the problem with the text on hotspots not showing at all?
To get rid of the replay, start winsetup, click the Advanced button and select "Don't run a replay", then click "Save and run".
So you can't see the border, you can't see any text?
In the GUI editor, what does the GUI look like? I assume it's a white rectangle on a pink background, right?
Yep thats exactly it, a white border with a pink background which means transparent. Ok the text is "test" at the moment, still no show. Thanks re the replay.
EDIT: Sorry I have tried and tried to find winsetup and I have no idea where it is anymore. I used to be able to know all this but it seems to have changed. Even my father who is an IT expert doesnt even know this one OMG
Save the game, then open the game's Compiled folder.
path_to_AGS/GameName/Compiled/winsetup.exe
So the GUI doesn't show at all? You seem to have added a lot of custom code to your game, probably from forum posts from a year ago. Maybe it screws with the GUI, although that's unlikely.
Did you check the GUI's visibility property? Is it set to "Normal"?
Another thing you could try is to add the following lines to the OverHot-code in rep_ex:
//*****OverHot code start
int c=System.ViewportWidth-gOverhot.Width;
int x=mouse.x+XOFFSET; if (x<0) x=0; if (x>c) x=c;
c=System.ViewportHeight-gOverhot.Height;
int y=mouse.y+YOFFSET; if (y<0) y=0; if (y>c) y=c;
gOverhot.SetPosition(x, y);
gOverhot.Visible=true; <-- add this
gOverhot.Transparency=0; <-- and this
//*****end
Lol you wont believe this!!!! I just turned off the replay and the test text showed up with the border completely!!! It stays next to the mouse pointer all the time tho, so thats something accomplished. I had a feeling the replay was holding back the text over hotspot gui. Ok next step is to tweak the whole thing... I'm guessing changing border back to 0 from 15 and the text back to @OVERHOTSPOT@?
EDIT:
BINGO!!! Its working now!!!!!! Thank you KrisMUC for your great help! As always this forum is a good friend ;)
Great, and good job pinning the cause for the trouble on the replay!
Since everything's working now, we can add a little spice:
//*****OverHot code start
String ohs="";
int ohmx=mouse.x; int ohmy=mouse.y;
if (GetLocationType(ohmx, ohmy)!=eLocationNothing)
ohs=ohs.Append(Game.GetLocationName(ohmx, ohmy));
GUIControl*ohgc=gOverhot.Controls[0];
Label*ohl=ohgc.AsLabel;
int ohtw=GetTextWidth(ohs, ohl.Font);
ohl.Width=ohtw+3;
gOverhot.Width=ohtw+6;
int c=System.ViewportWidth-gOverhot.Width;
ohmx+=3; if (ohmx<0) ohmx=0; if (ohmx>c) ohmx=c;
c=System.ViewportHeight-gOverhot.Height;
ohmy+=3; if (ohmy<0) ohmy=0; if (ohmy>c) ohmy=c;
gOverhot.SetPosition(ohmx, ohmy);
//*****end
This should allow the GUI to move further to the right if the hotspot's text is shorter.
Edit: yup, sorry, missed one x. Code is corrected.
Ok great... where will I put this. I have tried to put it where the existing code for this function is.... but maybe I have to replace some of that code with this one?... also how will I stop the characters name from being shown when mouse pointed over her? I know she must have her name in the field in the characters editor of ags.... ?
Replace ALL the existing code with the new lot. Everything currently between
//*****OverHot code start and
//*****end in your
repeatedly_execute function, should be replaced with everything between
//*****OverHot code start and
//*****end in Khris' last post. Really shouldn't be that hard to follow...
Quote
also how will I stop the characters name from being shown when mouse pointed over her? I know she must have her name in the field in the characters editor of ags.... ?
Which character? The player character, some other character, or just all characters in general? To not have ANY character's name appear, but still let them have names, will take a fair bit of work - fortunately, I don't think that's what you want. To have the player character's name not show up, go to the 'Characters' pane of the editor, and un-check the 'Clickable' box. The mouse now won't register when it's over the player character - which also means you can't have any interactions for them (Look at, Use Inventory on, etc). (Works for any character, not just the player.)
Hi Ashen, thanks for joining :) umm ok well I have done that and I got an error message:
Line 28: "Undefined symbol x" which I've pasted below:
ohmx+=3; if (x<0) ohmx=0; if (ohmx>c) ohmx=c;
Now my inability to understand programming fully probably contributes to this and I am assuming I have to change the x into a number......?
And yes sorry its not so easy for me to follow, I have virtually no experience or qualifications in programming so be patient with me please ;)
Try changing it to ohmx, as used in the rest of that line. It looks like Khris didn't fully update the code when he wrote the new version (often happens to me when I'm writing off the top of my head, and not in AGS). So:
ohmx+=3; if (ohmx<0) ohmx=0; if (ohmx>c) ohmx=c;
All done! Thank you. Yes know what you mean, very hard to keep track when thinking off head, I must say you guys are talented! :) Wish I could script just like that! But I'll learn, probably never be as good as you ;). Thank you again. Am very pleased its all solved.