Start Screen: how to select with keys or mouse
Blitz3D Forums/Blitz3D Programming/Start Screen: how to select with keys or mouse| 
 | ||
| how do you have use the arrow keys or the mouse to select the start, controls, and scores options when starting a game? | 
| 
 | ||
| One of the most annoying and boring parts of the game development process in my opinion is coding the front-end and user interface - unfortunately, there's no simple native Blitz3D solution. Essentially, you need to read and resolve all of the user input and its on-screen appearance. | 
| 
 | ||
| You have to code all that functionality yourself. That means using commands like keydown, keyhit, mousedown, mousehit along with either images or sprites for button images, and the mousex, mousey commands to check if the cursor is within the boundaries of the button images. There's a fair bit to do to get that to do it - but if you design it well you can reuse it elsewhere easily throughout the rest of your program. | 
| 
 | ||
| thanks _PJ_  you're a big help | 
| 
 | ||
| how would i apply my custom welcome screen to the the code you gave me? Const ESC_KEY=1 Const Q_KEY=16 ;launches the welcome functions welcome() ;creating welcome function Function welcome() Graphics 640,480 screen=LoadImage("textures/truewelcome.png") DrawImage screen,0,-75 While Not KeyDown(1) If KeyDown(16) Then Return Wend End Function | 
| 
 | ||
| Hi, first, you will need to decide if you want to use only the mouse, or arrow keys or maybe both on your start screen. If you want to use keys only, then imagine having a variable called menue This menue variable is starting with the default number 1. This would represent the start button. number 2 would be controls, and 3 would be score. now you will need to increase and decrease this menue variable with the arrow keys. The limits would be minimum 1, maximum 3. Pressing enter/return would take you to the variable's destination. here is an example following the above's description: in this example i have used simple text functions to display the menue. you can easily replace it to display boxes and even images. | 
| 
 | ||
| how would you make the text appear bigger? | 
| 
 | ||
| You would use the font commands, loadfont and setfont. Or alternatively you would use bitmap fonts, put them on a texture and use 2d-in-3d and scale them on the fly. | 
| 
 | ||
