I felt like making a quick tutorial for this as it's a very common question.
remstart
A beginners' tutorial on writing a basic menu program
By OBes... no wait, I am Libervurto now! xD
Date: 31/AUG/2013
This header is boring... ASCII art time!
__/\\\\\\\\\\\\\_______/\\\\\\\\\________/\\\\\\\\\\\____/\\\\\\\\\\\________/\\\\\\\\\_
_\/\\\/////////\\\___/\\\\\\\\\\\\\____/\\\/////////\\\_\/////\\\///______/\\\////////__
_\/\\\_______\/\\\__/\\\/////////\\\__\//\\\______\///______\/\\\_______/\\\/___________
_\/\\\\\\\\\\\\\\__\/\\\_______\/\\\___\////\\\_____________\/\\\______/\\\_____________
_\/\\\/////////\\\_\/\\\\\\\\\\\\\\\______\////\\\__________\/\\\_____\/\\\_____________
_\/\\\_______\/\\\_\/\\\/////////\\\_________\////\\\_______\/\\\_____\//\\\____________
_\/\\\_______\/\\\_\/\\\_______\/\\\__/\\\______\//\\\______\/\\\______\///\\\__________
_\/\\\\\\\\\\\\\/__\/\\\_______\/\\\_\///\\\\\\\\\\\/____/\\\\\\\\\\\____\////\\\\\\\\\_
_\/////////////____\///________\///____\///////////_____\///////////________\/////////__
__/\\\\____________/\\\\__/\\\\\\\\\\\\\\\__/\\\\\_____/\\\__/\\\________/\\\_
_\/\\\\\\________/\\\\\\_\/\\\///////////__\/\\\\\\___\/\\\_\/\\\_______\/\\\_
_\/\\\//\\\____/\\\//\\\_\/\\\_____________\/\\\/\\\__\/\\\_\/\\\_______\/\\\_
_\/\\\\///\\\/\\\/_\/\\\_\/\\\\\\\\\\\_____\/\\\//\\\_\/\\\_\/\\\_______\/\\\_
_\/\\\__\///\\\/___\/\\\_\/\\\///////______\/\\\\//\\\\/\\\_\/\\\_______\/\\\_
_\/\\\____\///_____\/\\\_\/\\\_____________\/\\\_\//\\\/\\\_\/\\\_______\/\\\_
_\/\\\_____________\/\\\_\/\\\_____________\/\\\__\//\\\\\\_\//\\\______/\\\__
_\/\\\_____________\/\\\_\/\\\\\\\\\\\\\\\_\/\\\___\//\\\\\__\///\\\\\\\\\/___
_\///______________\///__\///////////////__\///_____\/////_____\/////////_____
remend
`** Before we get into the loop, we have a couple of things to set up...
rem prepare the screen
set display mode 1360,768,32
sync on
sync rate 0
rem we're going to position the menu in the centre of the screen, so let's store the screen's central x coordinate now.
rem It's not going to change from herein, so it's best we store it to save the computer from making pointless calculations.
screenCentreX= screen width()/2
rem I'm going to store the colour value for white, for the same reason.
white= rgb(255,255,255)
rem load menu images
rem I'm just going to use text here, but since I'm storing the strings in an array
rem it will work in much the same way.
data "new game","load game","options","banana","exit"
`this next variable tells the program how many strings we are going to use
`remember we could use menu$(0), but since you want to use images and we can't have an image 0
`I will just start at 1 to make it simpler.
maxOpt= 5
dim menu$(maxOpt*2) :`we multiply maxOpt by 2 because we want two versions of each option: one unhighlighted and one highlighted.
rem now we read each of the strings from the data line into the array
for i= 1 to maxOpt
read menu$(i)
`let's store a capitalised version of each string to act as the HIGHLIGHTED version,
`let's also put some * around them to make them stand out more
`we'll offset the capitalised versions in the array so that they come after the lowercase versions.
menu$(i+maxOpt) = "**"+upper$(menu$(i))+"**"
next i
rem the last thing we need is a variable to keep track of what option is currently highlighted
menuCursor= 1
rem now we have everything set up we can begin the loop
rem === MAIN ===================================================
repeat
rem *=* INPUT SECTION *=*
rem store the input
up= silkey(upkey(),up)
down= silkey(downkey(),down)
enter= silkey(returnkey(),enter)
rem *=* PROCESS SECTION *=*
rem update the menu cursor
`we don't want the menu cursor to escape the menu, so we have to stop it going too far up or down.
`I've chosen to simply prevent it from going too high or low, but we could make it loop round to the other end if we liked.
if up =1 and menuCursor >1 then dec menuCursor
if down =1 and menuCursor <maxOpt then inc menuCursor
rem we're going to use the return key to select options. For now, EXIT is the only option that does anything.
if enter =1 and menuCursor =5 then requestExit= 1 else requestExit= 0
rem *=* OUTPUT SECTION *=*
rem display the menu
for i= 1 to maxOpt
rem if i=menuCursor, this means the option we are drawing is the one highlighted by the menuCursor.
if i =menuCursor
ink 65535,8 :`65535 is the value of cyan. 8 is not a special number, it's just a habit of mine to use it.
center text screenCentreX, 20+i*40, menu$(i+maxOpt)
else
ink white,8
center text screenCentreX, 20+i*40, menu$(i)
endif
next i
rem *=* DEBUGGING *=*
rem it's always useful to display hidden data for debugging purposes, that way we don't have to guess what's going on.
rem but it's also nice to have a way to deactivate it. I've made it so the debugging info only displays when CTRL is held.
rem I've put this part of the program into a subroutine. Subroutines are like bookmarks that you can use to organise your code
rem and tidy up the main loop, making it easier to read; provided you split up your code into logical chunks and give them
rem logical names. this gosub statement calls the subroutine called "debug", scroll down the page a little and you'll find
rem the debug subroutine and the code it contains. We could divide the whole program into subroutines, but since it's so short
rem there isn't much need.
gosub debug
rem don't forget to sync the output and clear the screen for the next loop!
sync
cls
until requestExit =1
rem leave a goodbye message
print "Goodbye..."
sync
wait 2000
rem it's important we manually end the program if we are using functions (which we are)
rem if the program is allowed to run into a function it wont know what to do and will crash.
rem running into subroutines isn't as disasterous but still, we don't want that code executing
rem after the program was supposed to end!
end
`//
debug:
if controlkey()
ink white,8
print "-- CONSTANTS --"
print "screenCentreX = "; screenCentreX
print "white = ";white
print "maxOpt = ";maxOpt
print "-- VARIABLES --"
print "FPS = ";screen fps()
print "menuCursor = ";menuCursor
print "menu$(menuCursor) = ";menu$(menuCursor)
print "<up> = ";up
print "<down> = "; down
print "<ret> = "; enter
endif
return
`//
rem don't worry about how the silkey function works.
rem all you need to know is the return values: 0=idle; 1=pressed; 2=released; 3=held
function silkey(trigger,oldstate)
newstate = 3&&(oldstate<<1||trigger)
endfunction newstate
Formerly OBese87.