Any problem in creating and deleting buttons all the time?

Discuss any general programming issues here
Post Reply
Bugala
Posts: 1178
Joined: Sun Feb 14, 2010 7:11 pm

Any problem in creating and deleting buttons all the time?

Post by Bugala »

I have used to programming using layers. However, with my latest game (still havent got to final release it, but soon perhaps) I instead tried non layer approach, and I liked it quite much actually and I am now thinking using it in my next project too.

As I am thinking on how to solve the buttons problems, one thought came to my mind, but I wonder if it is actually safe to do so, or can it cause some problem.

In layers approach, my buttons work so that they are calling a Function called for example "VirtualButtonFunction1"'.

This VirtualButtonFunction is very simple:

Code: Select all

Function VirtualButtonFunction()
RealButtonFunction1()
EndFunction
By otherwords, this button function was simply calling the real function.

Reason for this was because sometimes I wanted to change the button function on fly. That lets say normally I wanted a button click to shoot, but then suddenly I wanted the same button to instead shoot a missile or not even do anything at all. Since Hollywood dont let you change button functions on fly, I made this call to another function, since this RealButtonFunction could be changed on fly.


Since I like to have this same functionality of changing buttons on fly in this non layer approach too, what I have in my mind is following:

I would have a table called "table_Buttons".

then when ever I want some button to exist, i would throw it to that list of buttons.

Then there be a command like ButtonsCreate() which would create all those buttons currently in that list of buttons.

If I want to change function of one button, I would first use ChangeButtonFunction() command, which would affect Teble_button.ID.function

and then I would call ButtonsCreate() again, which would first delete all currently existing button, and then create them again based upon all on that button list.

From progamming point of view this seems to me like a good solution for my problems, but I am worried will it be a problem if I continuously keep deleting and creating buttons? As example, if one button is removed (for example some game menu closed) it means all buttons would be created again after to be deleted ones are removed from list first.
amyren
Posts: 361
Joined: Thu May 02, 2019 11:53 am

Re: Any problem in creating and deleting buttons all the time?

Post by amyren »

Your programming is probably more advanced than mine anyway. Many times I discover there are much simpler ways to acheive things, compared to my code with lots of extra code to compensate for missing knowledge :)
But I do have made a working example her on how to have buttons changed on the fly, with "home made" button routine

Code: Select all