| Sorry for the late reply. Hadn't noticed there was more to this. Here's an updated version of the same code I posted above, but now including the Welcome Screen and also a custom loaded font so you can alter the size. 
Graphics3D 800,600,32
Const WELCOME_SCREEN_PATH$="textures/truewelcome.png"
Const FONT_NAME$="Arial"
Const FONT_SIZE=18
Const STATE_WELCOME=0
Const STATE_MENU_MAIN=1
Const STATE_MENU_OPTIONS=2
Const STATE_GAME_INITIALISE=3
Const STATE_GAME_RUNNING=4
Const STATE_GAME_OVER=5
Global MACHINE_STATE
Global MENU_HIGHLIGHTED=0
Const MENU_MAIN_SELECTIONS=2
Const MENU_OPTIONS_SELECTIONS=3
Const BUTTON_WIDTH=128
Const BUTTON_HEIGHT=48
Global MENU_BUTTONS[MENU_MAIN_SELECTIONS+MENU_OPTIONS_SELECTIONS]
Const BUTTON_MAIN_START=0
Const BUTTON_MAIN_OPTIONS=1
Const BUTTON_OPTIONS_BACK=2
Const BUTTON_OPTIONS_GRAPHICS=3
Const BUTTON_OPTIONS_SOUND=4
Const KEY_SCANCODE_UP=200
Const KEY_SCANCODE_DOWN=208
Const KEY_SCANCODE_SPACE=57
Const KEY_SCANCODE_Q=16
Global KEY_SELECTION_UP=KEY_SCANCODE_UP
Global KEY_SELECTION_DOWN=KEY_SCANCODE_DOWN
Global KEY_SELECTION_GO=KEY_SCANCODE_SPACE
Global IMG_WELCOME_SPLASH
Runtime
Function Initialise()
	;Load Assets here etc.
	
	IMG_WELCOME_SPLASH=LoadImage(WELCOME_SCREEN_PATH$)
	
	Local Font=LoadFont(FONT_NAME,FONT_SIZE)
	SetFont Font
	
	MENU_BUTTONS[BUTTON_MAIN_START]=CreateImage(BUTTON_WIDTH,BUTTON_HEIGHT)
	SetBuffer ImageBuffer(MENU_BUTTONS[BUTTON_MAIN_START])
	Text BUTTON_WIDTH Shr True ,BUTTON_HEIGHT Shr True,"START GAME",True,True
	
	MENU_BUTTONS[BUTTON_MAIN_OPTIONS]=CreateImage(BUTTON_WIDTH,BUTTON_HEIGHT)
	SetBuffer ImageBuffer(MENU_BUTTONS[BUTTON_MAIN_OPTIONS])
	Text BUTTON_WIDTH Shr True,BUTTON_HEIGHT Shr True,"OPTIONS",True,True
	
	
	
	
	
	MENU_BUTTONS[BUTTON_OPTIONS_BACK]=CreateImage(BUTTON_WIDTH,BUTTON_HEIGHT)
	SetBuffer ImageBuffer(MENU_BUTTONS[BUTTON_OPTIONS_BACK])
	Text BUTTON_WIDTH Shr True ,BUTTON_HEIGHT Shr True,"BACK",True,True
	
	MENU_BUTTONS[BUTTON_OPTIONS_GRAPHICS]=CreateImage(BUTTON_WIDTH,BUTTON_HEIGHT)
	SetBuffer ImageBuffer(MENU_BUTTONS[BUTTON_OPTIONS_GRAPHICS])
	Text BUTTON_WIDTH Shr True ,BUTTON_HEIGHT Shr True,"GRAPHICS",True,True
	
	MENU_BUTTONS[BUTTON_OPTIONS_SOUND]=CreateImage(BUTTON_WIDTH,BUTTON_HEIGHT)
	SetBuffer ImageBuffer(MENU_BUTTONS[BUTTON_OPTIONS_SOUND])
	Text BUTTON_WIDTH Shr True ,BUTTON_HEIGHT Shr True,"SOUND",True,True
	
	FreeFont Font
End Function
Function Runtime()
	Initialise
	SetBuffer BackBuffer()
	Main_Loop
	EndGraphics
	End 
End Function
Function Main_Loop()
	
	While (Not(KeyDown(1)))
		StartLoop 
		UpdateLoop
		EndLoop
	Wend
	
End Function
Function StartLoop()
	Cls
End Function
Function UpdateLoop()
	
	Select (MACHINE_STATE)
		Case STATE_WELCOME:
			WelcomeScreen
		Case STATE_MENU_MAIN,STATE_MENU_OPTIONS:
			Menu
		Case STATE_GAME_INITIALISE:
			RuntimeError("Game Has Begun...")
		Case  STATE_GAME_RUNNING:
		Case STATE_GAME_OVER:
	End Select
	
End Function
Function EndLoop()
	Render
End Function
Function Render()
	Flip
End Function
Function Menu()
	
	Local SelectIonStart
	Local SelectionEnd
	
	Select (MACHINE_STATE)
		Case STATE_MENU_MAIN:
			SelectIonStart=BUTTON_MAIN_START
			SelectionEnd=BUTTON_MAIN_OPTIONS
			
		Case STATE_MENU_OPTIONS:
			SelectIonStart=BUTTON_OPTIONS_BACK
			SelectionEnd=BUTTON_OPTIONS_SOUND
			
	End Select
	
	DrawMenuButtons(SelectIonStart,SelectionEnd)
	UpdateMouseSelection(SelectIonStart,SelectionEnd)
	UpdateKeyboardSelection(SelectIonStart,SelectionEnd)
	ShowSelectionRectangle(SelectIonStart,SelectionEnd)
