Declaring groups of specific buttons??

Started by subspark, Mon 07/09/2009 10:29:00

Previous topic - Next topic

subspark

I tried to create an array of certain Buttons to call them by just one name, "ButtonsWithSounds" like this:

Code: ags

function repeatedly_execute ( )
{
  String ButtonsWithSounds = bMainCancel;
  String bMainSave = ButtonsWithSounds;
  String bMainLoad = ButtonsWithSounds;
  String bMainLoad = ButtonsWithSounds;
  String bMainRestart = ButtonsWithSounds;
  String bMainQuit = ButtonsWithSounds;
  String bModalYes = ButtonsWithSounds;
  String bModalNo = ButtonsWithSounds;
  String bNewGame = ButtonsWithSounds;
  String bLoadGame = ButtonsWithSounds;
  String bOptions = ButtonsWithSounds;
  String bCredits = ButtonsWithSounds;
  String bQuit = ButtonsWithSounds;
  String bLoadGameCancel = ButtonsWithSounds;
  String bLoadGameLoad = ButtonsWithSounds;
  String bSaveGameCancel = ButtonsWithSounds;
  String bSaveGameSave = ButtonsWithSounds;
  String bCombatHelpOk = ButtonsWithSounds;

  if (mouse.IsButtonDown(eMouseLeft) && Button.GetAtScreenXY(mouse.x, mouse.y)=="ButtonsWithSounds") {
    aClickDown.Play(eAudioPriorityVeryLow, eOnce);
  }
  else if (mouse.IsButtonReleased(eMouseLeft) && Button.GetAtScreenXY(mouse.x, mouse.y)=="ButtonsWithSounds") {
    aClickUp.Play(eAudioPriorityVeryLow, eOnce);
  }
}


Basically I want a sound to play when a GUI button is clicked down, and another sound for when that button is released.
Is there some neater way to do this?

Cheers,
Sparky.


NsMn

You need a Pointer, not a string. (Button*)

Also, if those buttons are all in one GUI, you must only check wether the mouse is over the GUIand any button.

subspark

The "buttons with sounds" come from all of my GUIs.

So like this?

Code: ags
function repeatedly_execute ( )
{
  Button* ButtonsWithSounds = bMainCancel;
  Button* bMainSave = ButtonsWithSounds;
  Button* bMainLoad = ButtonsWithSounds;
  Button* bMainLoad = ButtonsWithSounds;
  Button* bMainRestart = ButtonsWithSounds;
  Button* bMainQuit = ButtonsWithSounds;
  Button* bModalYes = ButtonsWithSounds;
  Button* bModalNo = ButtonsWithSounds;
  Button* bNewGame = ButtonsWithSounds;
  Button* bLoadGame = ButtonsWithSounds;
  Button* bOptions = ButtonsWithSounds;
  Button* bCredits = ButtonsWithSounds;
  Button* bQuit = ButtonsWithSounds;
  Button* bLoadGameCancel = ButtonsWithSounds;
  Button* bLoadGameLoad = ButtonsWithSounds;
  Button* bSaveGameCancel = ButtonsWithSounds;
  Button* bSaveGameSave = ButtonsWithSounds;
  Button* bCombatHelpOk = ButtonsWithSounds;

  if (mouse.IsButtonDown(eMouseLeft) && Button.GetAtScreenXY(mouse.x, mouse.y)=="ButtonsWithSounds") {
    aClickDown.Play(eAudioPriorityVeryLow, eOnce);
  }
  else if (mouse.IsButtonReleased(eMouseLeft) && Button.GetAtScreenXY(mouse.x, mouse.y)=="ButtonsWithSounds") {
    aClickUp.Play(eAudioPriorityVeryLow, eOnce);
  }
}


Also, how would I check if the mouse button has just been released from a down state on one of these sound enabled buttons?
(mouse.IsButtonReleased) is not really an actual function obviously.

Cheers,
Sparky.

Khris

#3
Slow down, you've got it all wrong.
You want to add an attribute to several buttons, so you need a proper way to store it.

