[SOLVED]Running multiple version of script

C

Cooltrain

Guest
Working on some GUI Buttons which I've built into 3 scripts, one for the create, one for the step, and one for the drawGUI, the buttons themselves work fine. Its just the problem of running them doesn't lend it self into creating multiple buttons. I'm thinking I need some kinda of buttonID/array to track which button is which but I'm not sure how to approach it. The aim is to be able to call these scripts from any object and create buttons easily.

scr_int_button
Code:
///scr_int_button(xGUI,yGUI,sprite)

button_pressed = false;
hover = false;

sprite_index=argument[2];
image_index=0;
image_speed=0;

button_x = argument[0];
button_y = argument[1];

button_width = sprite_get_width(argument[2])
button_height = sprite_get_height(argument[2])

//positions for mouse bounding box
button_left = button_x - button_width / 2;
button_right = button_left + button_width - 1;
button_top = button_y - button_height / 2;
button_bottom = button_top + button_height - 1;
scr_step_button
Code:
///scr_step_button()
hover = point_in_rectangle(device_mouse_x_to_gui(0), device_mouse_y_to_gui(0), button_left, button_top, button_right, button_bottom);

if (!hover){
button_pressed = false;
}else
{
    if (mouse_check_button_pressed(mb_left))
    {
        button_pressed = true;
    }
    else if (mouse_check_button_released(mb_left) && button_pressed)
    {
        // click action
        scrToCall = asset_get_index(argument[0])
        script_execute(scrToCall)
    }
}
scr_drawGUI_button
Code:
///scr_drawGUI_button()
if (button_pressed==true){
draw_sprite(sprite_index, 1, button_x, button_y);
}else if hover == true{
draw_sprite(sprite_index, 2, button_x, button_y);
}else{
draw_sprite(sprite_index, 1, button_x, button_y);
}
So if I were to list a bunch of new button script calls such as
Code:
scr_int_button(200,140,spr_sprite)
scr_int_button(300,140,spr_sprite)
scr_int_button(400,140,spr_sprite)
scr_int_button(500,140,spr_sprite)
Then it would create three working buttons. I might also need to list the scripts for the step and GUI the same number of times in the calling object ? I guess I need a way of indexing all the buttons that are created and running the code for each, or something ?

Any thoughts ?
 
C

CedSharp

Guest
I would create a ds_list containing arrays.

Index 0 of the ds_list would be the first button.
Index 1 of the ds_list would be the second button, etc.

A "button" would be an array containning all the needed info.
button[0] = sprite
button[1] = left
button[2] = top
button[3] = right
button[4] = bottom
button[5] = x
button[6] = y

Then in the create script, you would set the array and add it to the list,
in the step and draw event you would loop the list and use the info from the arrays :p

Hopefully this helps you
 

Tthecreator

Your Creator!
The first thing you need to do is think about all the variables your sprite will need. Is it that sprite to use, x position, y position, width or height?
Then when you know that, you can create a few arrays, or ds lists or a single ds map in which you hold all of these values.
Then you need a single script inside your step and draw event which loops trough all items in you data structure and handles the data.
If you need more information on what code to use, add another reply below and tag me @Tthecreator
 
C

Cooltrain

Guest
The first thing you need to do is think about all the variables your sprite will need. Is it that sprite to use, x position, y position, width or height?
Then when you know that, you can create a few arrays, or ds lists or a single ds map in which you hold all of these values.
Then you need a single script inside your step and draw event which loops trough all items in you data structure and handles the data.
If you need more information on what code to use, add another reply below and tag me @Tthecreator
Thanks both of you for the advice. I'm thinking something like this ?

Code:
///scr_init_button(x,y,width,height,sprite)
totalNumberButtons=2;
for(i=0;i<totalNumberButtons;i++){

button[i,0]=false;//mouse pressed
button[i,1]=false; //hover

button[i,2]=argument[4]//sprite
button[i,3]=image_index//image Index
button[i,4]=image_speed//image speed

button[i,5]=argument[0]//buttonX
button[i,6]=argument[1]//buttonY

button[i,7]=argument[2] //width
button[i,8]=argument[3] //height

button[i,9]=button[i,5]- button[i,7] /2; //button left
button[i,10]=button[i,9] + button[i,7] -1; //button right
button[i,11]=button[i,6] - button[i,8] /2;//button top
button[i,12]=button[i,11] + button[i,8]-1; //button bottom

}
I'll take you up on that offer @Tthecreator
 

Tthecreator

Your Creator!
Yea!, that's totally possible.
You just need some scripts that automatically handle everything so you can just call one creation script per button and have one single script in step and draw handle all of the buttons in a single script.
 
C

Cooltrain

Guest
Yea!, that's totally possible.
You just need some scripts that automatically handle everything so you can just call one creation script per button and have one single script in step and draw handle all of the buttons in a single script.
@Tthecreator

Ok so in my test project I've got creation script, and the step and gui code in an object. But the last button create call is the only one that is created. I think because the others are being overwritten ?

Creation script called by scr_init_button(x,y,width,height,sprite,clickAction)

Example being: scr_init_button(200,200,60,17,spr_tab,"scr_action_2");

