Saturday, May 19, 2018

Towels for Earth Postmortem

This is a postmortem for the game that I will be posting on May 25th for Towel Day which is the HTML5 port of Towels for Earth. Towels for Earth was a game that I created for a Game Jam back in 2013. The theme of the game jam was towels in honor of Douglas Adams. I suspect that there are several Douglas Adams fans who managed to encounter my Blazing Games site somehow as the polls show that there are quite a few people who wanted to see this game ported to HTML5. It is a fun but short missile defense game where missiles are destructor beams and anti-missiles are towels with the player tossing towels at destructor beams to save the Earth.



What Went Right

This was a game-jam entry so it was very quick to port over. I had a bit of time left over from what I budgeted so I decided to add some sounds to the game. The original game is in space for which there is no sound, but purists can simply turn the sound off via a nifty sound toggle that I added. The speaker artwork was taken from another game I wrote that had a sound slider but I didn’t have enough spare time to try and create a slider, but that is probably something I should be doing in the future if I ever get enough spare time, which won't be in the next couple of years.

I started going through some of the public domain and royalty free sounds that I have collected over the years to find a few sounds that would work with the game. While some people may not like my choices, I think they work well for the theme of the game. Sound in Create.js is very easy to play if the files have been downloaded which I am using preload.js to do so this was trivial to add once the sound files were found.

What Went Wrong

I went a bit overboard with the original game and had created a pixel-perfect collision detection routine. This requires the use of bitmap libraries that Create.js doesn’t have and would have been very painful to do – not to mention excruciatingly slow – to do so I reverted to good old-fashioned bounding circles. The wonderful thing about bounding circles is you just find the distance squared between two objects and see if the squared distance is within the combined radiuses. The problem is that if one of the shapes is not spherical, then the collision results can be a bit inaccurate. I don’t really mind too much but suspect that I may hear some complaints about this. I did try to be a bit generous with my circles feeling it is better to have more false positives than false negatives.

Some of you may be wondering why I am using distance squared. This is an old-school technique to save a bit of CPU cycles. Distance is sqrt( (x1-x2)^2 + (y1-y2)^2) which is a slow routine to calculate since square roots are very slow to calculate. On the other hand, radius*radius is very fast to calculate so by forgoing the square root portion of the calculation you can speed up the check while keeping the accuracy of the calculation.

Mixed Blessings

The original game used a combination of background images and vector artwork, but I opted to go with all images even though I could have saved a bit of space by using some vector images. The tradeoff of a slightly larger file size for slightly faster game rendering and a easier coding was arguably worth it. The images I did want to have as vectors were actually fairly large so it wasn’t that much space that I was using. My original plans were to have the backdrops converted into a separate jpeg file while the other parts were stored in a png file so I could get a bit better compression. When using my image view to see how different compression ratios would affect the image quality, I noticed that the images looked pretty good when converted to 8-bit png files with only a small increase in file size so I put all the images into a single image atlas.

For people who still have slow internet connections, these decisions may have resulted in longer loading times. For that I apologize as I know most people with slow internet don’t have a choice in the matter.

Conclusion

Overall, I am happy with how this game turned out. Sound does add a bit to the game, but sound and music is my Achilles heel. I really have to start trying to add more sound to my games in the future.

Saturday, May 5, 2018

State of the Site May 2018 update

With my being accepted into a Master of Science in Computer Science program I will be extremely busy for the next couple of years. I do want to keep up with my site, which is not that time consuming if I predominantly post ports of the games from Blazing Games so both this blog and my homebrewgamejam.blogspot.ca blogs will continue while I am in university. The frequency of the updates is going to be shifted from weekly to alternating between the two blogs with each having an article posted every other Saturday. If things get too hectic, I may cut back to a monthly update but am going to allocate a block of time towards the site and blogs so that things will continue unless something bad happens.

My Easter Egg generator is not really writing a postmortem for. While I did learn a bit about color filters while creating it, this is not enough to warrant a full article.

This month is seeing the release of two games. The first being the HTML 5 version of Four in a Row which is not a new port but does need to be transferred over from the Blazing Games site eventually and as towel day is so late in the month why not this month. The original version was still rough so I decided to clean up the AI a bit and to add animation to the game. There is still a lot that I would like to add to the game before I would consider it to be complete but not sure when I will find time to do that so it may be a decade before this game is properly completed.

Towel day will be the release of my Towels for Earth port. However, I will be posting the postmortem of the game before the actual release of the game. That will be the topic for next fortnight’s post after which I will start posting Chapter 4 of my Animate CC eBook.

