Ravancloak's Slice Menu Tutorial

Make games! Discuss those games here.

Moderators: Bob the Hamster, marionline, SDHawk

Post Reply
User avatar
Ravancloak
Red Slime
Posts: 51
Joined: Wed Jul 31, 2019 1:49 am
Location: Venus
Contact:

Ravancloak's Slice Menu Tutorial

Post by Ravancloak »

Alright folks, this guide is for anyone who is interested in learning how to make slice menus. I'm sure this has been covered before, but maybe this'll give a viewpoint that's a bit more helpful. There's many kinds of menus in this world, I'll first cover one similar to the default ohr menus. I'll describe my process in making a slice menu in the editor, as well as my process in writing the script. Note: I won't be covering mouse support, that's a bit more complicated and changes how you set up the slice collection.


THOSE FUN BUILDING BOCKS:

:D Basics of the scripting:
First things first, a menu is simply an a variable with graphical representation. You'll have that variable increment or decrement based on directional keypresses, and if statements that will preform different actions depending on the variable. With lower level coding you'll have an index of menu items, a variable that holds the selected menu item, and if statements; but in OHR we can simply use slices, a slice extra, and if statements.


:D Basics of Slices:
BMR has a wonderful guide on how slices work, check it out at viewtopic.php?p=108906&hilit=BMR%27s+slice#p108906. I won't bother with these basics, I'll just describe the slices we'll be using, and a bit about the slice collection editor in Custom. If the terms etc. below doesn't make sense, please look at BMR's guide.


:D About Slices:
  • Container Slices: Invisible slices mainly used to hold other slices. There is one of these as the root of slice collections - you won't need to bother with making one in this guide.
  • Rectangle Slices: Rectangles that can optionally use the box styles in the editor. Think of these as the back text boxes and menus.
  • Grid Slices: These are invisible slices that are used to neatly organize children. Used here so you don't have to manually position children.
  • Scroll Slices: These are interesting invisible slices that are used to offset children. Think of the scroll bar in menus that have more items than will fit.
  • Text Slices: Pretty self explanatory, these are slices that are text. They can be changed using strings (i.e. $0="text").
  • Sprite Slices: these are the all the images that are loading/drawn in the "Edit Graphics" portion of the editor. Think backdrop sprites, walkabout sprites, enemy sprites, etc.

:D About Slice Collections:
  • Slice Collection: these are for setting up slices in Custom without having to get too dirty with scripting. Very very helpful for when you're starting out with slices.
  • Lookup Code: A handle used by scripts to easily find a slice.
  • Dimensions: X and Y are the position on the screen, based on Alignment. Width and Height are the size of the slice. Note that you can't change the width and height of text slices, these are based on the text.
  • Visibility: Visible hides the slice. Clip children will clip the slice's children if they are outside the dimensions of the slice.
  • Alignment: Aligns are what edge of the slice's parent that the slice is aligned to. Anchors are what edge of the slice matches up with the Align edge.
  • Padding: This will change offset the edge of the slice when aligning it's children. More on this later when it's in action.
  • Extra Data: Three variables that are attached to slices. This is where I store the selected slice child; as it's easy to access.

MAKERING THAT MENU!!:

:D Setting Up Slice Collection:
This part will all be done in Edit Slice Collections. Press F1 to view the controls as needed. We'll be making a slice collection made up of a Rectangle, Scroll, Grid, and Text slices.

