Okay, my code works, but it seems "kludged" together and I'm trying to find out if there was a simpler way to pull this off. Specifically, adding a value to the function that can be automatically passed.
I created a GUI (called gRobotHunt) with 20 buttons that have their text randomly generated - each button being the name of a robot on that level of the ship. Trying to keep the code clean and I wanted one function to cover all 20 buttons. This is what I came up with....
Button *NameCheckBtn;
function Button20_OnClick(GUIControl *control, MouseButton button)
{
//Display("Button #: %d", control.ID);
NameCheckBtn = gRobotHunt.Controls[control.ID].AsButton;
if ( NameCheckBtn.Text == "Wall-E" ) {
Display("You found the right one. John Lassiter would be pleased.");
}
else {
Display("That's the wrong robot!");
}
}
All in all, I don't think it's too bad. But what variable would I add to the function so I could access the button directly, rather than muck about with "NameCheckBtn"?
- Cogliostro
Yeah, I know, it works, and this isn't exactly urgent, but in the interest of furthering my scripting skills, I was hoping someone knew the answer.
You could just do control.AsButton.
Also, in any case, you do not need a global variable.
function Button20_OnClick(GUIControl *control, MouseButton button)
{
Button *btn = control.AsButton;
....
}
or, if you don't like using extra variable for some reason
if ( control.AsButton.Text == "Wall-E" ) {
I don't really see any reason why you should avoid making extra variable. This is a way to go when you are making a conversion or getting internal object from other object.
If you're using this handler function for multiple buttons, doing what you did is exactly how it works, in principle.
I'd not check against the button text but rather name them and check the button directly though, and you don't need the ID:
if (control == btnWallE) ...
// or, in case that doesn't work
NameCheckBtn = control.AsButton;
if (NameCheckBtn == btnWallE) ...
Crimson Wizard,
You're right, there's no reason to AVOID making an extra variable, but, in six months time when I look over my own code, the more variables I use, the longer is takes for me to decipher my own code! That's an irritation that I'd like to avoid if I can. And, again, this was just to further my own understanding .
"control.AsButton.Text" will come in handy.
Khris,
You are a fountain of scripting wisdom. In this case, however, the game-puzzle required the buttons to be completely random, and I can rename the TEXT of the button but not the NAME. So, I assume I'm better off working the way I demonstrated.
Thanks,
Cogliostro
Still a bad idea; using text for checks like that is inherently unreliable, and your code will break as soon as you want to translate your game, to name one example of why it's not future proof.
But you can simply store the button with the correct solution in a Button pointer, then compare the clicked button to that. It might seem like overkill, but it's always best to adopt good practices from the start.
Quote from: Khris on Tue 26/08/2014 20:19:30
Still a bad idea; using text for checks like that is inherently unreliable, and your code will break as soon as you want to translate your game
I agree with Khris, I think it's bad design to use the Text value when the goal is to check the identity of the actual button/control. But it's ok for a small, quick project, provided it won't be translated.
My own concern would be to test that the control is actually a button before doing anything with it (just in case the gui grows bigger and gets more controls, some of them not being buttons):
Button *btn = control.AsButton;
if (btn!=null)
{
...
}
Translating the game had been something I was specifically thinking about, and I thought I had been using best practices with my code. Clearly, an "extra" step with a Button pointer is required.
Thanks for the follow up,
Cogliostro