Fleet, which I was planning on posting in June, is not quite ready. If it is not ready in time I may post a different game in it’s place but hope to have it finished. If the game is not ready by the 25th then I will go with an alternate post. Either way the site will have information about what I am going to post. If the game is delayed, it will still be worked on so will be posted later in the year. 

July's game will be released on the 13th of the month as that month has a friday the 13th. It is going to be 13^2 Spikes. August is String Along, but I may substitute it for Fleet if a delay is required.September is when CQ is finally suppose to appear but if things go as planned there may be a bit of a surprise with that release.

Saturday, April 28, 2018

3.7 Functions and Objects


Functions, which are known as methods in Java, are named blocks of code that can be called by using the name of the function. This allows you to create a block of code that can be re-used without having to duplicate the code every time it is used. Functions are defined by using the function keyword. Functions can also be given parameters. Parameters are values that the function can use. You can have a function use as many parameters as you need by separating them with commas. Functions may also optionally return a value by using the return keyword. An example of a function would be:

function square(number) {
    return number * number;
}

This function would simply return the square of the number passed to it. To use this function, you simply need to call it, like this:

x = square(2);

The parameter passed can be a variable or it can be a constant value. A constant being any value that will never change, such as the 2 above.

It is also possible to assign a function to a variable, allowing you to pass a function to a another function. In the earlier section you seen a function being created in-line to be assigned to a variable. To assign an already existing function to a variable you simply uses the function’s name without any parentheses and followed by a semi-colon.

 variable_holding_square = square;

Objects are similar to functions. Objects are essentially a combination of variables combined with the functions used to manipulate those variables. This, along with the topic of creating objects, will be covered in chapter 5. However, using existing objects is very common in JavaScript and a requirement of Create.js so we will briefly have to cover using existing objects.

While it is possible to create an empty object and add things to it to make it a unique object, more often you will be creating objects of a certain type called a class. You use a class by creating an instance of it. The variables in every instance are unique to that instance. You can, in theory, have as many instances of a class as you wish (in reality you have a limited amount of memory so you are limited to the number of instances). In fact, your movie is itself an instance of the MovieClip class.
To create an instance of a movie clip you can quite often just use Animate to drag the object (be it dynamic text, a movie clip, or a component) onto the current frame and give it an instance name using the properties panel. Some classes are not visual in nature so you have to manually create them using the new operator as follows.

variable_name = new ClassName();

Objects do take up memory. This memory will continue to be used until all references to an object have been removed. To remove an object (or at least one of the reference to the object) you use the delete keyword. All variables that are assigned to that object need to be deleted (or changed to refer to something else) before the object will be removed from memory.

delete variable_name;

To access a variable or function that belongs to an object, you use periods. An exception to this is if you are writing code within the class in that case, you refer to the object using this. Some classes, such as Math, have what is known as static methods. These are functions that can be called without having to create an instance of the object by simply using the name of the class Here are some examples.

otherMovieClip.gotoAndPlay(1);
Math.cos(angle);
otherMovieClip._x = 23;
otherMovieClip._y = 32;
this.gotoAndPlay(“labelToPlay”);

And that is all there is to basic JavaScript programming. Next chapter we will apply this knowledge to the creation of a simple Animate game.

Saturday, April 21, 2018

3.6 Arrays


Simply stated, an array is a list. The size of the list determines how many pieces of information, known as elements, can be put into it. Any part of the list can be accessed, if you know where in the list it is stored.

There are several ways of creating an instance of an array, as follows:

x = new Array();
x = [];
x = new Array(size);
x = new Array (element1, element2, ..., elementN);
x = [element1, element2, ..., elementN)];

The first two methods create an array that has no elements. While this may not seem useful, it is possible to add new elements to an array, which we will discuss later. The third method creates an array with a specific number of elements. These elements are initially empty, but new values can be assigned to them, as we will discuss later. The final two methods creates a populated array. The size of the array will depend on the number of elements that are declared, but in theory any number of elements can be specified. This type of constructor is very useful in cases when you want to have some type of table of predefined values that can be accessed.

The power of an array comes from the ability to access and modify the elements of the array. Elements of an array have an index number associated with them. The first element of an array is referenced with the number 0, the second is 1, and so on. Some people find using element 0 confusing, so will simply ignore that element and start storing stuff in element 1. If you are going to do this, remember that the last element of an array is one less than the size of the array.