Code:
///scr_init_button(x,y,width,height,sprite,clickAction)
totalNumberButtons=2;
for(i=0;i<totalNumberButtons;i++){

button[i,0]=false;//mouse pressed
button[i,1]=false; //hover

button[i,2]=argument[4]//sprite
button[i,3]=image_index//image Index
button[i,4]=image_speed//image speed

button[i,5]=argument[0]//buttonX
button[i,6]=argument[1]//buttonY

button[i,7]=argument[2] //width
button[i,8]=argument[3] //height

button[i,9]=asset_get_index(argument[5])

button[i,10]=button[i,5]- button[i,7] /2; //button left
button[i,11]=button[i,10] + button[i,7] -1; //button right
button[i,12]=button[i,6] - button[i,8] /2;//button top
button[i,13]=button[i,12] + button[i,8]-1; //button bottom

}
obj_gui step

Code:
//key press event
for(i=0;i<totalNumberButtons;i++){
button[i,1] = point_in_rectangle(device_mouse_x_to_gui(0), device_mouse_y_to_gui(0), button[i,10], button[i,12], button[i,11], button[i,13]); //hover inside box

if (!button[i,1]){
button[i,0] = false; //if not hover remove pressed
}else
{
    if (mouse_check_button_pressed(mb_left))
    {
        button[i,0] = true; //pressed is true
    }
    else if (mouse_check_button_released(mb_left) && button[i,0]) //mouse button released
    {
        // click action
        scrToCall = button[i,9];
        script_execute(scrToCall)
     }
    }
}
Finally obj_gui DrawGUI event
Code:
for(i=0;i<totalNumberButtons;i++){
    if (button[i,0]==true){
        draw_sprite(button[i,2], 1, button[i,5], button[i,6]);
    }else if button[i,1] == true{
        draw_sprite(button[i,2], 2, button[i,5], button[i,6]);
    }else{
        draw_sprite(button[i,2], 1, button[i,5], button[i,6]);
    }
}
So, how can I stop the last created button overriding the others ? And what would be the best way of having the totalNumberButtons increase each time I run the script for a new button ? Should it just be a global var ?

Thanks again
 

Tthecreator

Your Creator!
What the script should look like:
Code:
///scr_init_button(x,y,width,height,sprite,clickAction)
var i=array_height_2d(button)//I've added a link to the manual here.

button[i,0]=false;//mouse pressed
button[i,1]=false; //hover

button[i,2]=argument4//sprite
button[i,3]=image_index//image Index
button[i,4]=image_speed//image speed

button[i,5]=argument0//buttonX
button[i,6]=argument1//buttonY

button[i,7]=argument2 //width
button[i,8]=argument3 //height

button[i,9]=asset_get_index(argument5)

button[i,10]=button[i,5]- button[i,7] /2; //button left
button[i,11]=button[i,10] + button[i,7] -1; //button right
button[i,12]=button[i,6] - button[i,8] /2;//button top
button[i,13]=button[i,12] + button[i,8]-1; //button bottom
then inside your other code totalNumberButtons will be equal to array_height_2d(button);
Also you had all the arguments as an array, but that is slower than having using the normal argument variable.

You were overriding everything because you had a for loop looping trough everything. I hope you see your error. If you don't then please tell me because you won't have learned anything in that case.
 
C

Cooltrain

Guest
What the script should look like:
then inside your other code totalNumberButtons will be equal to array_height_2d(button);
Also you had all the arguments as an array, but that is slower than having using the normal argument variable.

You were overriding everything because you had a for loop looping trough everything. I hope you see your error. If you don't then please tell me because you won't have learned anything in that case.
Ah of course, the array height is the number of entries, (which I've used before in an inv system). Yea the loop was going back over those values again. The buttons are working fine, although it seems like the drawGUI is drawing some sprites that it shouldn't be in the top corner... and I'm really not sure why. It seems to be tied to the final else event in the drawGUI. Any thoughts @Tthecreator ?

Edit: So it seems to be drawing which ever sprite has a sprite index of 0.
 
Last edited by a moderator:

Hyomoto

Member
The literal easiest way to do this is to not use a script, and instead have a parent object with all your shared code, and then child objects that have object-specific code. Using user-defined scripts in this case adds a level of hassle you can simply overcome by not using them. The parent object can add itself to a controller's array which can then track this information. I've spent a lot of time trying to come up with useful solutions to UI problems in GameMaker and I promise this is the simplest.

It's fine to have a common code-base for various objects to share, but at some point you just need custom code per-button, so it's best to use the parent-child hierarchy and keep your code in the objects themselves.
 
C

Cooltrain

Guest
The literal easiest way to do this is to not use a script, and instead have a parent object with all your shared code, and then child objects that have object-specific code. Using user-defined scripts in this case adds a level of hassle you can simply overcome by not using them. The parent object can add itself to a controller's array which can then track this information. I've spent a lot of time trying to come up with useful solutions to UI problems in GameMaker and I promise this is the simplest.

It's fine to have a common code-base for various objects to share, but at some point you just need custom code per-button, so it's best to use the parent-child hierarchy and keep your code in the objects themselves.
In the long term if this doesn't work for what I need, I'll be sure to look into this.

@Tthecreator I've hot fixed the sprite showing in the top corner. When the mouse isn't pressed on the button the else statement is still trying to draw a sprite so its defaulting to the first sprite index of 0 as well as 0,0 for the x, and y. Now that's fixed it seems to be working fine for what I need currently. Thank you for all of your help, you've been invaluable. Anyway... back to work ;)
 
Top