Menus

Blitz3D Forums/Blitz3D Beginners Area/Menus

Happy Llama(Posted 2012) [#1]
I am trying to create a menu with a start button, a controls button, and an exit button. I have gotten the start and exit buttons working fine but the controls isn't working. I want it so that when you press controls it displays an image with a image of a button that you can click to return to the main menu. How can you do this?




Midimaster(Posted 2012) [#2]
You should work with flags to control, which screen you display. You already "touched" this, by working with a start% flag. So now expand this idea.

Try to work with only one FLIP command in your program. Use the REAPEAT/UNTIL as a main loop and jump from here into various display modes.

only symbolic code, i did not test it:
Graphics 800,600

Global DisplayMode% ; flag for the current Display
Global Paused% ;flag for pause mode

Const MENU=0, START=2, CONTROL=3, QUIT=4 
Const PAUSE_KEY=25 ; key P for pause

Global startmenu=LoadImage("start.png")
Global startbutton=LoadImage("startbutton.png")
MaskImage startbutton,0,0,0
Global exitbutton=LoadImage("exitbutton.png")
MaskImage exitbutton,0,0,0
Global controlsbutton=LoadImage("controlsbutton.png")
MaskImage controlsbutton,0,0,0
Global returnbutton=LoadImage("returnbutton.png")
MaskImage returnbutton,0,0,0
Global controls=LoadImage("controls.png") 
Global pause=LoadImage("pause.png")



Repeat
	Cls
	Select DisplayMode
		Case MENU
			ShowMenu		
		Case START 
			ShowMain
		Case CONTROL
			ShowControl
		Case QUIT
	End Select	
	Flip 1
Until DisplayMode=QUIT
End




Function ShowMenu()
	; Show Menu-background picture
		DrawImage startmenu,0,0
	
	; Show various foreground elements
		DrawImage startbutton,300,150
		DrawImage exitbutton,300,400
		DrawImage controlsbutton,300,275
	
	; check Mouse and Keys
		If RectsOverlap( MouseX(),MouseY(),1,1,300,150,ImageWidth(startbutton),ImageHeight(startbutton)) Then
			DebugLog"start"
			DisplayMode=START

		ElseIf RectsOverlap( MouseX(),MouseY(),1,1,300,275,ImageWidth(controlsbutton),ImageHeight(controlsbutton)) Then
			DebugLog"controlls"
			DisplayMode=CONTROL

		ElseIf RectsOverlap( MouseX(),MouseY(),1,1,300,300,ImageWidth(exitbutton),ImageHeight(exitbutton)) Then
			DebugLog"exit"
			DisplayMode=QUIT

		EndIf
		
End Function





Function ShowControl()
	; Show Control background picture
		DrawImage controls,0,0
	
	; Show various Foreground elements
		DrawImage startbutton,300,150
		DrawImage returnbutton,600,500
	
	; check Mouse and Keys
		If RectsOverlap( MouseX(),MouseY(),1,1,300,150,ImageWidth(startbutton),ImageHeight(startbutton)) Then
			DebugLog"start"
			DisplayMode=START

		ElseIf RectsOverlap( MouseX(),MouseY(),1,1,600,500,ImageWidth(returnbutton),ImageHeight(returnbutton)) Then
			DebugLog "return"	
			DisplayMode=MENU
		EndIf
		
		; do all the control stuff here
			; adjust sound volume, etc...
End Function





Function ShowMain()
	; Show Main background picture
		;DrawImage game,0,0
	
	; Show various Foreground elements
		DrawImage controlsbutton,300,275
		DrawImage returnbutton,600,500
	
	; check Mouse and Keys
		If RectsOverlap( MouseX(),MouseY(),1,1,300,275,ImageWidth(controlsbutton),ImageHeight(controlsbutton)) Then
			DebugLog"controlls"
			DisplayMode=CONTROL

		ElseIf RectsOverlap( MouseX(),MouseY(),1,1,600,500,ImageWidth(returnbutton),ImageHeight(returnbutton)) Then
			DebugLog "return"	
			DisplayMode=MENU
		EndIf


		If Paused=0	
				; do all the game stuff here
				; move playere etc...	
		
		Else
			DrawImage pause,300,300
		
		EndIf
		If KeyHit(PAUSE_KEY)
				Paused=1-Paused
		EndIf
End Function



Happy Llama(Posted 2012) [#3]
I'm a little confused with the ShowMain()function. This is for pausing right? and also what's that image that your drawing at the beginning called "game". If you could explain this that would be awesome!

Last edited 2012


Midimaster(Posted 2012) [#4]
oh, this was only an example. Don't be confused about the image names they are only placeholder for your real images (which i do not know). I added the function ShowMain() as a placeholder for the main game loop. Yes I added it to show you, how a PAUSE feature could be integrated.

Target of my code:
You should recognize the system of functions, that is behind this sample. In your code you tried to build one long REPEAT/UNTIL loop, which should contain all situations of the pre-game. This is not very helful.

The better way is to build one short REPEAT/UNTIL loop, which spreads into the different game situations. They game situations moved into functions. Not only MENU and CONTROL, but also the game intself. So the code for a MENU is not "before" the game. It is in the same loop!

Let us have a look like this: MENU or CONTROLS are different "displays" of the same game, the pictures are different, the possibilities are different, but what happens?: users enter mouse and/or keys to tell something to the code (like in the game itself...). So why not build the MENU like a "first display" of the game?

This way has two important advantages:

1.You can (but need not) jump from every display to each other only by changing the Value DisplayMode%

2.The code of the displays is clearly separated in different functions. At the beginning of each function you will define the buttons, that allow to jump into other displays.


One thing you should know about this code model: all pictures and all files you need in this code model have to be GLOBAL, because the game itself has moved into a function, where it only can reach the pictures, if they have been defined GLOBAL. So add a GLOBAL in front of all resources.




Paused

Paused should not be a standalone display. Paused should be a flag, that stopps the game level. The only thing the code has to do, when Paused is activ: show the game level, but without any movements and without the possibilities for the user to enter anything except the CONTINUE feature.


Ross C(Posted 2012) [#5]
You should think about using a type collection for your buttons also. It reduced the amount of global variables you need to use, and lets you use loops to draw them, and give the buttons more properties without having to create long variable names. Additionally, you can tag these buttons with a page number, so certain buttons are only displayed, checked for, depending on what page you are on.




Happy Llama(Posted 2012) [#6]
So would I put my main loop code here?

If Paused=0
; do all the game stuff here
; move playere etc...

Else


Midimaster(Posted 2012) [#7]
yes, but without any loop commands like REPEAT/UNTIL or WHILE/WEND...

because this will already be done by the first main loop.

I have here a running sample, which demonstrate the switching between the screens.

nice effects:

1. QUIT does not quit, but asks again.

2. In CONTROL the ESC key jumps back to MENU or to GAME, depending where you did come from.

3. You can jump from GAME to CONTROL and back to GAME. Values can be changed during running game (ball color, wall distance)

4. with wall distance you can see a feature, which can only be adjusted, when calling CONTROL from GAME . Calling CONTROL from MENU will always reset this value to default, when start the GAME

5. common elements like the "current Display" text can be put into the main loop instead in each display function




so you see, everything is possible in a model like this...

Last edited 2012

Last edited 2012