To access the element, you simply use the array variable's name, followed by the index number in square brackets. The index does not have to be a number, but can be a variable that contains the index number. For example, the following program adds the third and fourth elements (index values 2 and 3) and places the result in the first (index 0) element.

index = 3;
list = new Array(0, 1, 2, 3, 4, 5);
result = list[2] + list[index];
list[0] = result;

The Array class has functions for modifying and getting information about the array. It also has a read-only property variable named length that holds the current length of the array. Action Script allows you to change the size of the array at any time. Many other programming languages are not quite as flexible. The Action Script Dictionary that is included with Macromedia Flash covers these functions in detail.

Now we come to a rather interesting additional for statement that is included with Action Script, the for..in statement. This is what is known as an iterative for function. It is used to iterate through all the variables of the indicated object. The format for this command is for (variable_holding_index in object) The variable_holding_index is simply the name of the variable that holds the index. Here is a sample to illustrate how this can be used.

var cntr;
testArray = new Array("A", "B", "C", "D");
for (cntr in testArray) {
console.log("Element " + cntr + " is " + testArray[cntr]);
}

Saturday, April 14, 2018

3.5 Looping

Looping is a very common programming task. A loop is essentially a block of code that executes until certain conditions are met. JavaScript supports three types of looping statements. The while statement, the do ... while statement, and the for statement. The first two types of loops are very similar so we will look at them together.

The While statement always has a statement or block of statements tied to it. The condition of the while statement is tested. If the condition is true then the statement or block of code gets executed. When the block of code is finished executing the while statement condition is tested again. If it is still true, the statement or block gets executed again. This continues until the condition is false, at which point the program continues execution on the line after the statement of block of statements. Here is a use of the while statement to see how long an object will fall before hitting the ground.

var distRemain = meters_to_fall;
var vel = 0;
var time = 0;
while (distRemain > 0) {
     vel += 9.8;
     distRemain -= vel;
     ++time;
}

One thing that starting programmers must watch out for is the infinite loop. This is a loop that will never end, meaning that the program is stuck until stopped by the user. Most web browsers will only let loops run a certain amount of time before brining up a dialog box telling the user about the problem and letting the user cancel the script.

The problem with the while loop is that it’s possible that the statement or block after the while statement will never be executed. Sometimes you always want the statement or block to be executed at least once. This is what the do ... while statement does. In this example we want to find the length of time an object will decay rounded up to the nearest half life interval. A half life is the length of time a decaying object takes to be reduced to half of it’s original mass.

var life = startinglife;
var duration = 0;
do {
     life /= 2;
     ++duration;
} while (life > 1);
console.log ("Lifespan of object is " + (duration * halflife));

The most common type of loop in programming is the for loop. The purpose of this type of loop is to count through a series of numbers. The format of the for statement is:
for (start_condition; end_condition; increment){ /*loop action*/ }

The start condition starts the variable that will be counting to it's initial value. This will generally be 0 or 1, but can be any value. If there is no need to initialize a variable, you can skip this part of the statement by simply having the semicolon. I would consider having a /*none*/ comment before the semi-colon so you know that there is no loop initialization.

The end condition is simply a boolean statement like you would use with an if statement. The loop continues until this condition is no longer true. The condition can be any boolean condition, and could even consist of a function call.

The increment portion is where the counting variable is changed. It is called at the end of every loop iteration. Generally you will be increasing the counter by 1, but it is valid to decrease the counter, or do any other mathematical operation or call any function you wish. The following sample will add the numbers 1 to 10 together.

var cntr, value = 0;
for (cntr = 1; cntr <= 10; ++cntr) {
 value += cntr;
}

The for statement seems complex. When you get right down to it, the for statement is really a macro statement that makes a while loop behave as a counter. One way of better understanding a for loop is to look at the loop as a while loop. By doing this, you will see what the three parts inside the for loop really do. Here is the above example as a while loop.

var cntr, value = 0;
cntr = 1; // the start condition
while(cntr <= 10) // the end condition {
    value += cntr; // the loop action   
     ++cntr; // the increment
}

Repeating things a set number of times is important, but where for loops tend to be used the most is with arrays and objects so we will continue our discussion as part of our look at arrays and objects.

Saturday, April 7, 2018

The Switch Statement


The Switch statement is a convenient way of handling situations where you need to handle many actions based on the value of a variable. The Switch statement starts of with the switch statement which contains an expression that should evaluate into a number. After the switch statement is a block of code which consists of case statements and an optional default statement.

