Posted: 12th Aug 2022 15:33
+ Code Snippet
global volume=100
global state_game=0
global select_base=0

#include "main_menu.agc"
#include "in_game_space.agc"
#include "button_code.agc"
load_main_menu()
load_space_box()
load_button()
_main_menu1:
rem main_menu do loop
`---------------------------------------------------------------


rem place the button in the centre of the screen..
x=GlobalWidth/2
y=GlobalHeight/2
dim v[7]
dim close[7]
dim text_base_menu[6]
dim button[7]
for t=1 to 7
	button[t]=t
    AddVirtualButton(button[t],x,y+t*33,100)
    //GetVirtualButtonExists
    //GetVirtualButtonPressed
    //GetVirtualButtonReleased
    //GetVirtualButtonState
    //SetButtonScreenPosition
    //SetVirtualButtonActive
    SetVirtualButtonImageDown(button[t],buttondown[t])
    SetVirtualButtonImageUp(button[t],buttonup[t])
    SetVirtualButtonPosition(button[t],x,y+t*33)
    //SetVirtualButtonSize
    SetVirtualButtonVisible(button[t],1)
   next t
   
`select_base=2
_main_menu:
do
	if close[1]=1 
		playsound(buttons_click,volume)
		close[1]=0
		if select_base=2 then goto _game:
	endif
	
	if close[2]=1 and select_base=0
		playsound(buttons_click,volume)
		close[2]=0
		for t=1 to 7
			SetVirtualButtonVisible(button[t],0)
		next t
		select_new_base()
		if select_base=2 then goto _game:
	endif
	
	if close[3]=1 
		playsound(buttons_click,volume)
		close[3]=0
		`goto _load_game:
	endif
	
	if close[4]=1 
		playsound(buttons_click,volume)
		close[4]=0
		`goto _save_game:
	endif
	
	if close[5]=1 
		playsound(buttons_click,volume)
		close[5]=0
		if GetMusicPlaying()=1 
			StopMusic( )
			    SetVirtualButtonImageDown(button[5],buttondown[8])
				SetVirtualButtonImageUp(button[5],buttonup[8])
	else
			    SetVirtualButtonImageDown(button[5],buttondown[5])
				SetVirtualButtonImageUp(button[5],buttonup[5])
			playmusic(music_loop,1)
		endif
	endif
	
	if close[6]=1 
		playsound(buttons_click,volume)
		close[6]=0
		if volume>0
			volume=0
			    SetVirtualButtonImageDown(button[6],buttondown[9])
				SetVirtualButtonImageUp(button[6],buttonup[9])
		else 
			volume=100 
			    SetVirtualButtonImageDown(button[6],buttondown[6])
				SetVirtualButtonImageUp(button[6],buttonup[6])
		endif
	endif
	
	if close[7]=1 
		playsound(buttons_click,volume)
		sleep(200)
		end
	endif
	
	for t=1 to 7
		teststandardbutton(t)
		if v[t]=2 then close[t]=1
	next t

    CycleTime#=CycleTime#+1
    CycleTime#=CycleTime#+1
    SunDirX#=sin(CycleTime#)
    SunDirY#=0
    SunDirZ#=cos(CycleTime#)
	SetSunDirection(SunDirX#,SunDirY#,SunDirZ#)

   sync()
loop

end






+ Code Snippet
function load_button()
	dim name$[9]  as string = [ "","  Return", "  Start", "  Load" ,"  Save","  Music ON","  Sound ON","  Exit","  Music OFF","  Sound OFF"]
	dim buttonup[9]
	dim buttondown[9]
	for t=1 to 9
		creatbutton(0,0,128,24,2)
		SetPrintColor( 0, 0, 0 )
		SetPrintSize( 22 )
		print(name$[t])
		render()
		buttonup[t]=GetImage(0,0,128,24)
		sync()
		creatbutton(0,0,128,24,3)
		SetPrintColor( 0, 0, 0 )
		SetPrintSize( 22 )
		print(name$[t])
		render()
		buttondown[t]=GetImage(0,0,128,24)
		sync()
	next t
endfunction

function teststandardbutton(t)

mx= GetPointerX() : my= GetPointery() : v[t]=0

rem find out wear the mouse pointer is..
	if GetVirtualButtonPressed(button[t])=1

  
      rem mouse pointer over button.
      rem button has been selected...
      v[t]=2 
      else  
		v[t]=1
		
      update=1
   endif
   
endfunction

function creatbutton(x,y,width,height,tipe)
	
   rem set-up colour palette, for this program
   white=MakeColor(255,255,255)
   black=0
   grey=MakeColor(192,192,192)
   yellow=MakeColor(255,255,0)
   darkgrey=MakeColor(104,100,128)

   bc=width/2

   select tipe
      case 2
         rem draw preselected button
    `     ink black,black
         DrawBox( x,y,(x+width),(y+height),0,0,0,0,1)

     `    ink white,black
         DrawBox( x+1,y+1,(x+width)-2,(y+height)-2,white,white,white,white,1)

      `   ink black,black
         DrawBox( x+2,(y)+2,(x+width)-1,(y+height)-1,grey,grey,grey,grey,1)

       `  ink grey,black
         DrawBox( x+2,(y+2),(x+width)-2,(y+height)-2,grey,grey,grey,grey,1)
         rem ink text colour to yellow,
        ` ink yellow,grey
      endcase
      case 3
		 
         rem draw standard button
         `ink black,black
         DrawBox( x,y,(x+width)-1,(y+height)-1,0,0,0,0,1)

         `ink white,black
         DrawBox( x+1,(y)+1,x+width,(y+height),white,white,white,white,1)

         `ink darkgrey,black
         DrawBox (x+1,(y+1),(x+width)-1,(y+height)-1,darkgrey,darkgrey,darkgrey,darkgrey,1)
      endcase
   endselect

		
      rem this the standard text set up for the buttons...

endfunction

what else can you think of?

Posted: 14th Aug 2022 21:17
I prefer to use sprites rather than buttons.
Instead of storing several dimensional variables, I prefer to store them in a UDT and make an array out of it.
Also, if you want to write more than just one game, I recommend to pay attention to reusability and readability in the code.

Here is an example of my button UDT.
+ Code Snippet
type tUI_Button
	label as integer		// the label of the button
	back as integer			// background of the button
	state as integer		// current state of the button, see constnts
	value as integer		// holds value 0/1 for somthing like checkboxes
	
	pos_x as float
	pos_y as float
	width as float
	height as float
	
	lbl_offsetx as float
	lbl_offsety as float
endtype

Instead of a function that somehow starts with create, I prefer to use a function with the same name as the UDT.
As a constructor so to speak.
Old C/C++ habit
If the game is in prototyping phase and there are no graphics for the buttons you can set the parameter back to -1 then a background will be created automatically.
If a background graphic is available, width and height can be set to -1. They are automatically set to the size of the graphic.
If the size is to be changed then width and height can also be specified then the graphic is changed accordingly.
+ Code Snippet
function tUI_Button(label as string, back as integer, width as float, height as float)
	sprid as integer
	txtid as integer = -1
	result as tUI_Button

	result.value = -1
	if back < 1 and (width < 1 or height < 1) then exitfunction result
	
	if back > 0
		if width < 0 then width = GetImageWidth(back)
		if height < 0 then height = GetImageHeight(back)
	else
		back = _ui_make_button_background(width,height)
	endif
	
	if len(label)>0 
		txtid = CreateText(label)
		SetTextVisible(txtid,0)
		SetTextDepth(txtid,4)
		SetTextAlignment(txtid,1)
		SetTextSize(txtid,height*0.7)
		SetTextColor(txtid,0,0,0,255)
	endif
	
	sprid = CreateSprite(back)
	SetSpriteVisible(sprid,0)
	SetSpriteDepth(sprid,5)
	SetSpriteSize(sprid,width,height)
		
	result.lbl_offsetx = width*0.5
	result.lbl_offsety = height*0.15
	result.back = sprid
	result.label = txtid
	result.width = width
	result.height = height
endfunction result


function _ui_make_button_background(width as float, height as float)
	result as integer
	
	ClearScreen()
	DrawBox(0,0,width,height,COLOR_WHITE,COLOR_WHITE,COLOR_WHITE,COLOR_WHITE,1)
	DrawBox(2,2,width+2,height+2,COLOR_DGREY,COLOR_DGREY,COLOR_DGREY,COLOR_DGREY,1)
	DrawBox(1,1,width+1,height+1,COLOR_GREY,COLOR_GREY,COLOR_GREY,COLOR_GREY,1)
	Render()
	
	result = GetImage(0,0,width+3,height+3)
	SetImageMinFilter(result,0)
	SetImageMagFilter(result,0)
endfunction result


I like to define my indieces with constants (readability)
+ Code Snippet
#constant BTN_RETURN						0
#constant BTN_START							1
#constant BTN_LOAD							2
#constant BTN_SAVE							3
#constant BTN_MUSIC							4
#constant BTN_SOUND							5
#constant BTN_EXIT							6
#constant BTN_MAINMENU_COUNT				6

The creation of the buttons could then look like this.
+ Code Snippet
global main_menu as tUI_Button[BTN_MAINMENU_COUNT]
main_menu[BTN_RETURN] = tUI_Button("Return",-1,128,32)
main_menu[BTN_START] = tUI_Button("Start",-1,128,32)
main_menu[BTN_LOAD] = tUI_Button("Load",-1,128,32)
main_menu[BTN_SAVE] = tUI_Button("Save",-1,128,32)
main_menu[BTN_MUSIC] = tUI_Button("Music On",-1,128,32)
main_menu[BTN_SOUND] = tUI_Button("Sound On",-1,128,32)
main_menu[BTN_EXIT] = tUI_Button("Exit",-1,128,32)

// set start values
main_menu[BTN_RETURN].state = STATE_DISBALED
main_menu[BTN_SAVE].state = STATE_DISBALED
main_menu[BTN_MUSIC].value = 1
main_menu[BTN_SOUND].value = 1

This is what calling the buttons could look like.
+ Code Snippet
global g_quit_app as integer = 0
global g_ScreenWidth as float
global g_ScreenHeight as float
g_ScreenWidth = GetVirtualWidth()
g_ScreenHeight = GetVirtualHeight()

state as integer
i as integer
x as float
y as float
x = (g_ScreenWidth-main_menu[0].width)*0.5
y = (g_ScreenHeight-main_menu.length*48-48)*0.5

do
	if g_quit_app = 1 then exit
	
	for i=0 to main_menu.length
		state = DoMenuButton(main_menu[i], x, y+i*48)
		if state = STATE_PRESSED
			HandleMenuButton(i,state)
		endif
	next
	
    Print( ScreenFPS() )
    Sync()
loop

The function DoMenuButton only processes events that have a general effect on a button.
For example, playing a sound when a button is clicked.
+ Code Snippet
function DoMenuButton(btn ref as tUI_Button, posx as float, posy as float)
	state as integer
	
	if btn.state = STATE_DISBALED and GetSpriteColorAlpha(btn.back) <> 128 then SetSpriteColorAlpha(btn.back,128)
	if btn.state <> STATE_DISBALED and GetSpriteColorAlpha(btn.back) < 255 then SetSpriteColorAlpha(btn.back,255)
	
	state = uiDrawButton(btn,posx,posy)
	
	select state
		case STATE_ENTER
			// do something for each key that causes this event.
		endcase
		case STATE_HOVER
			// do something for each key that causes this event.
		endcase
		case STATE_PRESSED
			// do something for each key that causes this event.
		endcase
		case STATE_HOLD:
			// do something for each key that causes this event.
		endcase
		case STATE_RELEASED
			// do something for each key that causes this event.
		endcase
		case STATE_LEAVE
			// do something for each key that causes this event.
		endcase
	endselect
endfunction state

The statuses of the buttons are also defined via constants.
+ Code Snippet
#constant STATE_NOTHING						0
#constant STATE_ENTER						1
#constant STATE_HOVER						2
#constant STATE_PRESSED						3
#constant STATE_HOLD						4
#constant STATE_RELEASED					5
#constant STATE_LEAVE						6
#constant STATE_DISBALED					7

uiDrawButton draws the button and sets the corresponding state of the button.
+ Code Snippet
function uiDrawButton(btn ref as tUI_Button, posx as float, posy as float)
	state as integer
	mx as float
	my as float

	mx = GetRawMouseX()
	my = GetRawMouseY()
	state = btn.state

	if state <> STATE_DISBALED	
		if mx >= posx and mx <= (posx+btn.width) and my >= posy and my <= (posy+btn.height)
			if btn.state = STATE_NOTHING
				state = STATE_ENTER
			elseif btn.state = STATE_ENTER
				state = STATE_HOVER
			endif
			
			if GetPointerState() = 1 and state = STATE_PRESSED then state = STATE_HOLD
			if GetPointerPressed() = 1 then state = STATE_PRESSED
			if GetPointerReleased() = 1 then state = STATE_RELEASED
			
		elseif state <> STATE_NOTHING and state <> STATE_LEAVE
			state = STATE_LEAVE
		else
			state = STATE_NOTHING
		endif
	endif
	
	btn.state = state
	btn.pos_x = posx
	btn.pos_y = posy
	
	if btn.back > 0
		SetSpriteVisible(btn.back,1)
		SetSpritePosition(btn.back,btn.pos_x,btn.pos_y)
		DrawSprite(btn.back)
		SetSpriteVisible(btn.back,0)
	endif

	if btn.label > 0
		SetTextVisible(btn.label,1)
		SetTextPosition(btn.label,btn.pos_x+btn.lbl_offsetx,btn.pos_y+btn.lbl_offsety)
		DrawText(btn.label)
		SetTextVisible(btn.label,0)
	endif
endfunction state

The HandleMenuButton function in the main loop does the actual work and processes the input.
+ Code Snippet
function HandleMenuButton(index as integer, state as integer)	
	select index
		case BTN_RETURN
			// do something for each key that causes this event.
		endcase
		case BTN_START
			Message("Not implemented")
			// do something for each key that causes this event.
		endcase
		case BTN_LOAD
			Message("Not implemented")
			// do something for each key that causes this event.
		endcase
		case BTN_SAVE
			// do something for each key that causes this event.
		endcase
		case BTN_MUSIC
			main_menu[BTN_MUSIC].value = 1-main_menu[BTN_MUSIC].value
			if main_menu[BTN_MUSIC].value = 0
				SetTextString(main_menu[BTN_MUSIC].label,"Music Off")
			else
				SetTextString(main_menu[BTN_MUSIC].label,"Music On")
			endif
			// do something for each key that causes this event.
		endcase
		case BTN_SOUND
			main_menu[BTN_SOUND].value = 1-main_menu[BTN_SOUND].value
			if main_menu[BTN_SOUND].value = 0
				SetTextString(main_menu[BTN_SOUND].label,"Sound Off")
			else
				SetTextString(main_menu[BTN_SOUND].label,"Sound On")
			endif
			// do something for each key that causes this event.
		endcase
		case BTN_EXIT
			g_quit_app = 1
			// do something for each key that causes this event.
		endcase
	endselect
endfunction

This is what it would look like for me and is only a suggestion.
Of course you can use the code and change it as you want.
Posted: 15th Aug 2022 11:05
If you noticed, I draw buttons in the program, and then memorize them.
I used print because the text was not visible. had to be adjusted to fit the text. I use arrays because I have no idea how your methods work. Not taught in school. At the institute, I studied to be an engineer, not a programmer.

I will study your code, maybe I will learn something. Thanks for replying to my message.

P.S.
and what game sales can I dream of?
1) is disconnected from the unified payment system.
2) Linux is not supported?
Posted: 15th Aug 2022 16:11
On the code itself, to each their own. On the Menu...