End Function
Function MenuSelectEvent()
	;Responds to Menu Selection and changes Machine State
	Select (MENU_HIGHLIGHTED)
		Case BUTTON_MAIN_START:
			MACHINE_STATE=STATE_GAME_INITIALISE
			
		Case BUTTON_MAIN_OPTIONS:
			MACHINE_STATE=STATE_MENU_OPTIONS
			MENU_HIGHLIGHTED=BUTTON_OPTIONS_BACK
			
		Case BUTTON_OPTIONS_BACK:
			MACHINE_STATE=STATE_MENU_MAIN
			MENU_HIGHLIGHTED=BUTTON_MAIN_START
			
		Case BUTTON_OPTIONS_GRAPHICS:
			;... etc. Not completed here
			
		Case BUTTON_OPTIONS_SOUND:
			;... etc. Not completed here
	End Select
End Function
Function UpdateMouseSelection(SelectionStart,SelectionEnd)
	;Updates Selection based on MouseOver - Can be replaced with ImagesCollide() if using an Image for the pointer
	Local Iter
	
	Local X
	Local Y
	
	Local Count=SelectionEnd-SelectionStart
	
	For Iter=0 To Count
		X=GetXPosition(Iter,Count)		
		Y=GetYPosition(Iter,Count)
		
		If (GetMouseOver(X,Y,BUTTON_WIDTH,BUTTON_HEIGHT))
			DebugLog(Iter)
			MENU_HIGHLIGHTED=Iter+SelectionStart
			
			If (MouseHit(1))
				;Keep this here, so Mouseclick only calls event whilst mouseover
				MenuSelectEvent
			End If	
			
		End If
		
	Next
End Function	
Function UpdateKeyboardSelection(SelectIonStart,SelectionEnd)
	;Updates Selection based on Key Input
	
	Local SelectionChange=KeyHit(KEY_SELECTION_DOWN)-KeyHit(KEY_SELECTION_UP)
	
	If (SelectionChange)
		MENU_HIGHLIGHTED=MENU_HIGHLIGHTED+SelectionChange
		If (MENU_HIGHLIGHTED>SelectionEnd)
			MENU_HIGHLIGHTED=SelectIonStart
		End If
		If (MENU_HIGHLIGHTED<SelectIonStart)
			MENU_HIGHLIGHTED=SelectionEnd
		End If
	End If
	
	If (KeyHit(KEY_SELECTION_GO))
		MenuSelectEvent
	End If
	
End Function	
Function GetMouseOver(x,y,w,h)
	Local mx=MouseX()
	Local my=MouseY()
	Return  (  ((mx>x) And (mx<(x+w)))    And    ((my>y) And (my<(y+h)))  )
End Function
Function ShowSelectionRectangle(SelectionStart,SelectionEnd)
	Rect GetXPosition(SelectionStart,SelectionEnd),GetYPosition(MENU_HIGHLIGHTED-SelectionStart,SelectionEnd),BUTTON_WIDTH,BUTTON_HEIGHT,False
End Function
Function DrawMenuButtons(ButtonStart,ButtonEnd)
		;Draws the buttons from the library
	Local Count=ButtonEnd-ButtonStart
	
	Local Iter
	Local X
	Local Y
	For Iter= 0 To Count
		X=GetXPosition(Iter,Count)
		Y=GetYPosition(Iter,Count)
		DrawImage MENU_BUTTONS[Iter+ButtonStart],X,Y
	Next
End Function		
Function GetXPosition(Item,Count)
	;So the same function can be used for selection rectangle, mouse events and the actual button drawing
	Return (GraphicsWidth() Shr True) - (BUTTON_WIDTH Shr True)
End Function
Function GetYPosition(Item,Count)		
	;So the same function can be used for selection rectangle, mouse events and the actual button drawing
	Return  (BUTTON_HEIGHT*1.5)*(Item+1)
End Function
Function WelcomeScreen()
	DrawImage IMG_WELCOME_SPLASH,(GraphicsWidth() Shr True)-ImageWidth(IMG_WELCOME_SPLASH),(GraphicsHeight() Shr True)-ImageHeight(IMG_WELCOME_SPLASH)
	If ((KeyHit(KEY_SELECTION_GO)) Or MouseHit(1))
		MACHINE_STATE=STATE_MENU_MAIN
	End If