:D Add a Rectangle Slice. Edit the slice, and enter Lookup Code Go to the first empty User Defined code, and type in "menu" (we will use this lookup to find the menu in our scripts. Expand Dimensions, then set the width to 220 and the height to 150 (adjust as needed, I'll be making a menu that will have 2 columns of menu items). Expand Rectangle Settings and set the style to whichever box style you want. You can play with transparency if you want a transparent menu. Go to alignment and set all of them to center - this will make the menu appear in the middle of the screen. You can play with this and put the menu wherever you want. Go to Padding and set all of them to be 10. This can be played with later to move the children around. Go back to the slice collection.

It should look like this:
test0002.png
test0002.png (2.35 KiB) Viewed 879 times
:D Add a Scroll slice and move the Scroll below the Rectangle slice using shift arrow keys, then press shift + right to parent it to the Rectangle. Enter Dimensions, and set it to fill the parent.

:D Go back to the slice collection, and add a Grid slice. Parent the Grid to the Scroll. Set the lookup of the Grid slice to be "grid". Center the grid, this time setting the Fill Type to Horizontal, then set the Height to be 12 (this can also be adjusted later). Go to Grid Settings, and set the Columns to 2.

Your slice collection should now look like this:
test0003.png
test0003.png (2.48 KiB) Viewed 879 times
:D Add a text slice, and center it. Change text color (I used menu item, you'll have to change the script if you use anything else) and add an outline if desired. Copy paste that slice, then change the text under text settings to whatever your menu items are called.

Slice collection should now look something like this:
test0004.png
test0004.png (3.12 KiB) Viewed 879 times
SCRIPTED FUN:
:D I'll demonstrate how to load in the slice collection you've made, then free it. for reference, look up commands using Ctrl+F at this page: https://hamsterrepublic.com/ohrrpgce/do ... onary.html.

:D First thing we wanna do is load up the slice collection we've made. We'll suspend player so they can't move, then we'll load in the slice collection we made using "load slice collection (id)". We'll have it wait for a keypress, then we'll free the slice collection. We can use the lookup code we defined in the slice editor, but that won't delete the root of the collection. To do that, we'll get the parent of the slice "menu", then free the parent. (note that this can be avoided by showing the slice root, then giving that a lookup, but I can't be bothered to change the earlier stuff). So there you have it, we'll load in the slice collection, then free it.

:D You'll want to have this script called by something like a built-in menu, npc, or to your on-keypress script.

Code: Select all

plotscript, slice menu, begin
	variable (sli, sel, items, exit)
	#a variable that will hold slice handles, and one to store the slice extra for easy reference.
	#note that getting slice extra isn't needed at all, I just wanted to demonstrate how to do so
	#menuitems is used as a constant here for the number of menu items.
	#exit will close the menu if set to be true.
	
	#make sure the player can't move while menu is up
	suspend player

	#loads the menu slice collection you just made. Change the 0 to whatever slice collection you used.
	load slice collection (0)

	#wait for the any key here, then move on to free the slice.
	wait for key (any key)

	#free the slice collection here by getting the parent of the menu slice
	free slice (slice parent(lookup slice(sli:menu)))
	
	#add a wait so keypresses won't get mixed up when this closes
	wait
	#player can move again
	resume player
end
Here is that menu opening and closing in action!
test0000.gif
test0000.gif (52.2 KiB) Viewed 879 times
:D Now that we know how to load and free a slice collection, we'll get into the gritty part. We don't need the "wait for key" for the next part, so go ahead and delete that line. Instead of that, we will have a while loop that will wait for a keypress, then execute different actions depending on which keypress is pressed - meaning this is where the player can control the menu. Here, we'll just add in the ability to close the menu.

Code: Select all

plotscript, slice menu, begin
	variable (sli, sel, items, exit)
	#a variable that will hold slice handles, and one to store the slice extra for easy reference.
	#note that getting slice extra isn't needed at all, I just wanted to demonstrate how to do so
	#menuitems is used as a constant here for the number of menu items.
	#exit will close the menu if set to be true.
	
	#make sure the player can't move while menu is up
	suspend player

	#loads the menu slice collection you just made. Change the 0 to whatever slice collection you used.
	load slice collection (0)

	#this while loop will continually run until broken
	while (true) do (

		#stops the "while" loop until a key is pressed 
		wait for key (any key)

		#this else if block will do different things depending on which key is pressed.
		#we will add the other ones later, for now we'll just exit this while loop if 
		#the cancel/menu key is pressed.
		if (keypress (cancel key)) then (
			exit := true

		#use/up/down will come into play later
		) else if (keypress (use key)) then (
			
		) else if (keypress (up key)) then (
			
		) else if (keypress (down key)) then (
			
		)
		wait
		if (exit) then (break)	
	)

	#free the slice collection here by getting the parent of the menu slice
	free slice (slice parent(lookup slice(sli:menu)))

	#add a wait so keypresses won't get mixed up when this closes
	wait
	#player can move again
	resume player
end
:D Next we will make sure that we can increment and decrement the selected menu item using "show value". First we'll set "sel" to be the slice extra of the menu slice, and show that value. Then we'll add the functions of the up and down keys. We'll have sel increase by one if it's less than total menu items, and decrease by one if it is more than 0.

Code: Select all

plotscript, slice menu, begin
	variable (sli, sel, items, exit)
	#a variable that will hold slice handles, and one to store the slice extra for easy reference.
	#note that getting slice extra isn't needed at all, I just wanted to demonstrate how to do so
	#menuitems is used as a constant here for the number of menu items.
	#exit will close the menu if set to be true.

	#make sure the player can't move while menu is up
	suspend player

	#loads the menu slice collection you just made. Change the 0 to whatever slice collection you used.
	load slice collection (0)

	#gets the child count of the grid slice we set up earlier
	items := child count (lookup slice (sli:grid)) -- 1
	
	#this while loop will continually run until broken
	while (true) do (

		#get the slice extra of the menu slice, and store it in the "sel" variable
		sel := get slice extra (lookup slice (sli:menu), 0)

		#debug value to show what menu item is selected. comment out when script is done and works.
		show value (sel)

		#stops the "while" loop until a key is pressed 
		wait for key (any key)

		#this else if block will do different things depending on which key is pressed.
		#we will add the other ones later, for now we'll just exit this while loop if 
		#the cancel/menu key is pressed.
		if (keypress (cancel key)) then (
			exit := true

		#use will come into play later
		) else if (keypress (use key)) then (
			
		) else if (keypress (up key)) then (
			#if sel is greater than 0, then decrement sel
			if (sel > 0) then (
				#decrement the selected menu item
				sel -= 1
			)
		) else if (keypress (down key)) then (
			#if sel is less than total menu items, then increment sel
			if (sel < items) then (
				#increment the selected menu item
				sel += 1
			)
		)

		#sets the extra to be the same as the "sel" variable
		set slice extra (lookup slice (sli:menu), 0, sel)

		wait
		if (exit) then (break)	
	)

	#free the slice collection here by getting the parent of the menu slice
	free slice (slice parent(lookup slice(sli:menu)))

	#hide the debug value. comment out when script is done and works.
	show no value ()

	#add a wait so keypresses won't get mixed up when this closes
	wait
	#player can move again
	resume player
end
You should now see a number on the bottom corner that increases and decreases when you press up and down.
test0005.gif
test0005.gif (85.83 KiB) Viewed 879 times
:D Now for visuals for the player, and menu functions! We'll first get the selected text slice, and to do that, we'll use "slice child (lookupslice(sli:grid), sel)". Once we have that, we can change the color of that slice, or give it a background, or anything else you wanna do with it. We'll just change the color here. We'll do that 3 times, first we'll set the color of child 0 of Grid to be selected item. We'll then set the previous selected slice child to be the menu item color, and set it to be selected item after increasing or decreasing the value of sel. In short, we will set the color when the menu is loaded, then set the new one after every keypress. Once we have the color changing magic in, we'll have the scroll slice scroll to the selected menu item using "scroll to slice".

:D Finally, we'll add the use key functionality. To do that, we'll simply have a switch statement, with a case for every menu item. For example, you could have menu item 0 play one song, then have menu item 1 play another, and so forth. Or you could run different scripts from the menu items. Once that's done, all you need to do is make sure you comment out the show value once you get it working.

Code: Select all

plotscript, slice menu, begin
	variable (sli, sel, items, exit)
	#a variable that will hold slice handles, and one to store the slice extra for easy reference.
	#note that getting slice extra isn't needed at all, I just wanted to demonstrate how to do so
	#menuitems is used as a constant here for the number of menu items.
	#exit will close the menu if set to be true.

	#make sure the player can't move while menu is up
	suspend player

	#loads the menu slice collection you just made. Change the 0 to whatever slice collection you used.
	load slice collection (0)

	#gets the child count of the grid slice we set up earlier
	items := child count (lookup slice (sli:grid)) -- 1

	#highlight the first child to start out.
	sli := slice child (lookupslice(sli:grid), sel)
	set text color (sli, ui:selected item)

	#this while loop will continually run until broken
	while (true) do (

		#get the slice extra of the menu slice, and store it in the "sel" variable
		sel := get slice extra (lookup slice (sli:menu), 0)

		#debug value to show what menu item is selected. comment out when script is done and works.
		#show value (sel)

		#stops the "while" loop until a key is pressed 
		wait for key (any key)

		#set the former selected text to be the color of a normal menu item
		sli := slice child (lookupslice(sli:grid), sel)
		set text color (sli, ui:menu item)

		#this else if block will do different things depending on which key is pressed.
		#we will add the other ones later, for now we'll just exit this while loop if 
		#the cancel/menu key is pressed.
		if (keypress (cancel key)) then (
			exit := true
		) else if (keypress (use key)) then (
			switch (sel) do (
				case (0) do (
					#insert whatever you want done by the menu item in the ()s
					#you can add a break after to close the menu.
					#for example, the first menu item will do this:

					play song(0)	#(assuming you have a song loaded in)
				)
				case (1) do ( 
					#for example, the second menu item will do this:
					play song(1)	#(assuming you have a song loaded in)
					exit := true	#and close the menu.
				)
				case (2) do (
					#thing
				)
				case (3) do (
					#thing
				)
				case (4) do (
					#thing
				)
				case (5) do (
					#thing
				)
				#etc
			)
		) else if (keypress (up key)) then (
			#if sel is greater than 0, then decrement sel
			if (sel > 0) then (
				#decrement the selected menu item
				sel -= 1
			)
		) else if (keypress (down key)) then (
			#if sel is less than total menu items, then increment sel
			if (sel < items) then (
				#increment the selected menu item
				sel += 1
			)
		)

		#get the selected slice child here, so we can change the color/scroll to it
		sli := slice child (lookupslice(sli:grid), sel)

		#this will scroll the scroll slice to the selected menu item
		scroll to slice (first child(lookup slice(sli:menu)), sli)

		#making the selected text flash is out of the scope of this tutorial, so
		#we'll just make it be the selected color.
		set text color (sli, ui:selected item)

		#sets the extra to be the same as the "sel" variable
		set slice extra (lookup slice (sli:menu), 0, sel)

		wait
		if (exit) then (break)	
	)

	#free the slice collection here by getting the parent of the menu slice
	free slice (slice parent(lookup slice(sli:menu)))

	#hide the debug value. comment out when script is done and works.
	#show no value ()

	#add a wait so keypresses won't get mixed up when this closes
	wait
	#player can move again
	resume player
end
Your finished menu will look like this:
test0008.gif
test0008.gif (81.62 KiB) Viewed 879 times
:D So yay, you've learned how to copy paste stuff and set up a slice collection with directions! Now it's time for you to make your own menu. The basics are all you need, then you can do any kind of menu you can dream up. First you need to have a variable, then a way for the player to change the variable. Once they can change it, you'll want to add the functionality - I use switches that do different things depending on what the variable is. Then you can add in visuals - you can put things together in the slice editor, or you can script your own slice stuff. Finally, once you have visuals, you'll want to give the player feedback on what the variable is, and what it does.

Enjoy ~


additional helpful tutorial: https://rpg.hamsterrepublic.com/ohrrpgc ... r_Tutorial
Have a flower! ^-^~* (she/her)
User avatar
charbile
Metal Slime
Posts: 601
Joined: Tue Jun 21, 2011 6:18 am

Re: Ravancloak's Slice Menu Tutorial

Post by charbile »

This would be great for the wiki too
Post Reply