- Revisit "Return". If it is a "Back" button, then it would go toward the bottom of the list or a corner of the screen. A "Return" button would seem confusing to some, especially when it is prioritized as the first button.
- Music and Sound options typically are in an Options menu or, since they are being used as toggles here, displayed as icons.
- If "Start" is "New Game" then it should say as such. If Start takes you to a place where a person can choose New or Load/Continue, then Load and Save should be moved to that menu.
- Since you will have the space, you might want to consider changing Start, Load, and Save to something like New Game, Load Game, and Save Game, or Start New Game, Continue Game, Save Game - the clearer the instructions, the better
- If your game has a trailer, tutorial, how to play section, etc then you might want to have a buttonf or that here, too.



MadBit, I really like the way you do your button code! Very structured, organized, and flexible. *swipes*
Posted: 17th Aug 2022 15:23
MadBit, I really like the way you do your button code! Very structured, organized, and flexible. *swipes*

Thank you

If you noticed, I draw buttons in the program, and then memorize them.

This is also what I do when no image is specified.
What you can also do with my example is to always use the same image for the background of the button.
You only need to pass the image ID from the first created button to the others.
+ Code Snippet
global main_menu as tUI_Button[BTN_MAINMENU_COUNT]
button as integer

main_menu[BTN_RETURN] = tUI_Button("Return",-1,128,32)
button = main_menu[BTN_RETURN].back

