JavaScript Basics
As we said in Chapter 1, enchant.js is written in the JavaScript programming language. When you program games in enchant.js, you’ll write commands and other code in the JavaScript language, so we need to examine simple JavaScript before diving headfirst into enchant.js games. If you are already familiar with JavaScript, feel free to skip this chapter.
JavaScript is the primary programming language used for scripting on web pages. Unlike most programming languages used to create software applications that must be installed on computers to function, JavaScript code runs on the client web browser. Given that enchant.js and games written using enchant.js are created using JavaScript, it is imperative to understand the fundamental concepts of JavaScript. If you are new to programming, learning these fundamentals will benefit you immensely, as they happen to also be the building blocks of object-oriented languages and are a useful starting point from which to learn other popular programming languages, such as Java and C++.
The grammar of a programming language, or rather, the specific way elements of the language are written, is called syntax. In this chapter, you learn the building blocks of JavaScript, their syntax, and their functions by writing code on the code.9leap.net web site. We’ll take you step-by-step through the process and explain each of these building blocks through a series of simple code projects.
Summary List
In this chapter, we’ll show you how to do the following:
Declare a Variable
Variables are containers for values and in most cases can be updated at any time with a new value, hence their name. Their values “vary,” so they are “variable.” The benefit of using variables over explicit values is due to the dynamic nature of a variable. If you include a variable in a calculation, and then later change the value of that variable, the next time you perform the same calculation the new value will be used.
To use a variable, you must first declare it with the var statement, which tells the application to reserve a spot in memory for the variable. At the end of any single statement in JavaScript, you must include a semicolon (;).
To declare three variables with the names num0, num1, and sum, do the following:
Listing 2-1. Declaring a Variable
var num0;
var num1;
var sum;
You can use the following characters in variable names:
Table 2-1 shows reserved words in JavaScript that cannot be used as variable names.
Table 2-1. Reserved Words in JavaScript
Table 2-2 shows words that currently are not used, but have a high probability of being used in the future. We recommend avoiding them when naming your variables.
Table 2-2. Words Reserved for Future Use
You cannot use any other word that is predefined for use in JavaScript, such as String, true, and so on. For a complete list, please see www.javascripter.net/faq/reserved.htm.
Once a variable has been declared, a value can be assigned to it. To assign values to num0 and num1, do the following:
Listing 2-2. Assigning Values to Variables
num0 = 100;
num1 = 200;
Note Variables can be declared and assigned a value at the same time by using
var num3 = 400;
Add Variables
Variables can be used in place of numbers for arithmetic. A variable’s current value will be used for the calculation if arithmetic is performed using a variable. To add num0 and num1 and assign the result to sum, do the following:
Listing 2-3. Adding Variables
sum = num0 + num1;
Basic Arithmetic Operators
You are not limited to just adding variables or numbers. All the basic arithmetic operations can be performed. Table 2-3 shows the basic operators.
Table 2-3. Basic Arithmetic Operators
Operator | Description | Example |
---|---|---|
+ | Addition | a + b (add a and b) |
– | Subtraction | a – b (subtract b from a) |
* | Multiplication | a * b (multiply a and b) |
/ | Division | a / b (divide a by b) |
% | Remainder | a % b (the remainder of a divided by b. In other words, 7 % 4 = 3 because 4 goes into 7 one time, with a remainder of three.) |
The operators possess a priority: multiplication and division take place first, before addition and subtraction. To change the order of precedence, which might be useful if you want to calculate specific sections of a calculation before others, use parentheses, as seen in Listing 2-4. You do not need to copy this code. It is just for reference.
Listing 2-4. Changing the Order of Operations with Parentheses
var result0 = 1 + 2 * 3; //result0 will be 7
var result1 = (1 + 2) * 3; //result1 will be 9
To see the value of sum, do the following:
Listing 2-5. Displaying the Value of Sum on the Screen
document.write("Total amount = " + sum);
If you would like to check your code against a finished example, you can find one at http://code.9leap.net/codes/show/19823.
Why do we have to put quotes around what we place inside of document.write() in Listing 2-5? This is because document.write() accepts only values that are a string. A string, used to store strings of text characters, is one of the five basic, or primitive, data types in JavaScript. Three of those data types-number, string, and Boolean-are used to store data, while the other two are used to designate the current state of a variable. Table 2-4 shows the five data types.
Table 2-4. Basic Data Types
Type | Assigned Value | Usage Example |
---|---|---|
Number | Base 10 | var num = 10; |
Base 8 (0 appended to beginning of value) | var num = 011; | |
Base 16 (0x appended to beginning of value) | var num = 0x9A; | |
Floating point, base 10 (using a period [.]) | var fnum = 3.1415; | |
Floating point, exponent (using a period[.] and E) | var fnum = -3.1E12; | |
Boolean | true or false | var flag = true; |
String | String surrounded by double or single quotations | var str = “character string”; |
var str = ‘character string’; | ||
null | The object is known to exist, but has no value | var obj = null; |
undefined | The object does not exist, does not return a value, or has not been initialized |
In addition to the basic data types, there are complex data types in JavaScript:
We’ll cover the complex data types in more detail later.
Note In programming languages like C/C++ and Java, variables have static data types (such as integer or string), and you cannot assign a value of one data type to a variable of a different data type. In other words, if you have an integer variable, you cannot assign a string of characters to that variable.
In JavaScript, this is not the case. A value of any data type can be assigned to a variable, and a variable of a completely different data type can later be reassigned to the same variable. A variable of name foo could be assigned a number value with foo = 10; and then the very next line could state foo = "bar"; to assign a string value to the same variable. This flexibility is a major benefit in JavaScript, but the drawback is that sometimes you have to take extra care when performing calculations. We’ll see examples of this later on.
Manipulate a Variable Using Itself
Many games contain a score that is constantly updated when a player gets points. To update this score, the variable containing it must be increased. Do the following to see how:
Listing 2-6. Manipulating a Variable by Referencing Itself
var score = 10;
score = score + 20;
document.write(score);
Compound Assignment Operators
Compound assignment operators are operators that perform a value assignment to a variable along with another operation simultaneously. Table 2-5 shows these useful operators.
Table 2-5. Compound Assignment Operators
Operator | Description | Example |
---|---|---|
+= | Addition | a += 10 (equivalent to a = a + 10) |
–= | Subtraction | a –= 10 (equivalent to a = a – 10) |
*= | Multiplication | a *= 10 (equivalent to a = a * 10) |
/= | Division | a /= 10 (equivalent to a = a / 10) |
%= | Remainder | a %= 10 (equivalent to a = a % 10) |
Manipulate a Variable Using Incrementation
When a variable needs to be increased by a value of 1, an even more abbreviated operator can be used. Do the following to see it in action:
Listing 2-7. Declaring and Incrementing a Variable
var num = 1;
num++;
document.write(num);
Listing 2-8. Incrementing a Variable within a Statement
var num = 1;
document.write(num++);
num = 1;
document.write(++num);
Note The opposite of the increment operator is the decrement operator (--). The decrement operator works in the exact same way as the increment operator, except that it subtracts one from whichever variable it is attached to.
Compare a Variable
JavaScript contains commands called relational operators that compare two values and return a Boolean value of true or false, depending on the result. Do the following to see them in action:
Listing 2-9. Comparing Values
var num0 = 4;
var num1 = 7;
document.write(num0 >= num1);
document.write(num0 < num1);
document.write(num0 === num1);
Table 2-6 shows the useable relational operators.
Table 2-6. Relational Operators
Operator | Description | Example |
---|---|---|
== | Equivalent | a == b |
=== | Strictly equivalent | a === b |
!= | Inequivalent | a != b |
!== | Strictly inequivalent | a !== b |
> | Greater than | a > b |
>= | Greater than or equal to | a >= b |
< | Less than | a < b |
<= | Less than or equal to | a <= b |
See How Similar Two Values Can Be
See how the equivalent (==) and strictly equivalent (===) relational operators differ by doing the following:
Listing 2-10. Differing Equivalent Operators
var num0 = 4;
var num1 = "4";
document.write(num0 == num1);
document.write(num0 === num1);
Note The opposite of the equivalent operators are the inequivalent operators (!= and !==), which perform almost the exact same operation. However, the != operator performs type conversion and the !== operator does not.
Manipulate a Comparison
Sometimes you’ll want to manipulate how a comparison resolves (true/false). To see how these comparisons can be manipulated, do the following:
Listing 2-11. Manipulating Comparisons
document.write(!(4 > 3));
document.write((4 < 7) && (5 < 13));
document.write((4 > 5) || (4 < 5));
The screen will first say false because the statement (4 > 3) resolves to true, and the ! logical operator reverses the Boolean statement (true/false) after it, making it false. The screen then lists true because both (4 < 7) and (5 < 13) evaluate to true. The && (and) logical operator returns true only if both statements around it are true. Finally, the screen shows true again, because out of (4 > 5) and (4 < 5), one of them is true. The || (or) operator resolves as true if at least one of the statements is true. Table 2-7 shows the logical operators.
Table 2-7. Logical Operators
Operator | Description | Example |
---|---|---|
! | false if a is true, true if a is false | !a |
&& | true if both a and b are true, otherwise false | a&&b |
|| | true if a or b is true, otherwise false | a||b |
Implement Logic with the If Statement
Sometimes we want to perform specific actions in our code if and only if a certain condition is met. Do the following to see how:
Listing 2-12. Implementing Logic with the If Statement
var num0 = 4;
var num1 = 8;
if (num0 >= num1) {
document.write(num0 + " is greater than or equal to " + num1 + ".");
}
else if (num0 < num1) {
document.write(num0 + " is less than " + num1 + ".");
}
An object is a structure that can contain its own variables (called properties), and methods. These are called instance properties and instance methods when they belong to an object. To create an object that will enable you to get the current date, do the following:
Listing 2-13. Creating the Date Object
var date = new Date();
Listing 2-14. Assigning Date Information to Variables
var y = date.getFullYear();
var m = date.getMonth() + 1;
var d = date.getDate();
Table 2-8. Methods of the Date Object
Method | Effect | Return Value |
---|---|---|
getFullYear() | Returns the four-digit Gregorian calendar year | {Number} 4-digit Gregorian calendar year |
getMonth() | Returns the month - 1 (this is because it is an array reference) | {Number} Month - 1 |
getDate() | Returns the day | {Number} Day |
getDay() | Returns the day of the week | {Number} Day of the week |
getHours() | Returns the hour | {Number} Hour |
getMinutes() | Returns the minute | {Number} Minute |
getSeconds() | Returns the second | {Number} Second |
getMilliseconds() | Returns the millisecond | {Number} Millisecond |
Listing 2-15. Creating a String and Displaying It
var text = "The date is " + m + "/" + d + "/" + y;
document.write(text);
The Date object is just one of the many objects that come predefined with JavaScript. Table 2-9 contains some of the main objects bundled with JavaScript.
Table 2-9. Main Objects Included with JavaScript
Object Name | Object Description |
---|---|
window | Browser window |
document | Web page in a browser |
frame | Frame within a web page |
history | Browser history |
location | Current page location |
anchor | HTML hyperlink |
applet | Embedded program in a web page |
area | Clickable area on an image |
form | Web form |
image | Image on a web page |
layer | Layers for transparent elements |
link | Link to external style resource |
button | Clickable button |
checkbox | Markable check box |
fileupload | Dialog box for file upload |
hidden | Conceals passwords |
password | Accepts a password |
radio | Markable radio button |
reset | Clears choices in a form |
text | Single line of text |
linkarea | Text area |
select | Selection on a drop-down menu |
Array | Array of values |
Boolean | Boolean value (true/false) |
Date | Stores a date |
Event | Occurs with an event (such as a click) |
Function | Function (method) |
Math | Numerical calculations |
Navigator | Browser information |
Number | Stores a number |
Object | Stores code elements |
RegExp | Regular expression |
String | String of characters |
This large list of objects might seem daunting at first, but it’s only meant as a quick reference. If you’d like to learn more, see the section on “Predefined Core Objects” in the Mozilla Developer Network’s JavaScript guide at https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Predefined_Core_Objects. It’s a great resource on the basic core objects of JavaScript and their uses.
Note If you are familiar with object-oriented languages such as C/C++ or Java, you might be familiar with the concept of class. In these languages, classes act as predefined templates for objects. Properties and methods can be defined for a given class, and then all objects created from that class will inherit those properties and methods.
In JavaScript, the concept of class technically does not exist and is replaced by the concept of prototypes. A prototype is a specially designated object for which properties and methods can be defined. When new objects are created, they can be created from a prototype and will have the same properties and methods of that prototype.
The concept of class and prototype might seem similar at first, but they are different in their restrictions. We will not discuss class-based vs. prototype-based programming in detail, but the main difference is objects created from prototypes can override predefined prototype functions with their own function definitions, while objects created as part of a class are generally unable to do so.
Work Smarter with the While and For Loop Statements
Repetition makes your coding life easier because there are many cases where a program can be easily engineered to perform repetitive tasks for you. Let’s imagine we need to devise a way to add together all the numbers between 1 and 1000 and assign that value to a variable (int). If we were to manually add every single number between 1 and 100, we’d end up with code that would look something like the code in Listing 2-16.
Listing 2-16. An Impractical Way to Add Sequential Numbers
int num = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100;
Ouch. That doesn’t look like a very practical way to spend your time, does it? To speed things up, we can use loop statements to perform this repetitive calculation for us. To see this in action, do the following steps:
Listing 2-17. Creating Variables
var i;
var sumFor;
var sumWhile;
Listing 2-18. The While Loop
sumWhile = 0;
i = 1;
while (i <= 100) {
sumWhile += i;
i++;
}
document.write("The result using a while loop: " + sumWhile + "<BR />");
Note The “<BR />” in the document.write() method is an HTML tag (the name of an HTML element surrounded by brackets, specifying an element of a web page to be inserted) that tells the system to move down a line before displaying more text.
Listing 2-19. The For Loop
sumFor = 0;
for (i = 1; i <= 100; i++) {
sumFor += i;
}
document.write("The result using a for loop: " + sumFor + "<BR />");
Tip If a for statement has only one command, as does the one in Listing 2-19, the curly braces are not necessary. For instance, the for loop in the listing could be rewritten as
for (i = 1; i <= 1000; i++) sumFor = sumFor + i;
Interrupt a Loop with Break
Occasionally, in the middle of a loop’s execution, we want to stop the processing of the code in that loop and continue processing code past the end of the loop. This is easily accomplished with the break statement, which breaks the current processing out of the loop, even if the loop’s condition is still fulfilled. To see it in action, do the following:
Listing 2-20. Breaking Out of a Loop
var sumWhile = 0;
var i = 1;
while (true) {
sumWhile += i;
i++;
if (i > 100) break;
}
document.write(sumWhile);
Skip a Loop Iteration with Continue
On other occasions, you might want to skip the remaining code in a loop and start it again. As long as the conditional expression of a for or while loop is fulfilled, this can be done with the continue statement. When this statement is issued, the next iteration of the loop’s code is immediately started. As usual in a for loop, when returning to the beginning of the loop code, the increment/decrement expression of the for loop get executed. Do the following steps to try this out by making a program that calculates only the even numbers from 0 to 100:
Listing 2-21. Using Continue to Skip Odd Numbers
var sumFor = 0;
for (i = 1; i <= 100; i++) {
if (i % 2 != 0) continue;
sumFor = sumFor + i;
}
document.write("The sum of all even numbers up to 100 is " + sumFor);
Generate Random Numbers
If you want enemy characters to appear randomly in your game or if you want to create a game that tells you your fortune for the day and randomly assigns you a “luckiness” value, you need to be able to create random numbers. Do the following to see how it works for a fortune-telling game:
Listing 2-22. Creating Variables for the Fortune-Telling Game
var num;
var text = "";
num = Math.floor(Math.random() * 4);
Math.random() returns a value from 0 (inclusive) up to 1 (exclusive – not including 1). By multiplying this by 4, you get a value from 0 up to, but not including, 4. The floor() method of the Math object rounds down whatever is in its parentheses. Thus, the code you just wrote will return 0, 1, 2, or 3, randomly.
Listing 2-23. Fortune Telling with the If Statement
if (num===0) {
text = "Super Lucky";
} else if (num===1) {
text = "So-so Luck";
} else if (num===2) {
text = "Minor Luck";
} else {
text = "Bad Luck";
}
document.write("Your fortune: " + text);
Here, you are assigning a value to text depending on the value of num and then outputting the result.
Define Scenarios with Switch
In the last code example, several if statements were used to determine what value should have been assigned to text. However, there is an easier way to make this work, without all the if statements. Do the following to see how:
Listing 2-24. Setting Up for the Switch Example
var num;
var text = "";
num = Math.floor(Math.random() * 4);
Listing 2-25. The Fortune-Telling Switch Statement
switch (num) {
case 0:
textSwitch = "Excellent Luck";
break;
case 1:
textSwitch = "Moderate Luck";
break;
case 2:
textSwitch = "Small Luck";
break;
default:
textSwitch = "Bad Luck";
break;
}
The switch statement takes whatever value is in its parenthesis, finds the case that matches that number, and then executes the code beneath it. If there is no break statement in the current case, the switch statement will continue executing code from the next case and so on, until either a break statement is encountered or the end of the switch statement is reached. The default case is executed if no matches are found.
Store Numbered Data in an Array
Arrays are used to keep track of sets of data, which are necessary when dealing with maps, strings (arrays of text characters), and more. Do the following to see how a set of numerically indexed (numbered) data can be created in an array:
Listing 2-26. Creating an Array of Devices
var array = new Array(3);
array[0] = "iPhone";
array[1] = "Android";
array[2] = "Computer";
Just like when we created an instance of the Date object, you use a constructor to create an array (new Array(3)). The Array(3) tells the program to create an array with 3 spaces.
Listing 2-27. Iterating Through an Array
var text = "";
for (var i = 0; i < array.length; i++) {
text += array[i] + "<BR />";
}
document.write(text);
Notice how the compound assignment operator += can be used to add characters to the end of a string. Using a for loop allows you to go through all of the elements in an array automatically.
Note You do not need to specify the array to be larger to add more items to the array. For example, typing in array[3]="iPad"; in the example above will not cause an error.
Methods of the Array Object
In the previous example you created an array object. That object comes with several methods that can be executed on it. For instance, if you were to type in array.push("Galaxy"); at the end of your code, it would have added “Galaxy” to the array at whichever position was after the last item in the array. Table 2-10 provides a summary of the array object methods.
Table 2-10. Methods of the Array Object
Category | Code | Effect |
---|---|---|
Add Elements | push(element) | Adds an element to the end of the array. |
unshift(element) | Adds an element to the beginning of the array. | |
Remove Elements | pop() | Removes the element at the end of the array. |
shift() | Removes the element at the beginning of the array. | |
Sort Elements | sort() | Sorts the elements of the array in ascending order. |
reverse() | Sorts the elements of the array in reverse order. | |
Extract Elements | slice(start,end) | Extracts the elements within a specified start and end position and creates a new array with them. |
slice(start) | Extracts the elements from a specified starting position to the end of the array and creates a new array with them. |
Store Non-Numbered Data in an Associative Array
What if you want to store a color for each of the devices in the array you just made? To do this, you need to use an associative array instead of a regular array. Do the following to make an associative array:
Listing 2-28. Creating an Associative Array
var obj = new Object();
obj["iPhone"] = "White";
obj["Android"] = "Black";
obj["Computer"] = "Silver";
Associative arrays are not stored as array objects in JavaScript because all array objects are indexed, containing one key value (starting from 0) and one paired value for each entity in the array. Here, we use the ability of objects in JavaScript to be an array of values to link together the strings of device names and colors.
Listing 2-29. Manually Iterating Through the Associative Array
var textObj = "";
textObj += "The iPhone is " + obj["iPhone"] + ".<BR />";
textObj += "The Android is " + obj["Android"] + ".<BR />";
textObj += "The Computer is " + obj["Computer"] + ".<BR />";
document.write(textObj);
Because object arrays are not indexed in the same way as standard arrays, they cannot be iterated through with a simple for loop.
Save Time with Functions
You’ve seen objects that come with their own functions such as arrays, but if you’re planning on doing almost anything that requires you to type the same code multiple times, you can define your own functions to save you time. Do the following to see how:
Listing 2-30. Defining the buy() Function
function buy(device) {
document.write("I will buy the " + device + ".<BR />");
}
Listing 2-31. Calling the Function
buy("iPhone");
buy("Android");
See Where Variables Live
I want you to imagine for a moment that a program you’re going to write takes place in a medieval kingdom, with several villages and one castle. For explanatory purposes, imagine the king of this kingdom is named Bob. Throughout the kingdom, if someone talks about Bob, everyone knows that they are talking about the king. However, what if, in a given village, there is also someone else named Bob? Inside that village, people might refer to the local resident Bob as “our Bob,” but in the castle if someone refers to “Bob” it’s likely everyone will assume the person in question is the king.
This is, in essence, the concept of scope. It refers to the visibility of a variable within a program. In other words, scope is the context for a variable. To see how this works, do the following:
Listing 2-32. Making King Bob
var bob = 39;
Listing 2-33. Creating a Function to Create a Random Bob
function villager() {
var bob = Math.floor(Math.random() * 50 + 10);
this.bob += 1;
document.write("King Bob's age is " + bob + ".<BR />");
document.write("Villager Bob, this Bob, is " + this.bob + ".");
}
Notice that when you refer to the Bob inside a function, you use this.bob to specify you mean the one inside the function. To explain the visibility of villager Bob, we say he has function scope, instead of global scope like King Bob.
Listing 2-34. Calling the Villager Function
Villager();
Note You cannot reference variables created within a function outside of that function. This is the limitation of function scope. For example, we could not type this.bob outside the function to refer to villager Bob. Outside of villager(), the only Bob we can see or interact with is King Bob.
Make Object Blueprints with Prototypes
Prototypes essentially are a set of blueprints that can be used to create objects. By creating a prototype with properties and methods, we can easily create new objects equipped with the same properties and methods specified in the prototype. To create and use a software prototype that contains a name and a programming language, do the following:
Listing 2-35. Creating the Prototype and Properties
function Software() {
}
Software.prototype.name = "";
Software.prototype.language = "";
Listing 2-36. Creating The Prototype Function
Software.prototype.output = function() {
document.write(this.name + " is written in " + this.language + "<BR />");
};
Listing 2-37. Creating the Accounting Object
var accounting = new Software();
accounting.name = "Spreadsheet Master";
accounting.language = "Java";
accounting.output();
Note Using the preceding code as an example, with accounting as the name of an object, you can add properties at any time to this object by typing something like accounting.secondLanguage = "C++";. Here, secondLanguage has not been declared with var or anything before. It is an on-the-fly declaration. Functions can also be added to the object in a similar manner with accounting.showLanguage = function() {document.write(this.language)};.
Conclusion
Congratulations! If you’ve read through this section and worked with the example code on code.9leap.net, you should now have an understanding of variables, operators, strings, arrays, functions, and prototypes. These are the building blocks of JavaScript as well as many object-oriented languages in current use today. Understanding these basics gives you the foundation you need to learn how to code your own HTML5 games in enchant.js.
In Chapter 3, we delve into the enchant.js library and learn about sprites, scenes, labels, surfaces, and more. These are the basic features that enchant.js provides. As we progress through Chapter 3 and on into Chapter 4, you’ll begin to see how these features come together into creating a game.
18.220.201.187