End Function
 | 
| 
 | ||
| I've decided to use this as my menu screen because it was simpler and now in just need to figure out ;how or where i would create a code to when i press start it would start the game instead of saying that i hit the start button? IF you want the code for our game then ask? menue=1 menuedelay=MilliSecs() a$="" SetBuffer BackBuffer() Graphics3D 640,480,16,2 ;Main menue loop starts here Repeat Gosub menukeys Gosub drawscreen If KeyDown(28) Or KeyDown(57) ;Enter or Space Select menue Case 1 Gosub START Case 2 Gosub CONTROLS Case 3 Gosub SCORE Case 4 Gosub OPTIONS End Select EndIf Flip Until KeyDown(1) ;Escape key exits the main menue loop End .start ;game start A$="Starting" Return .controls ;Setting up controls A$="Controls" Return .options ;geyying options A$="Options" Return .score ;Displaying score A$="Score" Return .drawscreen Cls Graphics3D 640,480 screen=LoadImage("textures/truewelcome.png") DrawImage screen,0,0 Const font_nameA$="ariel" Const font_size=20 Color $ff,$ff,$ff Text 0,0,"Last item choosen was: "+A$ ;If variable number Then Color red, Else Color white If menue=1 Then Color $ff,0,0 Else Color $ff,$ff,$ff Text 10,100,"Start" If menue=2 Then Color $ff,0,0 Else Color $ff,$ff,$ff Text 10,140,"Controls" If menue=3 Then Color $ff,0,0 Else Color $ff,$ff,$ff Text 10,180,"Score" If menue=4 Then Color $ff,0,0 Else Color $ff,$ff,$ff Text 10,220,"Options" Return .menukeys If MilliSecs()-menuedelay > 75 ;Delaying the keypress or else it would be too fast, switching between 1 and 3 menuedelay=MilliSecs() If KeyDown(200) Then menue=menue-1 ;KeyUp If KeyDown(208) Then menue=menue+1 ;KeyDown If menue<=1 Then menue=1 If menue=>4 Then menue=4 EndIf Return | 
| 
 | ||
| Hi, please put the code which you want to write here on forums, in code boxes. Before pasting the text, use Codebox shoud be written in lower case letters: [Codebox] paste your text here [/Codebox] Here is the above Code with some Improvements. You want to make sure, that Graphic command is Called only 1 time in your program. Setbuffer command is used, normaly, after Graphic. Loading Images shall be done after Graphic command is set. They will Remain in the memory, so you dont need to load them in a loop. Loading images and then executing the Graphic command will clear every loaded images. This will Crash your program, as soon as you try to draw the image. how or where i would create a code to when i press start it would start the game This is the code which do something after you hit enter: After hitting the Return button,the Gosub statement leads you to the labels. To start the game, you would then make a game loop inbetween .start and the Return : .start ;.start is an label, here does the "Gosub start" jumps into. ;game start A$="Starting" ;this is the text, which is displayed in my example.It is here,where your game starts. Return ;After the Game ends, Return jumps back to the line where Gosub start was called | 
| 
 | ||
| how would i have an image showing for the controls of my game when  i hit enter on the controls option and i can go back to the menu screen again? | 
| 
 | ||
| so any helpful tips? | 
| 
 | ||
| you want to display a picture, which is explaining which keys are used ? then youll have to load a picture into a variable, right after screen=LoadImage("textures/truewelcome.png") 
img_controls=LoadImage("images/controls.png")
at the end of the listing use (copy&paste) following function: 
Function CheckReturn()
 if keydown(28) or Keydown(57)      ;check if user has pressed the enter or return keys
   while keydown(28) or Keydown(57) ;Wait until user has released the keys
      delay 1
   Wend
   Return 1
 EndIf
 Return 0 
End Function
 |