main_menu[BTN_START] = tUI_Button("Start",button,-1,-1)
main_menu[BTN_LOAD] = tUI_Button("Load",button,-1,-1)
main_menu[BTN_SAVE] = tUI_Button("Save",button,-1,-1)
main_menu[BTN_MUSIC] = tUI_Button("Music On",button,-1,-1)
main_menu[BTN_SOUND] = tUI_Button("Sound On",button,-1,-1)
main_menu[BTN_EXIT] = tUI_Button("Exit",button,-1,-1)
Posted: 18th Aug 2022 15:25
To be honest, I don't know how your code works. Therefore, I will do my own thing with sprites.
+ Code Snippet
// Project: interceptors 
// Created: 2022-08-11

// show all errors
SetErrorMode(2)
Global GlobalHeight
GlobalHeight=GetMaxDeviceHeight ()
Global GlobalWidth
GlobalWidth=GetMaxDeviceWidth ()
// set window properties
SetWindowTitle( "interceptors" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

SetWindowSize( GlobalWidth, GlobalHeight, 1 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
 
// set display properties
SetVirtualResolution( GlobalWidth, GlobalHeight ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts

shadowMode = 3 // start with cascade shadow mapping which gives the best quality
SetShadowMappingMode( shadowMode )
SetShadowSmoothing( 2 ) // random sampling
SetShadowMapSize( 1024, 1024 )
SetShadowRange( -1 ) // use the full camera range

 setcameraposition(1,0,0,500)
 SetCameraLookAt( 1, 0, 0, 0, 0 )
`--------------------------------------------------------------
rem place the button in the centre of the screen..
global x
global y
x=GlobalWidth/2
y=GlobalHeight/2
global cursor
cursor=loadsprite("cursor.png")
global music
global sound
sound=loadsound("main_menu/Ok.wav")
music=loadmusic("main_menu/Space01.mp3")
PlayMusic( music, 1 ) 
#include "button_code.agc"
#include "main_menu.agc"
load_button()
for t=1 to 7
	SetSpritePosition( button_up[t], x, y+(t-1)*32) 
	SetSpritePosition( button_down[t], x,y+(t-1)*32 )
	setspritevisible(button_down[t],0)
next t
	SetSpritePosition( button_up[8], x, y+(t-1-1-1-1)*32) 
	SetSpritePosition( button_down[8], x,y+(t-1-1-1-1)*32 )
	setspritevisible(button_down[8],0)
	setspritevisible(button_up[8],0)
	SetSpritePosition( button_up[9], x, y+(t-1-1-1)*32) 
	SetSpritePosition( button_down[9], x,y+(t-1-1-1)*32 )
	setspritevisible(button_down[9],0)
	setspritevisible(button_up[9],0)
global volume_music=100
global volume_sound=100	

global main_menu=1
global menu_save=0
global menu_load=0
global game=0
global start=0
global resume=0

_main_menu1:
do
	if main_menu=1 then main_main_menu()
	if menu_save=1 then main_save_menu()
	if menu_load=1 then main_load_menu()
	
	
	sync()
loop



+ Code Snippet
function main_main_menu()
	SetSpritePosition( cursor, getpointerx(),getpointery()) 
	
	rem ?????
	if getspritecollision(cursor,button_up[7]) and GetPointerPressed()=1  and GetSoundsPlaying( sound ) =0
	PlaySound( sound, volume_sound, 0 ) 	
	sleep(200)
	end
	endif
	
	rem ??????? ? ????
	if getspritecollision(cursor,button_up[1]) and GetPointerPressed()=1  and GetSoundsPlaying( sound ) =0
	PlaySound( sound, volume_sound, 0 ) 	
	sleep(200)
	game=1
	resume=1
	endif
	
	rem ????? ????
	if getspritecollision(cursor,button_up[2]) and GetPointerPressed()=1  and GetSoundsPlaying( sound ) =0
	PlaySound( sound, volume_sound, 0 ) 	
	sleep(200)
	game=1
	start=1
	endif
	
	rem ???????? ????
	if getspritecollision(cursor,button_up[3]) and GetPointerPressed()=1  and GetSoundsPlaying( sound ) =0
	PlaySound( sound, volume_sound, 0 ) 	
	sleep(200)
	main_menu=0
	menu_save=0
	menu_load=1
	for t=1 to 7
		 setspritevisible(button_down[t],0)
		 setspritevisible(button_up[t],0)
	next t
	for t=1 to 11
		 setspritevisible(button_load_down[t],0)
		 setspritevisible(button_load_up[t],1)
	next t
	endif
	
	rem ?????????? ????
	if getspritecollision(cursor,button_up[4]) and GetPointerPressed()=1  and GetSoundsPlaying( sound ) =0
	PlaySound( sound, volume_sound, 0 ) 	
	sleep(200)
	main_menu=0
	menu_save=1
	menu_load=0
	for t=1 to 7
		 setspritevisible(button_save_down[t],0)
		 setspritevisible(button_save_up[t],0)
	next t
	for t=1 to 11
		 setspritevisible(button_save_down[t],0)
		 setspritevisible(button_save_up[t],1)
	next t
	endif
	
	rem ????????? ?????????? ??????
	if getspritecollision(cursor,button_up[5]) and GetPointerPressed()=1  and GetSoundsPlaying( sound ) =0
		PlaySound( sound, volume_sound, 0 ) 
		if volume_music>0
			volume_music=0
			setspritevisible(button_up[5],0)
			setspritevisible(button_down[5],0)
			setspritevisible(button_down[8],1)
			setspritevisible(button_up[8],1)
			StopMusic() 
		else
			volume_music=100
			setspritevisible(button_up[5],1)
			setspritevisible(button_down[5],1)
			setspritevisible(button_down[8],0)
			setspritevisible(button_up[8],0)
			PlayMusic( music, 1 ) 
		endif
	endif
	
	rem ????????? ?????????? ?????
	if getspritecollision(cursor,button_up[6]) and GetPointerPressed()=1   and GetSoundsPlaying( sound ) =0
		PlaySound( sound, volume_sound, 0 ) 
		if volume_sound>0
			volume_sound=0
			setspritevisible(button_up[6],0)
			setspritevisible(button_down[6],0)
			setspritevisible(button_down[9],1)
			setspritevisible(button_up[9],1)
		else
			volume_sound=100
			setspritevisible(button_up[6],1)
			setspritevisible(button_down[6],1)
			setspritevisible(button_down[9],0)
			setspritevisible(button_up[9],0)
		endif
	endif
	

	for t=1 to 4
	if GetSpriteCollision( cursor, button_up[t] )=1
		 setspritevisible(button_down[t],1)
		 setspritevisible(button_up[t],0)
	else
		 setspritevisible(button_down[t],0)
		 setspritevisible(button_up[t],1)
	endif
	next t
	rem ?????? ????????
	if volume_music>0
	if GetSpriteCollision( cursor, button_up[5] )=1
		 setspritevisible(button_down[5],1)
		 setspritevisible(button_up[5],0)

	else
		 setspritevisible(button_down[5],0)
		 setspritevisible(button_up[5],1)
	endif
	endif
	rem
	
	if volume_music=0
	if GetSpriteCollision( cursor, button_up[8] )=1
		 setspritevisible(button_down[8],1)
		 setspritevisible(button_up[8],0)

	else
		 setspritevisible(button_down[8],0)
		 setspritevisible(button_up[8],1)
	endif
	endif
	rem ???? ???????
	if volume_sound>0
	if GetSpriteCollision( cursor, button_up[6] )=1
		 setspritevisible(button_down[6],1)
		 setspritevisible(button_up[6],0)
	else
		 setspritevisible(button_down[6],0)
		 setspritevisible(button_up[6],1)
	endif
	endif
	rem
	
	if volume_sound=0
	if GetSpriteCollision( cursor, button_up[9] )=1
		 setspritevisible(button_down[9],1)
		 setspritevisible(button_up[9],0)
	else
		 setspritevisible(button_down[9],0)
		 setspritevisible(button_up[9],1)
	endif
	endif
	rem ?????
	if GetSpriteCollision( cursor, button_up[7] )=1
		 setspritevisible(button_down[7],1)
		 setspritevisible(button_up[7],0)
	else
		 setspritevisible(button_down[7],0)
		 setspritevisible(button_up[7],1)
	endif
endfunction

function main_save_menu()
	SetSpritePosition( cursor, getpointerx(),getpointery())
	
	 rem ??????? ? ???? ????
	if getspritecollision(cursor,button_save_up[1]) and GetPointerPressed()=1  and GetSoundsPlaying( sound ) =0
	PlaySound( sound, volume_sound, 0 ) 	
	sleep(200)
	main_menu=1
	menu_save=0
	menu_load=0
	for t=1 to 7
		 setspritevisible(button_down[t],0)
		 setspritevisible(button_up[t],1)
	next t
	for t=1 to 11
		 setspritevisible(button_save_down[t],0)
		 setspritevisible(button_save_up[t],0)
	next t
	endif
	
	if main_menu=0 
	for t=1 to 11
	if GetSpriteCollision( cursor, button_save_up[t] )=1
		 setspritevisible(button_save_down[t],1)
		 setspritevisible(button_save_up[t],0)
	else
		 setspritevisible(button_save_down[t],0)
		 setspritevisible(button_save_up[t],1)
	endif
	next t
	endif
endfunction

function main_load_menu()
	SetSpritePosition( cursor, getpointerx(),getpointery())
	
	 rem ??????? ? ???? ????
	if getspritecollision(cursor,button_load_up[1]) and GetPointerPressed()=1  and GetSoundsPlaying( sound ) =0
	PlaySound( sound, volume_sound, 0 ) 	
	sleep(200)
	main_menu=1
	menu_save=0
	menu_load=0
	for t=1 to 7
		 setspritevisible(button_down[t],0)
		 setspritevisible(button_up[t],1)
	next t
	for t=1 to 11
		 setspritevisible(button_load_down[t],0)
		 setspritevisible(button_load_up[t],0)
	next t
	endif
	
	if main_menu=0 
	for t=1 to 11
	if GetSpriteCollision( cursor, button_load_up[t] )=1
		 setspritevisible(button_load_down[t],1)
		 setspritevisible(button_load_up[t],0)
	else
		 setspritevisible(button_load_down[t],0)
		 setspritevisible(button_load_up[t],1)
	endif
	next t
	endif
endfunction




+ Code Snippet
function load_button()
	rem ??????? ???? 
	dim name$[9]  as string = [ "","    Return", "    Start", "    Load" ,"    Save","    Music ON","    Sound ON","    Exit","    Music OFF","    Sound OFF"]
	dim button_up[9]
	dim button_down[9]
	for t=1 to 9
		creatbutton(0,0,196,22,2)
		SetPrintColor( 0, 200, 0 )
		SetPrintSize( 22 )
		print(name$[t])
		render()
		image=GetImage(0,0,196,22)
		button_up[t]=createsprite(image)
		sync()

	SetSpritePosition( button_up[t], 32+196+196, (t-1)*32) 


		creatbutton(0,0,196,22,1)
		SetPrintColor( 0, 200, 0 )
		SetPrintSize( 22 )
		print(name$[t])
		render()
		image=GetImage(0,0,196,22)
		button_down[t]=createsprite(image)
		sync()
		SetSpritePosition( button_down[t], 196,(t-1)*32 )
	next t

	rem ???????? ????
	dim name_load$[11]  as string = [ "","    Return", "    Load 1", "    Load 2" ,"    Load 3","    Load 4","    Load 5","    Load 6","    Load 7","    Load 8","    Load 9","    Load 10"]
	dim button_load_up[11]
	dim button_load_down[11]
	for t=1 to 11
		creatbutton(0,0,196,22,2)
		SetPrintColor( 0, 200, 0 )
		SetPrintSize( 22 )
		print(name_load$[t])
		render()
		image=GetImage(0,0,196,22)
		button_load_up[t]=createsprite(image)
		sync()

	SetSpritePosition( button_load_up[t], 32+196+196, (t-1)*32) 
	setspritevisible(button_load_up[t],0)


		creatbutton(0,0,196,22,1)
		SetPrintColor( 0, 200, 0 )
		SetPrintSize( 22 )
		print(name_load$[t])
		render()
		image=GetImage(0,0,196,22)
		button_load_down[t]=createsprite(image)
		sync()
		SetSpritePosition( button_load_down[t], 196,(t-1)*32 )
		setspritevisible(button_load_down[t],0)
		
		SetSpritePosition( button_load_up[t], x, y+(t-1)*32) 
	SetSpritePosition( button_load_down[t], x,y+(t-1)*32 )
		
	next t

rem ?????????? ????
	rem ???????? ????
	dim name_save$[11]  as string = [ "","    Return", "    Load 1", "    Load 2" ,"    Load 3","    Load 4","    Load 5","    Load 6","    Load 7","    Load 8","    Load 9","    Load 10"]
	dim button_save_up[11]
	dim button_save_down[11]
	for t=1 to 11
		creatbutton(0,0,196,22,2)
		SetPrintColor( 0, 200, 0 )
		SetPrintSize( 22 )
		print(name_save$[t])
		render()
		image=GetImage(0,0,196,22)
		button_save_up[t]=createsprite(image)
		sync()

	SetSpritePosition( button_save_up[t], 32+196+196, (t-1)*32) 
	setspritevisible(button_save_up[t],0)


		creatbutton(0,0,196,22,1)
		SetPrintColor( 0, 200, 0 )
		SetPrintSize( 22 )
		print(name_save$[t])
		render()
		image=GetImage(0,0,196,22)
		button_save_down[t]=createsprite(image)
		sync()
		SetSpritePosition( button_save_down[t], 196,(t-1)*32 )
		setspritevisible(button_save_down[t],0)
		
		SetSpritePosition( button_save_up[t], x, y+(t-1)*32) 
	SetSpritePosition( button_save_down[t], x,y+(t-1)*32 )
		
	next t


endfunction	
	

function creatbutton(x,y,width,height,tipe)

   rem set-up colour palette, for this program
   white=MakeColor(255,255,255) 
   black=0
   grey=MakeColor(192,192,192) 
   yellow=MakeColor(255,255,0) 
   darkgrey=MakeColor(104,100,128) 

   bc=width/2

   select tipe
      case 2
         rem draw preselected button
   `      ink black,black
  `       box x,y,(x+width),(y+height)
         DrawBox( x, y, x+width, y+height, 0, 0, 0, 0, 1 ) 

    ``     ink white,black
    `     box x+1,y+1,(x+width)-2,(y+height)-2
         DrawBox( x+1,y+1,(x+width)-2,(y+height)-2, white, white, white, white, 1 ) 

     `    ink black,black
     `    box x+2,(y)+2,(x+width)-1,(y+height)-1
         DrawBox( x+2,(y)+2,(x+width)-1,(y+height)-1, 0, 0, 0, 0, 1 ) 

    `     ink grey,black
     `    box x+2,(y+2),(x+width)-2,(y+height)-2
         DrawBox( x+2,(y+2),(x+width)-2,(y+height)-2, grey, grey, grey, grey, 1 ) 
         rem ink text colour to yellow,
         `ink yellow,grey
      endcase
      case 1
         rem draw standard button
 ``        ink black,black
 `        box x,y,(x+width)-1,(y+height)-1
         DrawBox( x,y,(x+width)-1,(y+height)-1, 0, 0, 0, 0, 1 ) 

   `      ink white,black
  `       box x+1,(y)+1,x+width,(y+height)
         DrawBox( x+1,(y)+1,x+width,(y+height), white, white, white, white, 1 ) 

   `      ink darkgrey,black
   `      box x+1,(y+1),(x+width)-1,(y+height)-1
         DrawBox( x+1,(y+1),(x+width)-1,(y+height)-1, darkgrey, darkgrey, darkgrey, darkgrey, 1 ) 
         rem ink text colour to yellow,
   `      ink yellow,darkgrey
      endcase
   endselect

endfunction

Posted: 18th Aug 2022 16:13
I think the best way to do a main menu for a game is to make the whole thing in keeping with the game you are creating, also one of the major thing to think about is to keep everything looking the same so the whole GUI system blends together seamlessly.
Posted: 19th Aug 2022 14:21
I found an error in compiling the code.
Out of the blue, an interesting error appeared.
please get acquainted.
the work program has stopped working correctly.
I give free access to the code and media.
The game I wrote vseravno would be free.





pay attention to screenshots.
Buttons are not displayed correctly.
why is that? everything was fine yesterday.
Posted: 20th Aug 2022 17:44
i was able to solve the problem. I had to draw buttons in advance and load ready-made buttons into the desired menu.
Posted: 21st Aug 2022 9:44
Here are some of my gui system showcases;











please notice that the gui controls are multi-lingual.

create a typedef and make an array with it.
use not single but let's say 8 sprites and 8 texts and 3 sounds for your any gui control, some of them will use only text, some of them use 3 sprites and 1 text e.t.c Oh I have guicontroltypes which uses nothing also like GuiControlType_HPadControl
some of them will be clickable, some of them have different text styles and text sizes etc

I have commands like createguicontrol() setguicontroltext hideguicontrol() guicontrolpressed() e.tc.

all these commands are checked in a function called rungui() which I call in every loop

I hope these examples will be usefull for you to make a better system than I've shown here.

P.S. Edit: Some of the Images are from my games which are pending to be released. And the images and texts in those pictures are all gui controls and most of them are clickable. Also notice that the numbers bigger than 2^31
Posted: 21st Aug 2022 13:45
I made separate loops for each menu level, and merged them into one. I call in a cycle functions. well, I'm dumb.
I do not understand your programs.
the screenshots are really cool.
Posted: 21st Aug 2022 22:54
You need bigger buttons, larger more readable text. Good idea to display the game title too.
Posted: 21st Aug 2022 23:12
Nice work Arch-Ok
Posted: 24th Aug 2022 12:32
Guys, what is the best way to do this:
1) to have in memory only parts of the gui and pictures of buttons and texts. and just apply them when I open the corresponding menu or option. Unload from memory when the option is not active.
2) or as each menu item have all texts and buttons. Once loaded and do not unload anything until the program is closed.



+ Code Snippet
// Project: main_menu_scifi 
// Created: 2022-08-21

// show all errors
SetErrorMode(2)

// set window properties
SetWindowTitle( "main_menu_scifi" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
x1=5
y1=9
image_down=loadimage("GUIFrame_Sci-Fi3_Button1.png")
image_up=loadimage("GUIFrame_Sci-Fi3_Button2.png")
dim text[y1-2]
dim button_up[y1-2]
dim button_down[y1-2]
text[1]=createtext("start")
text[2]=createtext("resume")
text[3]=createtext("load")
text[4]=createtext("save")
text[5]=createtext("music on")
text[6]=createtext("sound on")
text[7]=createtext("exit")
`sprite=loadsprite("elegant2 (4).png")
cursor=loadsprite("cursor.png")
dim gui[x1,y1]
for x=2 to x1-1
	for y=2 to y1-1
gui[x,y]=loadsprite("elegant2 (4).png")
setspriteposition(gui[x,y],(x-1)*63,(y-1)*63)
	next y
	next x
	for x=2 to x1-1
		gui[x,y1]=loadsprite("elegant2 (5).png")
		setspriteposition(gui[x,y1],(x-1)*63,(y1-1)*63)
		
		gui[x,1]=loadsprite("elegant2 (7).png")
		setspriteposition(gui[x,1],(x-1)*63,(1-1)*63)
	next x
	
	for y=2 to y1-1
		gui[1,y]=loadsprite("elegant2 (1).png")
		setspriteposition(gui[1,y],(1-1)*63,(y-1)*63)
		
		gui[x1,y]=loadsprite("elegant2 (3).png")
		setspriteposition(gui[x1,y],(x1-1)*63,(y-1)*63)
	next y
	
	gui[1,1]=loadsprite("elegant2 (9).png")
	setspriteposition(gui[1,1],(1-1)*63,(1-1)*63)
	
	gui[1,y1]=loadsprite("elegant2 (2).png")
	setspriteposition(gui[1,y1],(1-1)*63,(y1-1)*63)
	
	gui[x1,1]=loadsprite("elegant2 (8).png")
	setspriteposition(gui[x1,1],(x1-1)*63,(1-1)*63)
	
	gui[x1,y1]=loadsprite("elegant2 (6).png")
	setspriteposition(gui[x1,y1],(x1-1)*63,(y1-1)*63)
	
	for t=1 to 7
		drawtext(text[t])
		SetTextSize( text[t], 22 ) 
		SetTextPosition(text[t],63+20,t*63+10)	
		button_up[t]=createsprite(image_up)
		button_down[t]=createsprite(image_down)
		setspriteposition(button_up[t],63,t*63)
		setspriteposition(button_down[t],63,t*63)
		setspritevisible(button_down[t],0)
	next t
	
do
		SetSpritePosition( cursor, getpointerx(),getpointery()) 
		
		for t=1 to y1-2
	if GetSpriteCollision( cursor, button_up[t] )=1
		 setspritevisible(button_down[t],1)
		 setspritevisible(button_up[t],0)
	else
		 setspritevisible(button_down[t],0)
		 setspritevisible(button_up[t],1)
	endif
		next t
	sync()
loop
end
Posted: 24th Aug 2022 19:48
Here is a link to a similar question that provides various coder preferences basically based on the uses of the images and sprites.

https://forum.thegamecreators.com/thread/228546