One way is to use an array. One could fake a two-dimensional one, but that isn't really necessary. A GUI can have a maximum of 30 controls, so I'll use Gui.ID*100 + Button.ID, as in the array index of button 4 on gui 2 is going to be 204.
Code: ags
// above game_start

bool button_with_sounds[10000];  // 99 Guis tops

void AddSounds(this Button*) {
  button_with_sounds[this.OwningGUI.ID*100 + this.ID] = true;
}

bool HasSounds(this Button*) {
  return button_with_sounds[this.OwningGUI.ID*100 + this.ID];
}

// inside game_start

  bMainCancel.AddSounds();
  bMainSave.AddSounds();
  ...

// add on_event, if necessary
void on_event (EventType event, int data) {
  GUIControl*gc = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
  Button*b;
  if (gc != null) b = gc.AsButton;

  if (event == eEventGUIMouseDown && b != null)
    if (b.HasSounds()) aClickDown.Play(eAudioPriorityVeryLow, eOnce);

  if (event == eEventGUIMouseUp && b != null)
    if (b.HasSounds()) aClickUp.Play(eAudioPriorityVeryLow, eOnce);

}


Not tested!

EDIT: Code corrected, thanks dkh!

subspark

Most appreciated Khris. Thanks for the kickstart here.
Thumbs up!

Sparky.

DoorKnobHandle

Just for reference, Krishmuc's code is absolutely correct apart from a typo:

Code: ags

this.OwningGUI*100 + this.ID


should be:

Code: ags

this.OwningGUI.ID*100 + this.ID


That line appears two times. Also don't forget to replace:

Code: ags

GUIControl*gc = GUIControl.GetAtScreenXY(int x, int y);


with:

Code: ags

GUIControl*gc = GUIControl.GetAtScreenXY(mouse.x, mouse.y);

monkey0506

#6
There's something else in Khris's code which isn't necessarily wrong, but it's safer to use the built-in constant AGS_MAX_CONTROLS_PER_GUI than just a static value in case that ever changes.

So:

Code: ags
this.OwningGUI.ID*AGS_MAX_CONTROLS_PER_GUI + this.ID


Another point as for the size of the array you could do this (as long as you're using AGS 3.0+):

Code: ags
bool button_with_sounds[];

function game_start() {
  button_with_sounds = new bool[Game.GUICount * AGS_MAX_CONTROLS_PER_GUI];
}


The up-shot of that being that 1) you could potentially save memory if you have fewer than 99 GUIs and 2) if you have more than 99 GUIs you wouldn't have to go back and change the code to make it work with those GUIs.

Also subspark you might want to take a look at AGS Pointers for Dummies, a guide I wrote to (hopefully) help people better understand pointers (both in general, and specifically within AGS). Just looking at your second example you're assigning multiple different pointers all pointing at bMainCancel (clearly indicating you don't fully understand exactly what you're doing). In both of your example scripts you're doing some casting between Button* and String which AGS does not allow.

Another problem is that you were creating and assigning multiple variables (actually pointers) inside of rep_ex! When you have a variable (or pointer) inside a function like that it will get created, used, and then destroyed every time the function is called. If you find yourself creating that many local variables (pointers, whatever) inside of a function, you may need to re-evaluate what you're doing.

As for what you're trying to accomplish Khris's example should serve quite well. You don't want to just create local synonyms for all of the buttons you're working with anyway. All the bMainCancel, bMainSave, bMainLoad, etc. should be set in the editor. You shouldn't be attempting to change those values at all. If you want to store additional data, you need to come up with a custom storage method (such as Khris's example which uses a boolean array for data storage) as well as accessor methods (how you will get and set the values of your data).

I'm not trying to discourage you from trying your own hand at scripting though. But as Khris said:

Quote from: Khris on Mon 07/09/2009 11:46:24Slow down, you've got it all wrong.

Take some time and don't be afraid to start from the beginning if you have to. Trust me, it pays off in the end. ;)

SMF spam blocked by CleanTalk