[SOLVED] Function parameters with pointers

Started by Baguettator, Thu 06/08/2020 08:43:55

Previous topic - Next topic

Baguettator

Hello again !

I encounter a new problem. I'm trying to simplify my code now that I have learnt a lot since I started AGS a few month ago.

I tried to create a specific function with parameters to simplify the code (and hugely decrease the size of the script !!!). But I encounter problems while using pointers in parameters.

I created Button pointers in my script :

Code: ags
Button *garage[10];
Button *salon[10];


And I want to do something like :

Code: ags
function Objectifs(int obj, Button *type)
{
  int control;
  if (obj==1) control=32;
  if (obj==2) control=45;
  type[obj]=gAffichageexpedition.Controls[control].Asbutton;
}


And I think that when I click the button, it could be like this :

Code: ags
function Button1_Onclick
{
  if (garage[1]==this) Garage(1, 25); // assuming there is a function "Garage" that does something in the case this button is a "garage"
  if (salon[1]==this) Salon(1, 56); // the same if this button is a "salon"
}


Is my code correct ? I don't manage to get it working, so probably I made a mistake or don't understand how it works...

Khris

In general: each OnClick function has two parameters: the mouse button and the Control that was clicked. In case you've assigned the OnClick function to multiple buttons, you can use that parameter to check which button was clicked.

Let's say there's ten buttons, and all of them have objectif_OnClick in their events table. The function will look like:
Code: ags
function objectif_OnClick(MouseButton button, GUIControl* control) {
  if (control.ID == 0) Display("You clicked the first button.");
}

(There's no  this  here, that only exists in a struct's instance method.)

As for your code, can you explain which GUI type / gameplay mechanic you're trying to implement? Best try explaining it without using AGS technical terms.

Baguettator

OK, I didn't know that I can use the parameters of the function On click ! Thanks for the information :)

What I want to do is that my character arrive in a room (1 for example), and in this room a map is randomly chosen. To show the map (understand the background image of the room that shows a building's interior), I use a Dynamic Sprite that draws the chosen sprite on the background of the room (that works perfectly, no problem for that).

Depending which map is chosen, I have to place up to 9 buttons of a transparent GUI (only the small buttons are important), and when the player click on a button it happens an event randomly chosen depending which "type" of button has been clicked.

In my first "design", I made 9 buttons of each type (garage, salon, chambre...) to represent all the possibilities, and if the 1st button to place was a type "garage", I get garage1.Visible=true. If it was a "salon", salon1.Visible=true. For the second button, if it was a chambre, chambre2.Visible=true. etc... up to the 9th.

So what I want to do is to reduce the number of buttons and mechanicly reduce the script by simplifying : instead of 9 buttons for each type (at the moment it is a total of 81 buttons for me !!!), just have 9 buttons "generic", and instead of "when you click garage1 or other button named garage, it calls the function Garage()", replace by something like "when you click on button1, if the pointer that point to button1 is garage[1], call the function Garage()"

I hope I am clearer now, but it is not easy to explain that kind of thing I think :S (or my english is so bad that... umpf :) )

Khris

I see, so every background has all of the nine button types? And they're just in different positions?

Because if that's the case, you can use a single button for the garage and merely change its position based on the background image. And in the button's OnClick, you'd then run "garage code", also based on the background image.

Or you can use a single OnClick for all nine buttons and use control.ID and background image to run the appropriate function.

Baguettator

In fact, every background has not the nine buttons type. Maybe for one background, there will be 3 buttons type "garage", 2 buttons type "salon", 3 buttons type "chambre", but for another background, it will be 1 button type "cuisine", 2 buttons type "salon" and that's all...

9 is the maximum buttons a  background can have. But it is possible that there will be several buttons of a type, none of another type etc...

That's why I wanted to use pointers to say : "now this button is a garage, this button is also a garage, but this one is a cuisine, and the others are not use so no pointer needed for those now."


Baguettator

Maybe I have found out how to get that working !

Is it right if I create 2 pointers, and if I write something like that :

Code: ags
Button *pionobjectif;
Button *type;

// In game start function :
pionobjectif=gAffichage.Controls[1].Asbutton;
type=gAffichage.Controls[1].Asbutton;

if (pionobjectif == type) 
// Do something


Is it correct syntax for that ?

Because I want to do that : (Assuming that I created an array of pointers : pionobjectif[10];

Code: ags
function Objectifs(int pion, int nombre, Button* type1, int xtype1, int ytype1, Button* type2, int xtype2, int ytype2, Button* type3, int xtype3, int ytype3, Button* type4, int xtype4, int ytype4)
{
  int o=Random(nombre-1);
  if (o==0)
  {
    type1=pionobjectif[pion];
    type1.Visible=true;
    type1.SetPosition(xtype1, ytype1);
  }
  if (o==1)
  {
    type2=pionobjectif[pion];
    type2.Visible=true;
    type2.SetPosition(xtype2, ytype2);
  }
  if (o==2)
  {
    type3=pionobjectif[pion];
    type3.Visible=true;
    type3.SetPosition(xtype3, ytype3);
  }
  if (o==3)
  {
    type4=pionobjectif[pion];
    type4.Visible=true;
    type4.SetPosition(xtype4, ytype4);
  }
}


So I need to script : type1 (or type2 or type3 or type4) is pointing to the same button as pionobjectif[pion]. By this way, if as a parameter I write garage[1] for type1, I can call the function that creates an event for the garage type !! :)


Khris

I don't know about that approach, especially the first snippet seems like total nonsense to me :-D

Anyway, you need to create a basic data structure to store the button types and positions for the different backgrounds.
A nice approach is to write the function calls you want to use, them write the functions for them.
Just pretend the function already exists, and provide suitable arguments.

As an example, here's setting up the room:
Code: ags
  int bgImage = Random(6);

  if (bgImage == 1) {
    SetRoomButton(0, eRoomGarage, 234, 123);
    SetRoomButton(1, eRoomSalon, 160, 80);
  }


Next you start writing the  SetRoomButton  function:

Code: ags
function SetRoomButton(int id, RoomType type, int x, int y) {
  Button* b = gRoom.Controls[id].AsButton;
  b.SetPosition(x, y);
  b.NormalGraphic = button_sprites[type];
}


Now it becomes clear that we need an array  button_sprites  that stores the sprites for each room type. We can also use this to determine which code to run when the user clicks the button (at least in theory).
We might also wonder at this point whether we should set up a struct to store additional info for the rooms buttons, like for instance their type.

Another benefit of this approach is that you keep finding out which information your game needs, and it's more likely that you will avoid redundancies.

Baguettator

#7
Okay, I see and start to understand your approach.

The problem is that the buttons have the same sprite, so I can't use the sprite to "identify" if it is a button for a garage event, or a salon event...

By Structure, you mean that I can create a structure for buttons ? And having something like "button1.garage" to say "the 1st button of the room is for a garage event" ?

I don't know a lot about structures, can you give me an example please ?

The room types are : garage, salon, chambre, cuisine, wc, rangement, bureau. So I imagine that with a structure I can define "properties" for buttons (like bool garage, bool salon etc...), and then set the properties of the buttons in the function that randomly choose them and, depending of the background, place them there or anywhere else.

EDIT : I don't know how to declare structures and how to configure them, that's what I want to say :p

Baguettator

Found out how to do that without using structure : I used enum for a function parameter, and it was perfect ! I discovered how to use enum, it is sooooooo useful !

thanks for the help !

SMF spam blocked by CleanTalk