@BGPIC 1, "background_1.png"
@DISPLAY {Title = "Buttontest", ScaleMode = #SCALEMODE_AUTO, fitscale = True, HideTitleBar = True}
 
LoadSprite(1, "Button1.png", {width = 80 , height = 25, Frames = 2, FPR = 2, Transparency = #BLACK})
LoadSprite(2, "Button2.png", {width = 80 , height = 25, Frames = 2, FPR = 2, Transparency = #BLACK})

button1on = True
button2on = True

If button1on 
	DisplaySprite(1, 20, 50, 1)
EndIf
If button2on 
	DisplaySprite(2, 120, 50, 1)
EndIf

Function p_HandlerFunc(msg)
	mousexpos = MouseX()
	mouseypos = MouseY()
  Switch(msg.action)
  Case "OnMouseDown":
	If button1on
		If mousexpos > 20 And mousexpos < 100 And mouseypos > 50 And mouseypos < 75
			DisplaySprite(1, 20, 50, 2)
			button1pressed = True
		EndIf
	EndIf
	If button2on
		If mousexpos > 120 And mousexpos < 200 And mouseypos > 50 And mouseypos < 75
			DisplaySprite(2, 120, 50, 2)
			button2pressed = True
		EndIf
	EndIf
  Case "OnMouseUp":
		If button1on
			If mousexpos > 20 And mousexpos < 100 And mouseypos > 50 And mouseypos < 75
				DisplaySprite(1, 20, 50, 1)
				button1pressed = False
				button1 = True
				p_dobutton
			EndIf
		EndIf
		If button2on
			If mousexpos > 120 And mousexpos < 200 And mouseypos > 50 And mouseypos < 75
				DisplaySprite(2, 120, 50, 1)
				button2pressed = False
				button2 = True
				p_dobutton
			EndIf
		EndIf
  Case "OnMouseMove":
		If button1on
			If button1pressed
				If Not (mousexpos > 20 And mousexpos < 100 And mouseypos > 50 And mouseypos < 75)
					DisplaySprite(1, 20, 50, 1)
					button1pressed = False
				EndIf
			EndIf
		EndIf
		If button2on
			If button2pressed
				If Not (mousexpos > 120 And mousexpos < 200 And mouseypos > 50 And mouseypos < 75)
					DisplaySprite(2, 120, 50, 1)
					button2pressed = False
				EndIf
			EndIf
		EndIf
  Case "OnKeyDown":
    If msg.key = "ESC" Then End
  EndSwitch
EndFunction

Function p_dobutton()
	If button1 = True
		DebugPrint("Button 1 activated")
		button1 = False
		If button2on = True
			button2on = False
			RemoveSprite(2)
		Else
			button2on = True
			DisplaySprite(2, 120, 50, 1)
		EndIf
	EndIf
	If button2 = True
		DebugPrint("Button 2 activated")
		button2 = False
		If button1on = True
			button1on = False
			RemoveSprite(1)
		Else
			button1on = True
			DisplaySprite(1, 20, 50, 1)
		EndIf
	EndIf

EndFunction

InstallEventHandler({ OnKeyDown = p_HandlerFunc,
    OnMouseMove = p_HandlerFunc, OnMouseDown = p_HandlerFunc,
   OnMouseUp = p_HandlerFunc})

Repeat
	WaitEvent
Forever
Bugala
Posts: 1178
Joined: Sun Feb 14, 2010 7:11 pm

Re: Any problem in creating and deleting buttons all the time?

Post by Bugala »

Thanks for giving that example, but it is not a question of that I couldnt change buttons functionality on the fly, it has to do with programming technic.

To show what I am after, I will use some almost pseudocode with your example:

Code: Select all

OnMouseUp:
If mode=1 then DoMouseUpFunction1
if mode=2 then DoMouseUpFunction2
Now I can control this by simply setting mode=1, or mode=2 and it works fine.

However, This is not a good system from code reusability point of view or code uplkeeping point of view.

Lets say I have 10 different functions for a button and use this same system, by having 10 lines like this.

Or actually, it is better illustrated by giving more realistic version:

Code: Select all

OnMouseUp:
if mode=1
lots of code
if mode = 2
lots of code
if mode=3
lots of code
...
Suppose I want to use some of these functions in some other program. Now I need to copy them and also remember to remove the unnecessary lines.

It also becomes harder to read what is happening, since it is all around messier.

Also, when I change the mode, even if i name it well, it is still not telling as much info as the direct assign of function does, since to find out the function name, i would still in worse case need to check it from the OnMouseUp place, and if i decide to change something, i need to change in two different places, plus the problem that mode might change for some reason, and when button is clicked and i think it is supposed to do mode 1 situation, it is actually doing mode 2 situation.

This all can be avoided by simply using:

Code: Select all

OnMouseUp = FireGun
now i change my mind
OnMouseUp = FireMissile
Only one line had to be changed, and there is no chance that FireGun() would happen accidentally because mode will be wrong when button is pressed.

In addition, if I ever want to assign this FireMissile() to another button, I dont need to find the OnMouseButton place and change code there, but all I have to do is OnMouseDown = FireMissile().

This also means that I can save FireMissile() function on separate fie in same folder with other similar functions. ANd then I can just open the folder, see all the options and then just keep using: OnMiddleMouseUp = DoNothing(), OnMiddleMouseDown=FireMissile() etc.

So it is a matter of keeping the code clean, better maintainable, and bug free.

Not so much that it isnt doable.

Your system however works fine, and as long as it works fine for you, no need to do it any other way.

Myself I am aiming at being able to reuse same code preferably by simply copy-pasting it to next project, so my requirements are bit different.

I am aiming at making them independent from other functions, that theoretically I could copy-paste every second function from two different programs and end up having a third program (not working like that in reality, but just to explain the idea).
Bugala
Posts: 1178
Joined: Sun Feb 14, 2010 7:11 pm

Re: Any problem in creating and deleting buttons all the time?

Post by Bugala »

@airsoftsoftwair

Having couple of problems to overcome and remembering amyrens code, I am starting to think that best solution is to make my own button code similar to amyrens, that instead of using #SIMPLEBUTTONS, I would be using similar handler_func as amyren is using on basis of finding out if one of the buttons is for example clicked or not.

Is there any benefit to using #SIMPLEBUTTON, or does it make any difference if using my own handler_func?

Like OnMouseOver case it means I would need to check every time through all the existing buttons if mouse is over them or not,and this could affect speed, but then again, doesnt #SIMPLEBUTTON do this anyway?

And if i have less than 100 buttons to check (more likely less than 20) does it even matter anyway?
Bugala
Posts: 1178
Joined: Sun Feb 14, 2010 7:11 pm

Re: Any problem in creating and deleting buttons all the time?

Post by Bugala »

And another question, will msg.action always be containing only one option? That basically user could both be moving the mouse and clicking a button at the same time, but will it then report only OnMouseDown for example?

And what about pushing both mouse buttons down at the same time?

Basically I dont think I really need to worry about this much, but just in case it becomes an issue one day, asking in advance so I can consider taking this into account.
PEB
Posts: 569
Joined: Sun Feb 21, 2010 1:28 am

Re: Any problem in creating and deleting buttons all the time?

Post by PEB »

Well, you can test it out:

Code: Select all

DebugPrint("Test:")

Function p_Events(msg)
	Switch msg.action
	Case "OnMouseDown"
		DebugPrint("Mouse Down")
	Case "OnMouseUp"
		DebugPrint("Mouse Up")
	Case "OnRightMouseDown"
		DebugPrint("Right Mouse Down")
	Case "OnRightMouseUp"
		DebugPrint("Right Mouse Up")
	Case "OnMouseMove"
		DebugPrint("Mouse Move:  X="..msg.x.."    Y="..msg.y)
	EndSwitch
EndFunction

InstallEventHandler({OnMouseDown=p_Events, OnMouseUp=p_Events, OnRightMouseDown=p_Events, OnRightMouseUp=p_Events, OnMouseMove=p_Events})
Post Reply