switch (number)
{
     case 1:
           console.log("The number is one");
           break;
     case 2:
           console.log("The number is two");
           break;
     case 3:
           console.log("The number is three");
           break;
     default:
           console.log("The number is not one, two or three");
}

After each of the case statements is the code you want to execute if the variable being switched equals the value of the case. The code should end with a break statement, which causes the program to skip over the rest of the switch block. If there is no break statement, all code in the following case statement will also be executed. In some cases, this is exactly what you want to happen, as it allows you to define a group of numbers that all do the same action. Forgetting the break statement is a very common mistake for beginners to make and is even something that experts have made resulting in devastating results.

The default statement will be executed if none of the case statements match the value of the switch expression. No break statement is needed after the default code, though I usually do have a break statement out of habit. While the default statement is optional, it is a good habit to always have a default action, even if the default is simply a trace statement telling you that you have reached code that should not be reached.

The switch statement we have above could be done with if statements as you can see below.

if (number == 1) {
    console.log("The number is one");
} else if (number == 2) {
    console.log("The number is two");
} else if (number == 3) {
    console.log("The number is three");
} else {   
     console.log("The number is not one, two or three");
}

The choice between using switch and if statements is more of a cosmetic one with JavaScript. Switch statements are a convenience statement designed to replace large numbers of if then else statements in a more readable way.

The switch statement comes directly from the C programming language. While I am a fan of that language, being one of the first programming languages that I learned, I have been bitten by the switch statement too many times and have uncovered bugs in other people’s code due to the forgetting of a break statement frequently. Therefore, I am happy that new languages are replacing the default fall-through behavior with default break behavior requiring a statement to fall through.

Another common bug with the switch statement is not having a default block when a case does not cover all possibilities. The result of not having a default is essentially a default that does nothing which may be what you want. It could also be an indication that you expect only the values in the case to exist. Having a default that reports an error if it is reached is recommended in this situation.

Saturday, March 31, 2018

3.3 The IF statement

One reason for having a scripting language is to be able to control the flow of a movie. Controlling something requires making decisions. This is what the if statement does. The if statement uses the following format:

if (condition)
     statement_to_perform_if_condition_is_true
else
     statement_to_perform_if_condition_is_false

The else part of the if statement is optional. If you wish to have more than one statement after the if or the else, you should place the block of statements into a pair of curly braces {}. Curly braces indicate a block of code so can be used anywhere that a single statement is expected in order to run a block of statements.  Here is an example.

 if (x == 1)  {   
     console.log("x is assigned a value of 1");
     y = 23;
}

The condition is simply a mathematical condition, but two equal signs are used together to indicate equals while a != combination is used for not equal. The greater than and less than symbols (<, <=, >, >=) can also be used. Be careful not to use a single equals in a condition as this will assign that value to the variable which can lead to hard to track bugs. Many languages, such as Pascal, use equals for equality and use something else (:= in Pascal) for assignment.

Conditions can be combined to form more complex conditions. This is done by placing each condition in it's own set of brackets and then placing an and (&&) or an or (||) symbol between them.
The and (&&) operation means that both conditions must be true if the condition is to be true. If either or both conditions are false then the condition is false. For example, to make sure a player is in the bounds of a 100x100 square they must be within all four sides. We may have the following code to check this:

if   (
(playerX >= 0) &&
(playerX < 100) &&
(playerY >= 0) &&
(playerY < 100)
)
     console.log("Player is within the bounds");

Note that the range for the square is 0 through 99 inclusive. This is a programmer thing that makes a lot of sense once you start doing a lot of programming but can be confusing for non-programmers. This makes even more sense when you do machine language programming. If you are interested in machine language, you can learn about it from my HomeBrewGameJam blog where I am writing a 6502 emulator for use in an Atari 2600 emulator and later a NES emulator.

The or (||) operation just requires that one of the conditions is true, though both conditions being true is also acceptable. For example, to check if something is not within the bounds of a square we can check to see if any of the bounds have been violated with the following code:

if   (
(playerX < 0) ||
(playerX >= 100) ||
(playerY < 0) ||
(playerY >= 100)
)
     console.log("Player is outside of the bounds");

It is also possible to assign a condition result to a Boolean variable which can be useful if you have to check the results of some condition multiple times. To demonstrate this, the inside box check could be written as follows:

if   (
(playerX >= 0) &&
(playerX < 100) &&
(playerY >= 0) &&
(playerY < 100)
)
     console.log("Player is within the bounds");
if (inBox)
     console.log("Player is within the bounds");

The statement or block that follows an if statement can itself contain if statements. This is known as nested if statements.