Feeks naming menu

From Spheriki

Jump to: navigation, search


This naming menu tutorial is a simple re-write of my previous tutorial. This one is better and more straightforward. Hopefully you'll learn something from this one. The end result will be a "game" that should play in any resolution. The skill level required should be beginner to intermediate users. Beginners will look at how to apply basic programming skills to a custom menu while intermediate users may use this as a basis to construct further custom menus. I expect intermediate users to know JS's String object as well as the Sphere functions involved. I expect beginners to expand their knowledge of these previously unknown functions inside Sphere, they may not know how everything works coming into this, but hopefully will gain an understanding on the completion of the tutorial.

Contents

Step 1

First we need to create our own "font" with the use of an existing font. My previous tutorial had this be done with a string. This is not good for fonts that do not have a fixed width. Those are fonts that have the same width throughout. Therefore, we are going to need to use an array of characters. Then we will separately center each letter by coming up with our own fixed width.

// Naming Tutorial.js //
var MyFont = ["A", "B", "C", "D", "E", "F",
             "G", "H", "I", "J", "K", "L",
             "M", "N", "O", "P", "Q", "R",
             "S", "T", "U", "V", "W", "X",
             "Y", "Z", "?", "!", ".", " "];

We do not need to create a lower case for this font, we already have a method for doing this: String.toLowerCase();

Step 2

Now, we need to create a function that will display the menu, with an arrow, and of course, the letters. First we will need to create more global variables. These variables will hold our font and windowstyle, as well as values for the screen width and height.

// Naming Tutorial.js //
var windowstyle = GetSystemWindowStyle();
var font        = GetSystemFont();
var black       = CreateColor(0, 0, 0);
const SW        = GetScreenWidth();
const SH        = GetScreenHeight();

Note: 'const' is used to declare a data-type that cannot be written over. Basically, that variable is 'const'antly the same throughout the entire program.

Now we write a basic function that displays the contents in the center of the screen. But! How do we know how big to create it? We can't just throw down some numbers and expect results (I'm looking at you, beginners). First we need our own fixed width. Depending on the size of the font you use, this number may change. Since we are using the system font, I'm going to go with '8' as a nice even and safe number to use.

Now we visualize the container. We have in total, 30 characters. Should we do 10 across 3 down? No... That's too thin. What about 6 across and 5 down? That's perfect! Because we have a longer horizontal direction than a vertical direction, we can afford adding more characters across the screen.

Also, we would want to space the characters apart with an extra 8 pixels. This leaves us with 16x16 squares to work with.

// Naming Tutorial.js //
function DrawNamingMenu(name)
{
  windowstyle.drawWindow(SW/2-48, SH/2-40, 96, 80); // the letter box //
  windowstyle.drawWindow(SW/2-48, SH/2-72, 96, 16); // the  name  box //
  windowstyle.drawWindow(SW/2-48, SH/2+56, 96, 16); // the choice box //
 
  font.drawText(SW/2-48, SH/2-72, "Name: " + name);
  font.drawText(SW/2-40, SH/2+58, "Case");
  font.drawText(SW/2+8, SH/2+58, "Done");
}

And that is it, for the windows at least. The name parameter will be used later to output the currently typed in name.

Step 3

Now we will draw the code to draw and handle the selector to select certain letters in the menu.

To do this we will create a new function with a while loop, that will draw stuff by using the DrawNamingMenu() function we defined earlier. To draw every individual character, we will use two for-loops. One will draw the stuff going across, the other for the stuff going down. Beginners, take note of this.

function ShowNamingMenu()
{
  var name = ""; // we will keep this empty.
  var cx = 0;
  var cy = 0;
  var lettercase = 0;
  while(true)
  {
    DrawNamingMenu(name);
 
    // Our selector: //
    OutlinedRectangle(SW/2-48 + cx*16, SH/2-40 + cy*16, 8, 12, black);
 
    // The letters: //
    for (var y = 0; y < 5; ++y)
    {
      for (var x = 0; x < 6; ++x)
      {
        // if conditional justifies if whether ot not the font is upper or lower case.
        if (lettercase == 0)
          font.drawText(SW/2-48 + x*16, SH/2-40 + y*16, MyFont[x+y*6]);
        else
          font.drawText(SW/2-48 + x*16, SH/2-40 + y*16, MyFont[x+y*6].toLowerCase());
      }
    }
 
    FlipScreen();
  }
}

By this time if you call the function ShowNamingMenu() You will see the letters, rectangle and windowstyles.

This is pretty much how it's going to look. The next step is to add keyboard support.

Step 4

In this step we make it work. This entire function at the end must return a single value. Your name. In going about doing this, we will add key support and a multitude of checks to make certain we get letters into a name and return that name as a whole.

After the FlipScreen we add keyboard support:

while(AreKeysLeft())
    {
      switch(GetKey())
      {
        // These will control the rectangle and do commands.
        case KEY_UP:
          // if cy != 6 this means we are in the letters box
          // otherwise we are in the case/done box.
          if (cy > 0 && cy != 6) cy--;
          else if (cy == 6) cy = 4;
        break;
        case KEY_DOWN:
	  if (cy <= 4) cy++;
          if (cy == 5) cy = 6, cx = 0;
        break;
        case KEY_LEFT:
          if (cx > 0 && cy != 6) cx--;
          else if (cy == 6) cx = 0;
        break;
        case KEY_RIGHT:
          if (cx < 5 && cy != 6) cx++;
          else if (cy == 6) cx = 3;
        break;
        case KEY_ENTER:
          // here we have conditionals to check if the rectangle is in the letter box
          // if it is, we add a letter depending on the case.
          if (cy != 6 && name.length != 8)
          {
            if (fontcase == 0) name += MyFont[cx + cy*6];
            else name += MyFont[cx + cy*6].toLowerCase();
          }
          // if it isn't then we either change the letter case
          else if (cy == 6 && cx == 0)
          {
            if (fontcase == 0) fontcase = 1;
            else fontcase = 0;
          }
          // or exit the menu.
          else if (cy == 6 && cx == 3) return name;
        break;
        case KEY_SHIFT:
          // this will delete a letter off of the end by returning the
          // name with one letter removed. It's 'length-1'.
          var name = name.substr(0, name.length-1);
        break;
      }
    }

Phew! That was a lot of code! Basically, I used a switch...case conditional for each key press. 6 is the magical number here. I made checks to see if whether or not the rectangle is within a zone where we select and quit the menu. This zone begins when cy = 6. When cy = 0 we are at the zone for changing the letter case. When cx is equal to 3 we are at the zone to return the name.

Step 5

Finally let's make a little game...

function game()
{
  var MyName = ShowNamingMenu();
  Abort ("My name is: " + MyName + "!\n");
}

Add that as the last thing and test the script out in Sphere. Hopefully, if you wrote the code right, the game would be a success.

Personal tools