DaVince scripting tutorial/Conditions and loops
From Spheriki
Contents |
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.