DaVince scripting tutorial
This tutorial teaches you how to script with JavaScript, and how to apply this knowledge so you can make games in Sphere. I have tried to write the tutorial in such a way that beginners can easily step into the world of Sphere. There are also some tests available which you can take to practice the things you have learnt.
Notes
- Spherical has been reborn, so this tutorial needs to be fixed and updated. Expect some future changes.
Resource pack
Here's a very basic resource pack so you can get started right away. Includes:
- a simple map (rmp file)
- a sprite (rss file)
- a font (rfn file)
- some sounds
File names are in Dutch, but it should be clear what's what.
There are more resources on the Spherical Downloads Repository (coming soon).
Contents
About
This tutorial
Ah, Sphere... An awesome and flexible RPG-creation program... It includes a fully-fledged editor to make your own RPGs (or other kinds of games!), and a flexible, extensive scripting language. But how do you start learning and using this scripting language, and how does it work inside Sphere? This tutorial will help you on your way. Some of the tutorial's chapters are based on other, older and sometimes fairly well-known tutorials, but I tried to make sure that they are easier to understand for newbies. Also, examples were added to these chapters. Next to those, there are chapters that I completely wrote myself. The tests are also original. Well, I hope my tutorial will be useful! Have a good Sphere experience! :)
Questions? Suggestions? Other feedback? My email address is VincentBeers@gmail[Dot]com. You can also of course contact me on the Spherical forums. --DaVince
Sphere
Sphere is a program designed to create RPGs in the style of early Final Fantasy games without too much effort. However, you'll be able to create almost any other kind of 2D game you can imagine if you're skilled enough. It uses a scripting language (JavaScript, which is NOT JAVA!) that "makes everything happen". This, of course, means that you will have to learn this scripting language in order to be able to create a game in Sphere. Scripting isn't always easy, especially for programming/scripting newbies, so I'll try to keep things simple and clear.
Where can I find the latest version of Sphere?
Sphere and its editor can be downloaded from Sphere:Latest. The latest versions can always be found there. The versions of Sphere used when this tutorial was first written are versions 1.10989, 1.11, and 1.13 (1.5 during the rewrite of this tutorial). If some things don't work (correctly), download the latest version of Sphere and these problems will usually disappear. If you already have the latest version and you still encounter problems, there might just be something wrong with your code (or you may have found a bug inside Sphere itself).
Get used to the editor first!
If you want to be able to follow this scripting tutorial well, you will have to get used to the editor's interface a bit first and learn how to use it. If not, AT LEAST get used to the file formats and structure that Sphere games use. Tutorials on how to use the editor's interface can be found in Sphere's default docs. Radnen's Using Sphere tutorial and Sphere/Guide to Sphere are pretty good.
Sphere and Javascript
Sphere uses SpiderMonkey, a special library that makes JavaScript available in applications like Sphere. Sphere itself then adds lots of functions to this implementation of JavaScript so you can actually use it to create a game. JavaScript is a browser scripting language in origin, specially designed for the use in webpages, but as Sphere proves it can be used for other things perfectly fine too. Web JS consists of three parts: the Core, the Client and the Server. Sphere only uses the Core, the other two are actually parts that belong to Web JS.
Configuration and information on scripts
Every Sphere game must have a script where it can start out "reading" (actually interpreting) what to do. The start script to use can be defined in the Game Setings window, accessible by double-clicking on "Game Settings" in a project's main window. You can't define a script if you don't have a script yet, of course, so make one first. Give this first script a good, identifiable name, like start.js or main.js. The script doesn't need to have a specific name like main.js - you can give it any valid name you can think of, "valid" meaning using only characters you can use in a filename. However, it's recommended to keep the name simple and preferably without any special characters (even spaces), so you can quickly and easily reference this script in your code. The start script will be the first script that's read by Sphere's game engine when you start the game. If you want to let Sphere open other scripts next to this one, you can use specific functions in the main script to include these scripts (by using RequireScript()).
You do not need to have more than one script, you could just as well put all of the game's code in the one single start script. But using multiple script files makes everything more clear and easier to find and use. Think about it: seperate scripts for battles, menus, text boxes, storyline... It also allows you to use specific scripts in multiple games, if you make sure to make everything in that script work independently from other scripts... Very nice if you made a nice menu or item system that you want to re-use in a different game. Sphere looks for the function game() inside your startup script when the game is launched. This is the only automatically started (rather, "called") function and gives you a point to start with. All other functions will have to be called by hand. More about functions further down in this document.
You will get to know more about scripts later; I'll talk about where you can use scripts first now.
Places that scripts are used
You can use scripts in different places in Sphere. These are the maps, triggers, persons and files.
Maps have a few internal scripts. You can find these in the Map Properties (menu: Map > Properties). They are useful to have the game control what happens when the map itself is opened or closed, or when/where the player-controlled character is entering or leaving the map. Maps also contain two different types of "entities": triggers and persons.
Triggers are attached to a specific tile and have a script that is launched when the player walks over it.
Persons are entities on the map that have a name, spriteset and scripts to control their actions (like walking around, or talking). Persons can have up to 5 personal scripts, each being run in a different situation:
- On Create, used to run code when the person is created.
- On Destroy, runs right before the person is destroyed.
- On Activate (Touch), runs when the person is being touched by the player-controlled person.
- On Activate (Talk), runs when the player-controlled person faces the person and presses the TALK button (default = space).
- On Generate Commands, runs every frame the map engine is open (but only when the person isn't doing anything else).
Files are the most common place for script code and can be created in any text editor. JavaScript files, whether made in Sphere or not, use the .js file extension. The files are the most important part of a game as these are the main method to give instructions to Sphere, including what to start (and where). The scripts in persons, triggers and maps are more of an extra place for a few instructions when that specific map starts or when you talk to a specific person. More experienced coders tend to avoid making scripts inside maps and entities as much as they can, and instead try to code it all in JS files. They do this because this way, all code stays in one place instead of spread out all over the place, and it becomes easier to access, modify and test this code.
To make a new script file, go to File > new > script, or click on the empty page icon. You'll get a notepad-like editor. This is Sphere's built-in script editor, probably the best one for Sphere scripts. You can also make your scripts in your own favourite text editor, just save them as .js files in the scripts directory of your game.
Now that you know what scripts are all about, we can start the real work!
NOTE: FROM THIS PART ONWARD MOST TEXT IS STILL UNFORMATTED. All the tutorial text is here, but I'll still need to take some time making it look pretty again. Sorry.
The basics of scripting
Comments
A comment is the most simple thing to do in Sphere.
With comments, you can give an explanation of something with normal, human-readable text. Sphere itself plain skips over this text. It doesn't read comments as real code, so you can put anything you like in it. A comment is mainly intended to help the reader of the code: you can put comments above your real code in which you explain what it will do, for example. A single comment line can be made by putting // in front of the line, a whole block (multiple lines) can be made by putting /* in front and */ behind it.
//This is a comment. /* And this is a comment. */ /* This is also a comment. But, it stays comment on the next line, too. And it will keep on doing that until the blocks gets closed with the asterisk and the slash. */ This line is NOT a comment, because it doesn't have // in front and isn't in a /* */ block! //Note: above line is a comment from ^^ this spot onward, though!
A comment can be put on the same line as a line of code, too. This is useful for explaining just that line:
Code(); //Comment!
If you're a beginner, it's useful to put comments before or after every line of code that you think you might forget what it does, so you can look it up later and read what a certain piece of code did again...
End a line of code with a semicolon
This is the second simplest thing in JS's code rules (syntax, "grammar"). In real life, you have to add a period (.) at the end of every sentence, and you basically do the same in JavaScript. Well, it's slightly different, as you type a ; instead of a period.
code_goes_here; different_bit_of_code_goes_here; Code; Next_bit_of_code;
Remember this! If your script doesn't work correctly it could be because you forgot a semicolon. If you forget to put a semicolon somewhere, Sphere might try to 'glue' one bit of code together with the next one, which may cause errors because it tries to interpret things differently than you intended.
The basics on functions
Functions
This tutorial will make sure that you can make your own game in Sphere. A simple, but working game. A function is a thing you give an identifiable name, put some code in, and then you can run that code any time you reference the function by its name. For example, you can make a function called TextBox that would make a box displaying text appear, and then you can show this text box whenever you like by calling the function TextBox elsewhere. It's very useful to make your code manageable, and it prevents you from doing bad things like copying the same block of code over and over again in different places. The bad thing about doing things like that is: if you make a change to the code you'll need to change it everywhere else, too. If you have a function, you only need to change it once in that function. It also makes your code take up much fewer lines (because your six lines of code is now replaced by one - the call to the function containing those six lines).
The structure of a function
As you should know by now, every Sphere game must have a main script file, containing the main function called game. If you don't know or remember, please read chapter 1 again. A function always starts with the word function so both Sphere and the reader of the script knows we're going to make a function. You call such a word a keyword because JavaScript uses it internally to identify what you're trying to do. In this case, we want to define a function.
After the word function comes the name of the function. When giving it a name, keep in mind only letters, numbers and the underscore _ are allowed. It is also not possible to start the name with a number. Examples: FunctionName, funcname1, function_name.
After the name come two parentheses: an opening parenthesis and a closing parenthesis (). Things can go inbetween these parentheses, but I'll explain that later.
After that, you put an opening brace { which indicates that the code coming after the brace will belong to your function.
After the brace, you put the code that would be run when the function is run.
When you're done with your code, you close down the functions with the closing brace }.
Example of a function named 'game':
function game() { //code comes here. }
That's what a function looks like, basically. game() is, as mentioned before, the starting function for a Sphere game.
Still, if you try to run this code, nothing will happen. Sphere will open and then immediately close. That's because we didn't put any code in yet. Let's add one very simple command, with a comment in front of it:
function game() { //This function will open the map map.rmp. MapEngine("map.rmp", 60); }
This piece of code WILL do something, namely it will open the map engine with the file map.rmp, with a framerate of 60 frames per second. Still, if you want this code to work, make sure that the file map.rmp actually exists (and is inside the maps/ directory of your game)! The above code also demonstrates what calling a function looks like. MapEngine() is a function inside Sphere itself, but if it were coded in JS by a normal user it would have the same structure as the game() function:
function MapEngine(map, framerate) //map, framerate will be explained in the next chapter. { //Code to make the map engine to work here. }
The original function actually consists of internal Sphere code, not scripted in JS, but in the programming language Sphere itself has been written in, C++.
Example of some simple Sphere functions
Okay, now for some more difficult stuff. I'm going to show you and explain a few of the most used functions in Sphere. Every line of code will be explained.
function game() { CreatePerson("my_name", "character.rss", false); //Creates a new person. gives him the name my_name and loads the spriteset file character.rss for his looks. //'false' indicates he should NOT be destroyed when the game switches maps. That means he'll keep existing even on other maps. AttachCamera("my_name"); //Makes sure that the camera is always pointed at the person called my_name. AttachInput("my_name"); //Bind the default input to the person my_name. This means that when you press an arrow key, he'll move, stuff like that. MapEngine("map.rmp", 60); //We'll open map.rmp with a framerate of 60 frames per second (fps). }
The functions:
CreatePerson(person_name, spriteset, destroy_with_map) AttachCamera(person_name) AttachInput(person_name) MapEngine(mapfile, framerate)
A list of common functions
There are a lot more common Sphere functions, another bunch explained below. You can look up all the other Sphere functions in the doc_functions.txt file that comes with Sphere (it's in the docs directory). You should also check out the Functions documentation on this website, it's a lot more comprehensive and offers examples for each function. NOTE BEFORE YOU USE THESE: Some functions have a dot . in them. I'll talk about what this means in detail later. For now, just put the appropiate function that loads a resource in front. Example LoadFont("file").drawText(1, 1, "text");
Function Description
- FlipScreen() Puts everything you have drawn so far on the screen. When using a draw or blit function or anything like that, it doesn't get drawn on the screen but on the backbuffer. Things drawn on the backbuffer will show up on the screen when using FlipScreen(). After that the backbuffer is made empty again. ALWAYS PUT THIS AFTER YOU HAVE DRAWN SOME STUFF!
- LoadFont("font_file") Loads a font file. Only the Sphere font format .rfn is supported, so make a Sphere font first.
- Font.drawText(x, y, text) Write text on the screen with the assigned Font and on the assigned x/y coordinates (in pixels). Don't forget to replace 'Font' with the font file you wish to use, like this:
- LoadFont("font_file.rfn").drawText(10, 10, "Good day, world!");
This is not the optimal way to do it because you load the font file over and over every time you want to draw text, but it will do for now.
- Font.drawTextBox(x, y, width, height, offset, text) Write text on the screen with the assigned font and on the assigned x/y coordinates. This is a bit different from Font.drawText: it has borders you can assign using the width and height arguments. When the text hits the maximum width, it continues writing the rest of the text on the next line until the maximum height is reached too (in pixels). The offset adds an extra bit to the Y position of your text.
- LoadWindowStyle("windowstyle_file") Loads a windowstyle file in memory. Make sure you have a windowstyle file first, of course.
- WindowStyle.drawWindow(x, y, width, height) Draw the windowstyle on coordinates x,y with the assigned width and height.
- LoadImage("image_file") Load an image file (bmp, png, gif, jpg, pcx, tga are valid formats, png is recommended for its size/quality ratio).
- Image.blit(x, y) Draws the image on the assignes x,y coordinates. Blit is an old English word for draw.
- Image.zoomBlit(x, y, zoom) Draws the image on the assigned x,y coordinates, but resized according to the zoom argument. Zooming is 1:1, so when inserting a value like 1.5 the image will be drawn 1.5 its original size.
- LoadSound("sound_file") Load a sound file into memory. wav, mp3, ogg, MIDI, modules (IT, MOD, XM) are supported sound formats.
- Sound.play(repeat true/false) Play the loaded sound. The argument is tru or false, depending on if you want the sound to repeat. true = repeat, false = do not repeat.
- Sound.stop() Stop the sound. This function has no arguments.
- RenderMap() If you have the map engine open and you want to draw something on screen, the map will not be shown when you FlipScreen() it. This is done for flexibility purposes. With RenderMap() you tell Sphere to put an image of the map engine in the backbuffer, so all the stuff you draw after it will be displayed on an image of the map. Put this before all other draw stuff, because it will be drawn in front of the rest if you don't.
- GetKey() Pauses the script until you press on a key (ANY key). Useful for intros. can also be used in combination with an if condition. You can find more information about if in chapter 4.
- ChangeMap("map_file") If the map engine is open, you can switch maps with this function.
- Exit() Exits the game.
Variables and more on functions
Variables
If you inserted more texts or objects of the same type in your code, you'll find that it is pretty annoying to type things like LoadFont("file") over and over again. Luckily there is is this little thing called a variable, which you can use to store these things (and values, text and a lot more!). Because of this you will only need to type the name of the variable to get what's stored inside it, which could be our LoadFont("file") or whatever!
var i_gave_it_a_name;
This is how you make a variable. It does NOT have a value or contain any data yet. I did give it the name "i_gave_it_a_name", which means we can type i_gave_it_a_name every time we need its contents. You can't do that yet, though, as it doesn't have any contents right now. What we have done here is declared (created) a variable. This means that you made a piece of memory available for our variable. The keyword var is only needed once, and that is during declaration. After that, every time you type the variable's name, JS already knows it's a variable. Now, let's declare a different variable and assign a value to it.
var music; music = LoadSound("SomeFile.mp3");
This code declares a variable called music. Then we give it a value. The value we just gave it is LoadSound("SomeFile.mp3"), which is a function that loads a sound file an puts it (as a value of sorts) inside the variable. Now you can use the variable music as a 'shortcut' to what's inside it, which is the contents of LoadSound("SomeFile.mp3") in this case.
music.play(true); //This is much easier than LoadSound("SomeFile.mp3").play(true);
What you see is music.play(true), but Sphere sort of reads it as LoadSound("SomeFile.mp3").play(true) because music is a variable containing (the result of) LoadSound("SomeFile.mp3"). This is not only easier to type, but it also saves a lot of memory because the actual sound file is loaded only once into variable music, and not reloaded for every time we need the music. Using just LoadSound("SomeFile.mp3") all the time would load the file over and over every time, making your game use way too much memory. Not only that, but if you load the same song twice, it's still identified as two different songs in memory, so you can't actually use the .stop() function to stop music if you don't put it in a variable!
There is another, faster way to create a variable and assign a value to it at once. You can do it like this:
var music = LoadSound("SomeFile.mp3"); The variable is declared and immediately given a value. Don't forget you don't need the var keyword anymore after you declared the variable once. var haha = LoadFont("haha.rfn"); haha = LoadFont("eh.rfn"); //As you can see, there's no 'var' in front. haha = LoadSound("haha.mp3");
As you can see you can also change the value in the variable anytime you like. It IS called a variable, after all. Its contents can vary, even from one moment to the other.
Variables and data types
You can store more than just functions in a variable! You can also use them to hold numbers or text so you can use these later. These different types of data is called exactly that - a data type. Example:
var story = 1; var current_text = "What a nice string of text I am!";
This is useful for storylines, for example. If an event has happened: change the value of the story variable so Sphere knows that the event has happened. There are many more types of data that you can store, they will be explained in detail in the More on variables section.
Adding and subtracting to variables
How to add and subtract values from variables containing numbers? It isn't as hard as you'd expect...
- variable++ adds 1 to your variable.
- variable-- subtracts 1 from your variable.
- variable += value adds the value to your variable.
- variable -= value subtracts the value from your variable.
- variable = value changes your variable to the value.
Of course, you could always do something like variable = variable - 4 if you like. But why do that if there's a shorthand version like variable -= 4?
Creating a function
As you probably know by now, Sphere reads the commands you insert. These commands are called functions... game(), for example, is a function too, so it could be started the same way as for example a FlipScreen(): by typing its name and the braces behind it.
game();
So with this you'd run whatever is in function game(). This particular function doesn't need to be called manually, because game() is automatically called when Sphere starts your game. But it's a good example on how to create your own functions.
Making your own function is pretty simple. Just look at how you made the game() function... You can make your own functions in the same way.
function Name() { //Code comes here. }
You can put code in functions, this code will be executed as soon as the function is called from somewhere else. As an example we'll try to make a function that executes all commands necessary to make a box containing text.
//First we'll declare a few variables outside of any function. //This makes them global, which means they will exist in any function, even if you didn't declare them there. var window = GetSystemWindowStyle(); //Declare the variable 'window' and put the standard Sphere window style in it. var font = GetSystemFont(); //Opens the (ugly lol) standard Sphere system font and puts it in the 'font' variable. //Here's our own function named 'TextBox'. function TextBox() { //Code goes inbetween the braces {}. window.drawWindow(5,5,310,100); font.drawText(5,5,"Some text"); FlipScreen(); GetKey(); }
If you insert TextBox(); in your game function, everything in the TextBox() function will be run once you start the game.
function game() { TextBox(); }
Function arguments
There is something lacking about our textbox: you can add TextBox(); to your code, but the end result will always stay the same. Every time you call TextBox() you will see the text "Some text" appear on the screen, no matter what. But what if we wanted to display something else, like "Hello", "Line 2" or "Status: moody"? It's not smart to make four different functions just for that, that would be a waste of memory. It would duplicate almost the exact same code four times, defeating the purpose of having a function! So instead, we slightly change the TextBox() function. Examine the following code:
function TextBox(text) { window.drawWindow(5,5,310,100); font.drawText(5,5,text); FlipScreen(); GetKey(); }
Look at the spot where the function is declared (the first line). Inbetween the parentheses there's something new now. This is NOT a function or variable, but an argument. Arguments (also named parameters) can pass values (any kind: numbers, strings etc) on to your function, resulting in the output varying depending on what you "fed" the function. Now we can put all our different text in the function and get different results:
TextBox("Hello"); TextBox("Line 2"); TextBox("Status: dead");
As you can see we put our text in-between double apostophes ", in-between the braces () of the function call. The " are there to show Sphere that it's a string of text. More on that in chapter 5. The stuff that we insert inbetween the parentheses is saved into an argument, we gave this argument the name 'text'. Arguments behave like variables, but only inside their own function. They don't exist outside the function. (The same actually counts for variables made inside a function.) Anyway, what Sphere will do is give assign whatever value you put inbetween parentheses to this argument, and then use it inside the function.
If that wasn't clear enough, imagine that Sphere is doing this: (it doesn't happen literally, but you can compare it with this anyway:)
- Take the text that was found when the function is called and put it in our argument 'text'.
- Walk through the function and look for other places using this argument 'text'.
- Replace it with what we got through the function call.
- The result is different every time because it's dependant on what you inserted!
And here it is in physical form:
function a(argument) { Abort(argument); } //And to call it: a("This text is used by the Abort() function inside the a() function."); function a("something!") //Don't write code like this! Only put something that looks like a variable. This is just an example on what Sphere might do internally. { Abort("something!"); }
Multiple arguments in one function
If you want to have more than one argument, simply seperate the argument names with a comma:
function TextBox(x, y, text) { window.drawWindow(x, y, 310,100); font.drawText(x, y, text); FlipScreen(); GetKey(); }
The function call would look like this:
TextBox(10, 15, "hahaha!");
This will make the text "haha" appear on x position 10 and y position 15.
Test 1
It's good to take a breather from learning new concepts from time to time and actually use the time to put your newly learned concept into practice. I'll help a bit by creating a test that indicates what you should try to do.
Please note that the test is not up-to-date with the revised tutorial right now. This will be fixed soon.
Good luck!
More on variables
There's a few types of values available in Sphere, each one of them is intended for different things. This means that you can put different types of content in variables. In this chapter you'll learn about most of these types of values.
1. Numbers
You already knew this one. It is an often used type of value. You can put numbers in variables so you can refer to them, change them, or do maths with them. var blah = 4;
2. Text
You know this one already, too, if you have been paying close attention to the last chapter. You can use regular sentences, words, letters and characters with this type of content. You call this a string. Strings are used to store and use text in your program. Strings are recognizable by the fact that they have double quotes put around them (like "this"). This is done to clearly define to the system that it is a text string, not a number or anything else. You can also use single quotes if it's more convenient at the time, but take care with single quotes if you have "regular" text: words like it's use a single quote too, so they would end the string. Strings are also typically useful to define file and directory names.
var hi = "Hello!"; var project_file = "game.sgm";
There is a way to "connect" seperate strings together, in fact, it doesn't even have to be a string to be able to connect it to a string. Connecting (or combining) two strings (or compatible types) is what you would call concatenating. There is a very simple way to concatenate: use the plus sign as if you were "adding" two values. Run the following code in Sphere:
var string = "I am a string" + " with a second string concatenated"; string = string + " and a third string concatenated"; string += " and even a fourth one!" + " And a fifth one on the next line, because the plus character allows this."; Abort(string);
Sphere will show something like this:
I am a string with a second string concatenated and a third string concatenated and even a fourth one! And a fifth one on the next line, because the plus character allows this.
Strings can also contain some special characters you can use for formatting the text when it's put on screen:
- \n makes a new line.
- \t adds a tab (or rather, 5 spaces).
- \\ is for adding a \ to the text. :P
- \" is used so you can safely add a double quote to your string without indicating to the engine that you finish the string.
If you used a single quote ' to formulate your string in stead of a double quote, you can use a regular " inside this single-quote string, but you will then have to define "textual" single quotes like this: \'
Try running the following code to see how you can use these:
Abort("Hi.\nI'm on a new line.\nMe too.\n\tI'm on a new line with a tab in front.\nC:\\path\\to\\something.txt\nAnd \"I\" am in \"quotes\".");
The result will be something like this:
Hi. I'm on a new line. Me too. I'm on a new line with a tab in front. C:\path\to\something.txt And "I" am in "quotes".
3. Sphere functions
Sphere has a few built-in functions that can return values, meaning they give you values back when calling them. For example, GetPersonX(name) gives you a numerical value of the X position of a person on the map, GetScreenWidth() gives you the screen width, stuff like that. When you use such a function as a value in a variable, Sphere will put the resulting returned value in the variable. var blah = GetScreenWidth(); In this case, you're not really putting the function in a variable. You're putting whatever value it gives back to you in it instead. For example, GetScreenWidth() could return the number 320 to you, so var blah would then contain the number 320 as a value.
You can actually store the actual function inside a variable, if you wish. This will create what you would call a reference to this function: you're basically creating a new identifying name to call the function. To re-reference a function, just remove the parentheses () at the end: var GetSW = GetScreenWidth; var blah = GetSW(); //GetSW() actually calls the same code as GetScreenWidth() would now. There are a lot of functions in Sphere that return a value to whatever called it. Below are a few that you might want to study and practice using.
- GetPersonX(person_name) - Returns the x position (as a number) of person_name on the map.
- GetPersonY(person_name) - Same, but returns the y position.
- GetScreenWidth() - Returns the width of the game screen (as a number).
- GetScreenHeight() - Returns the screen height.
- GetPersonList() - returns an array filled with strings of the person names on this map.
- GetVersionString() - Returns the current Sphere version (as a string).
4. Sphere's special internal objects
You can put objects in variables. Objects are a kind of function too, but they can do much more internally, like store and retreive sub-values and even sub-functions inside. They also can have "changing" states: two objects can be the same on the outside, but store very different things. For example, you can have two instances of an Image object, one containing a small icon and the other a big cloud graphic. Objects are complex, so I'll leave the explanation at that for now and go more in-depth later in the tutorial. Anyway! Sphere has a bunch of internal objects that can load images, music, basically all basic file resources. These objects can be made (instantiated) and stored inside variables by calling their appropiate LoadWhatever() functions, like LoadImage(file) or LoadFont(file). These then offer some internal "sub"-functions (or subvalues) to get or change further information, like image.width and image.height, or Font.getHeight().
var blah = LoadFont("fontfile.rfn"); var fontheight = blah.getFontHeight(); blah.drawText(10, fontheight, "Hahaha!"); //y position of this text depends on the height of the largest character in the font you loaded.
blah contains an instance of Sphere's internal Font object, which has methods (subfunctions, indicated with a separating dot) to further do things with this object, like draw it on the screen.
The following is a list of functions that returns an instance of any special Sphere object, like images and fonts.
- LoadFont(file) - Makes and prepares a font object and returns it (to whatever called it).
- LoadImage(file) - Makes and prepares an image object and returns it (to whatever called it).
- LoadSound(file) - Makes and prepares a sound object and returns it.
- LoadAnimation(file) - Makes and prepares an animation object and returns it.
- LoadSpriteset(file) - Makes and prepares a spriteset object and returns it.
- LoadSurface(file) - Makes and prepares a surface object and returns it.
- LoadWindowStyle(file) - Makes and prepares a windowstyle object and returns it.
- OpenFile(file) - Makes and prepares a file object (for saving game data or settings) and returns it.
---
- CreateColor(red, green, blue, alpha) - Makes a color object with the values you gave it.
- GrabImage(x, y, width, height) - Returns an image object that contains the contents of whatever is on screen in the zone you specified.
- GrabSurface(x, y, width, height) - Same as GrabImage(), but it returns a surface object, which has different kinds of functions. Better suited for manipulating the image, or drawing it in a special way (like warping it all over the screen).
All of the above functions actually make different kinds of objects, which have their own specialized functions for that type of file. For example, a Sound object has .play() and .stop() functions in it (these are methods), and the Image object has a .blit() function (or method), etcetera. You can create your own objects too.
5. New functions
You can also put NEW functions in variables, like this:
var blah = function(parameters) { //Code comes here. }
This is basically a different way to declare a function. It's functionally equivalent to this:
function blah(parameters) { //Code comes here. }
This might seem useless, it has several uses:
Objects use it to create methods (subfunctions, example is the getHeight() method in Font.getHeight()), because the syntax to make these is a bit different. You can make anonymous functions. These are normal functions that do not have a name. An example of doing this is when you pass a function as an argument:
function CallMe(argument) { argument(); //I'm sure that the argument actually contains a function! Let's call it. } //... CallMe(function() { Abort("something happens in here."); });
That's a lot of braces and parentheses! But all we do on the last line is create a function on the spot, on a single line, and not assign any identifiable name to it. I could also have done the following for the last line, but then you wouldn't call it an anonymous function anymore:
var somefunction = function() { Abort("something happens in here."); } CallMe(somefunction);
Still, it does the same thing; pass a function to another function, showing that functions can be allowed as "values" to pass to other things just as well as a number or a string.
6. true and false
true and false are keywords in JavaScript that are used when you only need to know two "states" about something. Some examples: Has an event happened? (you could call it a flag when used like this, you toggle the flag as you finish the event.)
var talked_to_old_man = false;
Should my textbox draw a window?
var draw_a_window = true; //And in a textbox function somewhere: if (draw_a_window) //The condition evaluates to "true" because draw_a_window is true... { windowstyle.drawWindow(x, y, w, h); }
Do I want to debug my game and show extra values on the screen?
var DEBUG = true; //Anywhere else in code: if (DEBUG) { /* Do something related to testing your game */ }
Do I want to check if something finished in order to end a loop?
var finished = true; while (finished == false) { //Do whatever until I set finished to true somewhere in this loop. }
An alternative way of checking for false is by putting an exclamation mark in front of the condition (or variables in the condition), like this:
while (!finished)
Do I want to check if something simply is true or false, or do I want to make it true or false?
if (!sound.isPlaying()) //Check if sound is not playing (sound.Playing == false). { sound.play(true); //The true here is an argument to sound.play, which answers Sphere's question: should the music loop? }
As you can see, it has many small but important uses. You'll encounter these two values a lot.
Last thing, remember that false is (sort of) equivalent to 0, and true is (sort of) equivalent to almost any other value. This means that a condition like (value == false) could be true when value equals 0! This can come in handy in places like loops.
7. undefined
undefined is a keyword in Sphere (or rather, JavaScript) that lets you enter nothing as a value! For example, some function's argument could be optional, and use some other default value if it's not set, so in this case you could pass the undefined value as an argument. Or maybe you wish to erase a variable's previous value.
var blah = 4; blah = undefined; //Woops, setting 4 was a mistake.
Or maybe you wish to declare a variable, but not set a value yet... But then again, in that case you could just not set a value: JS will automatically enter undefined as the default value for a variable not given a value.
var blah; Abort(blah); //Sphere will quit, printing out "undefined".
8. Arrays
Arrays are somewhat different from the other variables mentioned so far. The big difference lies in that you can put multiple values in it, and these values can be of various types (even more arrays)! Declaring the array To make an array, you can type one of the following:
var blah = new Array();
- OR -
var blah = [];
I recommend using [] because it's shorter to type, though it doesn't really make a difference. The first way is a nice example of instantiating an object, though, so you might want to come back here later when you're learning about objects.
Storing values in the array
Okay, so now you have an Array. You can store your values in it in two different ways. The first way to do it is by putting values in it right when you declare the array.
var blah = new Array(1, 6, 4, "Theo", "etcetera", new Array("subarray!"), 88);
- OR -
var blah = [1, 6, 4, "Theo", "etcetera", ["subarray!"], 88];
This is how you declare the array and immediately put some values in it. An array is like a list of items where you can store a value, each seperated with a comma. All items in this list also have a number, starting from 0, which can be used to identify the seperate items, or places in the array. In the above array: The number 1 is stored in spot 0 of the array. The number 4 is stored in spot 2 of the array. The string "etcetera" is stored in spot 4 of the array. Another array (containing the string "subarray!" on spot 0) is stored in spot 5 of its parent (or containing) array. Did I confuse ya? Read over it again, then continue. The second way to put values in an array will make things a bit clearer. :)
The second way to store values in an array is by already having declared the array, and then assigning values to spots in the array: var array = []; //or new Array(); array[number] = a_new_value; For example, I'll now change some of the values in the array blah we made before: blah[0] = "new value!"; //Spot 0 contained the value 1 before, now it contains "new value!". blah[1] = 7; //And this used to be 6 blah[4] = "Pete"; //And this used to be "etcetera" blah[7] = "new value"; //Spot 7 comes after the last spot (spot 6, which contains 88), so basically we created a new spot to store a value in. blah[9] = [1, 2, 3]; //Another subarray with three items is added to the blah array. Spot 8 will contain an undefined value. This way you can change the values (or make new values) on different places of your array. The old values (if there are any) are replaced, just like in a normal variable. Since we didn't touch spots 2 and 3, they'll keep their original values, which were 4 and "Theo". That means that our array now consists of the following values: ["new value!", 7, 4, "Theo", "Pete", ["subarray!"], 88, "new value", undefined, [1, 2, 3]] Now how do we use these values? Well, that's pretty simple, actually. Just refer to your array and add straight brackets right after it containing the number of the spot you want to reach. For example: var nn = blah[3]; //nn now contains the value "Theo". TextBox(blah[4]); //TextBox will print out the text "Pete". Abort(blah[9]); //Sphere will quit, showing the text "[1, 2, 3]" (the array gets interpreted as a string, showing its internal values).
So what are arrays useful for? Well, for example, they can be useful for an inventory: var inventory = ["Potion", "Antidote", "Empty bottle"]; But most importantly, they can be used to store similar data together and perform mass actions on them. Like making of all characters in your game (or just the party) and then generating a person on the map for each one of them: var people = ["DaVince", "Petey Pirate", "Aegis", "Flikky", "Nidoran"];
//Create persons using their above name for both the identifying name and the spriteset file to load (like DaVince.rss or Nidoran.rss). CreatePerson(people[0], people[0] + ".rss", true); CreatePerson(people[1], people[1] + ".rss", true); CreatePerson(people[2], people[2] + ".rss", true); CreatePerson(people[3], people[3] + ".rss", true); CreatePerson(people[4], people[4] + ".rss", true); The above code can be made much simpler and quicker using loops, explained in the next chapter. You'll find that arrays can have lots of uses. I use them a lot, and some native Sphere functions also use them, so you'd better get to know them! ;)
Conditions and loops
If, while and for
This chapter will become a bit more difficult and confusing because we'll have to break some of the Javascript syntax rules that you learned before. For instance, we won't add a semicolon after every line anymore, and sometimes we add multiple semicolons in one line! Luckily this only happens on a few special occasions, so once you know this exception from the rule it shouldn't be too hard to stick with it.
Conditions: 'if'
I bet you have thought at least once about having an event happen in the game ONLY when something else had happened first. This is called a condition, as you set a condition for when it will happen. Conditions can check if something is true or not. For example, it can check if the variable 'blah' contains value '4', and if it's true it will return 'true'. This can be done with the if keyword. var story = 0;
1. if (story == 0) //Note that there's no semicolon ; at the end! 2. { 3. TextBox("Hi. Could you do something for me? Thanks!"); 4. story = 1; 5. } (The TextBox() function doesn't exist by default in Sphere, you'll have to make a TextBox() function yourself if you want the above to really run. It's just an example.) What you did with this code is the following: You check whether the story variable is equal to 0. This line of code has TWO equals signs (=) in it, because a double equals sign tells JavaScript that this is a comparison: we're comparing the value of story and the numerical value 0 with each other. Double-equals (==) indicates that JavaScript will specifically check if these are EQUAL to each other. A single = does not run a comparison, but assigns a value to a variable. A good example of this is when you were making variables: you assigned a value to a variable by putting an = in-between: var a = 6. We shouldn't use a single = in a comparison because we're comparing two values, not assigning a value to a variable! A condition (or if-statement) uses braces {} in-between which you enter the code that's going to run when the condition passes, just like how a function runs code inbetween braces when it is called. You usually call this a block of code, or a code block. The opening brace { is put after the if-statement. The code in-between the braces will run when the condition evaluates as true (so when story == 0). Else, it will simply skip the block of code and continue regular code execution from the marked line 5 onwards. This is some code to run. TextBox() from the previous example was used in this example, too. Now that we've done everything we wanted in case story was 0, let's change the value of story to 1. This ensures that the condition will not be run again, so the same event won't happen twice (unless you set story back to 0 somewhere). The condition's code to run (the code block) is ended with a }. As you can see, the structure of a condition is almost the same as the one when you're creating a function. The big difference lies in when it is run: a function will run when it's called, but a condition will run whenever it's encountered AND when its conditions all evaluate to 'true'. (Evaluate, in JS's case, basically means to "solve" a problem by simplifying it. 1+1==2 would evaluate to true since 1+1=2, and 2 IS indeed equal to 2. Otherwise it will evaluate to false.)
If it helps, here's one more explanation compared to real life. Things like story == 0 are things that you could call a statement. Basically, you make a statement to the engine that story would have the same value as 0. JS then evaluates this statement and determines if this is true, or false. Kind of like a math teacher evaluating your test answers. They'll also put crosses and circles on your test paper to indicate if your statement that 1 + 1 = 3 is true or false.
Comparing values
The == operator (that's what you call it) is just one of a set of comparisons you can use in conditions. It compares whether one number is equal to the other. But more types of comparisons exist, like checking if a value is higher or lower than the other. Here they are:
a > b Compares whether value a is higher than value b. a < b Compares whether value a is lower than value b. a >= b Compares whether value a is higher than or equal to value b. a <= b Compares whether value a is lower than or equal to value b. a != b Compares whether value a is anything but value b. a === b - This is a special beast. Some weird values can evaluate to true together, even if they're not of the same type or even value. For example, when you compare to the value true, almost any value will do to make the complete comparison evaluate to true. (2 == true), (true == "a string") and (-400.6 == true) will all evaluate to true, simply because these values are not false in the machine code (false is typically, and physically, 0. True is plain everything else). However, these values obviously ARE different. A triple-equals sign === was made to solve this problem: it will not only compare the values but also the types of the items compared. If you do this, only one single value will still evaluate the comparison with true to true: true itself. (2 === true) evaluates to false. (true === "a string") and (-400.6 === true) also evaluate false. Only (true === true) will evaluate the condition as true. And this, in some cases, is the only behaviour the user wants. Think it's useless? Why would you compare true to true, after all? Well... Don't forget you can store values, including true, in variables! When var blah = true;, (blah === true) will evaluate to true!
You use all of these in the same way you used the double equals sign. if (a > b) { TextBox("a was higher."); } if (a != b) { TextBox("a and b are different."); } if (a <= b) { TextBox("a is lower, or the same as b."); } if (a === b) { TextBox("a is the exact same object with the exact same value as b."); } //etc. Side note Notice how I put the condition, opening brace, code and closing brace all on one line? Yes, this is allowed. You can do the same with functions, or other blocks of code that look like them: function Something() { TextBox("Hi."); /* I'm a nested comment. */ Abort("The game is quit now."); } It's best to do this only if you have only one or two things to do for a condition, though. The semicolons ; within the braces {} get real important as its seperates each function call properly.
Loops: 'while' and 'for'
while
Loops in Sphere! These are very useful for things like repeating code. One advantage is that you don't have to have many lines containing the same code over and over again. Example: var value = 0; value++; TextBox(value); value++; TextBox(value); value++; TextBox(value); value++; TextBox(value); //etcetera etcetera....
It takes up way too much code if you want to add 1 to value and show a textbox with that value 100 times in a row. That's where the loop comes in: a loop makes it neat and short because you just enter the two lines (value++ and TextBox(value)) in it once, and then run it a hundred times! The loop takes a condition to determine when it should still repeat the code running inside. If the condition is false, the loop ends. There are more kinds of loops. The while loop is the easiest one to start with, because it looks just like an if block. var value = 0;
while (value < 100) {
value++; TextBox(value);
}
//Code continues here when the loop is done. In this case, the loop is done when variable value is 100, because the statement made in the condition is then false: we state that value < 100, and JavaScript will evaluate the statement as false because value is no longer lower than 100.
And the explanation: The loop is basically like an if-statement: it checks whether the given condition returns true. The only difference is that it repeats the code inside the braces when this is the case. In this case, the loop can be interpreted as: While the value of var 'value' is lower than 100: add 1 to value and run the function TextBox with the value as its argument. When the loop starts, var value is still 0, and the code in the loop is run until var value reaches a value of 100 (or higher). Then the loop ends because (value < 100) is false. Sphere will go back to running the code that's below the block of loop code. If we had NOT used a loop for this piece of code, we would have wasted around 200 lines of code: 100 for value++ and another 100 for TextBox(value). But with the power of loops we minimized this to 5 lines, where the two crucial lines loop themselves 100 times. This makes the loop a really powerful tool. Finally, a single time that we run the loop is called an iteration: the above code goes through 100 iterations. The second iteration would have the system raise value from 1 to 2 and display '2' in a TextBox. The 88th iteration would make the value go from 87 to 88 and display '88'. The last iteration is run when value is 99 - when it's 100 the block of code is no longer run.
for
There is a different, more useful but also more difficult to learn type of loop. This is the for loop. A for loop looks a bit different. It's because you do multiple things at once, still in the loop. A for loop usually looks like this:
for (var value = 0; value < 100; value++) There are three things here, and semicolons inbetween them! That's a bit different from the usual... But, it's not as difficult to grasp as you might think, and it actually makes the loop much more powerful...
for (instantiate a variable; put your condition here; the stuff that happens to the variable each loop iteration comes here) In the first part of a for loop, you place your variable that will usually 'control' the loop. This can be a new variable, or one that was created globally somewhere else. You should also give it a starting value (if you don't, your variable will effectively be useless for use in the loop). In the second part you place the condition, just like you would do in an if or a while loop, only this time you usually involve your special variable. In the third part you put code that affects the variable so it can end the loop at some point. The third part of the statement is run after the code inside loop was run; eg. after an iteration has finished. This is the best I can explain it. Best way to understand it after this is trying it out for yourself. ;)
The rest of a for loop looks just like a condition or a while loop: for (var blah = 0; blah < 25; blah++) {
TextBox("This loop started " + blah + " times so far...");
} TextBox("Countdown for liftoff! Ready..."); for (var blah = 10; blah > 0; blah--) {
TextBox(blah + "...");
} TextBox("ZERO! We have a liftoff!"); The loop won't show a text box with "0..." because the loop ends right after blah is decreasing in value from 1 to 0. So we can put our own, neater "ZERO!" at the bottom instead.
Practical example of combining loops with arrays
Now for a different use of the loop that also shows its practical use in combination with a collection of data (in this case, an array). We're going back to the last example of the previous chapter, and we're going to rewrite it to use a loop. Goal: to create persons on the map using their names identified in the array. Original version: var people = ["DaVince", "Petey Pirate", "Aegis", "Flikky", "Nidoran"];
//Create persons using their above name for both the identifying name and the spriteset file to load (like DaVince.rss or Nidoran.rss). CreatePerson(people[0], people[0] + ".rss", true); CreatePerson(people[1], people[1] + ".rss", true); CreatePerson(people[2], people[2] + ".rss", true); CreatePerson(people[3], people[3] + ".rss", true); CreatePerson(people[4], people[4] + ".rss", true); New version: var people = ["DaVince", "Petey Pirate", "Aegis", "Flikky", "Nidoran"]; var len = people.length; //array.length can be used to get the length of an array. //In this case, it's 5 (the highest spot to contain a value is in 4, meaning there's 5 items that were given a value (including the undefined ones)).
for (var i = 0; i < len; i++) //Basically, we go through each and every item that's in the array, and run the code below, using them. {
CreatePerson(people[i], people[i] + ".rss", true); //people[i] is people[0], then people[1], then people[2]...
} It might not seem too worthwhile to write a loop for this small bit of code, but consider how much extra work you would have to do if you had 14 people... And what if two of them disappeared later? The original version is inflexible and relies on you knowing exactly what's in the array; the flexible version has the computer take care of that. This greatly reduces the chance of getting error messages as your program won't read entries that no longer exist, for example. It also greatly expands the possibilities of what you can do with the language, and with your game.
do...while
There is also a third type of loop, but it's basically the same as a while loop and not many people use it. If you still want to know more about it, check out this page.
Test 2
Alright, you should now know enough about data types, conditions, loops, basically anything important enough to be able to make simple games! In fact, you're now fully equipped to make your game already, but if you want to do it orderly and efficiently, you'd better learn more about objects too!
Advanced functionality in functions
There's much more that you can do with if-statements than you have learnt so far. For example, you can put several conditions on your if-statement at once; you can group related if-statements together for efficiency and readability; you can even leave out the braces around the code to execute in some cases. This chapter will explain you why and how.
Combining several conditions: && and ||
You can combine several conditions - that is, comparisons - to make an overall more complicated if clause. More complicated, but also more precise. For example, (value > 0) can only check if your value is higher than 0, but combined with a (value < 10), we suddenly only have the possibility to be the numbers 1 to 9 to have a condition evaluate to true! This can be very useful, and sometimes even required, to get the desired effect.
The inefficient way
The inefficient way is nesting a condition inside another one.
if (value > 0) {
if (value < 10) { TextBox("The value is somewhere in-between 0 and 10."); }
}
You're running two conditions, here. But you're also running two if clauses. This takes up a tiny bit more processing power. The computer gets a tiny bit more to do, because it has to do this:
- Compare a value,
- then run the code inside,
- which again compares a value,
- then runs the code inside that,
- and then Sphere has to "end" that block of code.
- And then another one, because we had two conditions.
This can surely be done more efficiently! Yup, it sure can:
The efficient way
if (value > 0 && value < 10) {
TextBox("The value is somewhere in-between 0 and 10.");
}
What Sphere does now:
- Compare a value,
- and a second one,
- evaluate whether the total result is true.
- If so, run the code inside,
- and then "end" that block of code.
Actually, I think it might be less steps, because computers have special ways to compare multiple grouped conditions efficiently. Still, one step less than the previous thing with my explanation. The code complexity has decreased, and you have saved some precious processor power, which can then be used towards more useful things, like advanced AI or whatever.
Next to the &&, which is called the AND operator, there is the OR operator. This special operator will evaluate the entire result as true if any of the given conditions is true, no matter if all others are false. This can be useful if you want some common code to run under only some circumstances:
if (cheat_mode || backflip_mode || the_player_kicks_ass) //If even just one of these three equals true... {
DoABackflip();
}
The player might do a backflip if any of the three variables given are true. Doesn't matter if only one of them is true, or all three... As long as something is true, it'll run the code inside the block.
The two types of operators can be combined. You could check if all elements in a set of conditions is true, and then compare that to another conditions that might override it and run the condition anyway. It's best to group these together by using extra parentheses. Example:
if ((master_password_entered && voice_recognition_success && confirmed_twice) || evil_intruder_override) {
SelfDestruct(ship);
}
The ship will ONLY self-destruct if the master password was entered, the voice recognition succeeded AND the user confirmed the self-destruct sequence twice. Only then. Oh, or if there's an evil intruder who somehow overrode the system.
Of course, even if you don't use such a complicated combination of options, it's still a lot more convenient than putting a condition alongside a condition inside a condition inside a condition. Note that it also works with loops.
while (!done && keep_going) //When done is false AND keep_going is true... {
DontGiveUp();
}
Leaving out the braces
This is another exception to the syntax rules in JavaScript, and sometimes a rather handy one: you can choose to leave out the braces. However, you can do this in only ONE case: when there's only one statement to make. The if-statement immediately closes after you put that finishing semicolon after your only line of code that's going to be run in the condition:
if (condition)
Statement();
if (next_condition)
OtherStatement();
Of course, you can still format this in any way you like. This can make code much more compact:
if (story == 1) Statement(); if (story == 2) SecondPart(); if (story == 3) ThirdPart(); if (story >= 4) Abort("End of the game!");
Another exception exists where you can use several statements if you like. However, this method is less compatible; a few JavaScript keywords like return and break will NOT work if you do this:
if (condition)
Statement1(), //Use a comma, not a semicolon, and you can keep feeding the thing code until a semicolon ; is encountered! story++, Statement2(); //End of the code to run for this condition.
Note that it also works with loops.
while (keep_going)
DontGiveUp();
for (var i = 0; i < 1000; i++)
TextBox("The loop has run " + i + " times now. WILL IT EVER END? Yes, at 999.");
The "else" keyword
You can connect if-statements together if you like. What if there's three related cases? Maybe var story is 1... Maybe it's 2. Maybe it's neither! You can use the else keyword to connect these three different conditions together. This offers two advantages:
To people reading the code, it's recognizable as a group of related statements;
When one condition evaluates as true, all others will automatically skip, not even bothering to evaluate. This saves processing power (your PC needs to do less).
There are two types of ways to use else:
- else if - there's a different, related condition. For example, story is 2.
- Just else - All of the previous related conditions have evaluated to false. For example, story is 6 and there's no else if that checks for it to be 6.
Basically, using just else is like defining code that will run in all other cases. else if can only exist right after an if or another else if. else can only exist once, and that is after all other related conditions.
var story = (any value)
if (story == 0)
RunStorySectionOne();
else if (story == 1)
RunSecondSection();
else if (story >= 2 && story <= 4) //If story is 2, 3 or 4
RunThirdSection();
else //Story could be 5, or 389, or -300 for all we know
Abort("That story section does not exist, fool!");
Objects
NOTE: WORK IN PROGRESS. VERY LIKELY A MESSY EXPLANATION. Please let me know if the current text is too unclear and why.
I've mentioned objects before, now we'll go into more detail about them. An object is one of the more complicated things in Sphere, but they will allow you to do very powerful things.
What is an object?
An object is a type of variable in which you can store many things - values, functions, and even more objects. However, an object is not like an array because of two main reasons: Objects use names instead of numbers for your data. These "names" are properties if you're storing data and methods if you're storing functions. Objects can have different instances.
What is an instance?
Objects are very useful for one specific thing - creating clones of itself that contain different data, and possibly different behavior. When you start making your own object, you start out by shaping the "original" object, which is called the prototype. From here on, your prototype will serve as the way to create actual, usable objects out of your prototype. These new, copied objects are what you would call an instance of that object. Instances let you have similar object - with different values.
An example of different instances
The best example to start out with is with something familiar: let us look back at Sphere's own, internal object. When you use LoadImage(), you actually create a new instance of the internal Sphere Image object. For example:
var a = LoadImage("a.png"); var b = LoadImage("b.png");
Both a and b are Image objects, but they contain different images - that is, different data.
Making your own prototype
Now, Sphere's internals use functions like LoadImage(), but this is not actually "true" object-oriented programming, and it is not how we will make our own object prototype. But in this first step, it will almost appear as if we are!
function MyObject() {
}
There you go, we just made an object prototype. What? It looks just like making a function? That's exactly right - all functions are actually objects, except we don't normally use them as such! Let's take it a step further and see what's so different about objects.
function MyObject() {
this.myproperty = 4;
}
Objects have properties. Inside properties, you store values. It's just like using var, but instead we use this. The reason for this is so we can access the value from outside the function. Not only that, but we tell Sphere that this variable-type thing is a default value that the prototype will give to each instance, after which it can be changed individually per instance. You could access the property from the outside as follows:
MyObject.myproperty
But take note! We are still making an object prototype here, so it's better to leave the prototype alone. Why? Because if you change the prototype's properties' values, new instances would take over that new value too (but old ones would still be in their original state with the old values). This can become a mess, so be careful with it. Usually you will want your prototype to be well-defined inside itself, and nowhere else.
Object prototypes can also have functions. These are copied just like values would be, which is why you could make two instances of the same type (that means, derived from the same prototype) have similarly named functions that do different thing. A function inside an object is called a method - usually because the object is made to do certain related things, and these subfunctions would be the method to manipulate its data. function MyObject() {
this.myproperty = 4; this.myMethod = function() { this.myproperty++; }
} The above added method adds 1 to our property, so every time it's called, myproperty would increase by 1. So now we're going to make an instance of the object.
Making an instance of the object
Todo.
Tutorial TODO list
- Explain try...catch and its lack of implementation in Sphere internals
- Make a glossary for all special terms (if-statement, code block, condition etc.)
- Make more tests, maybe one after each chapter?
- Include pictures?
Come back later and these thing just might be included! Don't be afraid to PM me on the forums for any suggestions, questions, improvements etc.