Saturday, December 1, 2018

C5.1 Namespaces

When you are writing small programs you may never run into the namespace problem. Once you start using libraries, especially if you use multiple libraries, the namespace problem comes into play. Let us say you had a library that had a function for displaying hello. This library is called namespaceIssue.js and may look something like this:

message = "Hello!"
function sayHello() {
return message
}

Now lets say you wrote the following page that uses the library:

<!DOCTYPE html>

Namespace issue demo


Namespace issue demo









You would expect this program to display the words hello and goodbye. This is not what happens. Instead, it displays goodbye twice. Why? The library used the variable message to store the message that the sayHello function would display. The script in the html file uses message to store the goodbye message to display. It overwrites the variable which the library was using. For a small program like this it is a trivial problem to solve, but when the size of your program increases, especially if you are using code provided by third parties, this problem of variable (and function name) collision becomes a huge problem.

The solution to this problem is namespaces. The idea here is that you have a unique namespace for your program and all the variables for that program go into that namespace. Since each namespace is separate, you can have the same variable name in each of the namespaces without any conflict. In JavaScript, namespaces are created by creating a object with the name of the namespace. Here is the demo above re-written to use namespaces.

namespceUsed = {}
namespceUsed.message = "Hello World!"

function sayHello() {
return namespceUsed.message
}

It is possible to nest namespaces by having another namespace object as part of a namespace object. This is very commonly done to have library namespaces stored under a single unique namespace that you have control of. The convention is to use your domain as the unique name with appropriate names for the libraries under that domain. Some companies will take this a step further by having the root domain as the first namespace object, followed by their domain, followed by their library. This leads to the problem of declaring a namespace without overwriting other namespaces. The solution is to use the following way of declaring a namespace:

com = com || {}com.spelchan = com.spelchan || {}

It is a good habit to use namespaces for any script that you are loading. I generally don’t bother with the com root namespace but if Spelchan was a more common word, then it may be a good idea. 


Saturday, November 17, 2018

Chapter 5 Overview

Object Oriented programming has become the predominant way of developing software today. While there are some people who believe that object-oriented programming (OOP) is a misstep, there are also people who quite dogmatic about OOP. Both of the Universities I have attended tend to favor the OOP approach but there is starting to be a look at the alternatives to OOP, with functional programming gaining traction. I am a bit more flexible when it comes to programming believing that methodologies, like languages, are tools and one should try and use the appropriate tool for the problem they are dealing with.

Object Oriented approaches are so common, however, that no matter what your stance on OOP is, you should at least be familiar with the concepts behind it. This section of the book takes a look at the core OOP features that JavaScript supports. Unfortunately, like a lot of things about JavaScript, things are not as straightforward as they should be. While JavaScript has always had support for Objects, the language itself did not explicitly support OOP constructs until the ECMAScript 6 standard was released. This means that older browsers do not support the new language keywords but there are a shrinking number of people who use those browsers. It also means that there is a lot of legacy code out there that does OOP the hard way. These techniques are still valid so it is wise to at least be familiar with them.

In this chapter we will look at a number of OOP related concepts looking at what the idea behind the concept is, how ECMAScript 6 supports that concept, and the "old" way of handling the concept.

To start with, in the "NameSpace" section we will be looking at the name space problem and how to get around it. Even if you are not into the other OOP concepts, name spaces are something that ALL non-trivial programs should use.

It goes without saying that objects are important to object-oriented programming so we will then revisit creating objects in "Creating Objects". This will be followed by "Constructing Classes". Classes are what most OOP languages use to define objects with a class keyword being something that was missing from JavaScript until the ECMAScript 6 standard was released.

One of the more powerful, albeit over-abused, features of object oriented programming is the use of inheritance. This allows you to create new classes based off of existing classes without needing to write most of the functionality and will explained in the "Inheritance" section. Polymorphism is how OOP languages take advantage of inheritance by letting you use a child class in place of a parent class. JavaScipt uses a variant of polymorphism known as Duck Typing which gives you a lot of flexibility and power but has some downsides. These issues will be covered in "Polymorphism and Duck Typing".

JavaScript handles classes a bit different from most other object oriented languages. This leads to a strange issue when trying to use an objects function as a call-back. This issue can be solved using something known as binding, which we will explain in a section strangely named "Binding".

What allows JavaScript to bind functions actually is a very powerful construct known as a closure. Closures are a bit confusing and you may not want to use them in your programs, but they are an important JavaScript technique so I will be covering them in the "Closures" section.

And that should cover all the object oriented JavaScript knowledge that you will need for the remainder of this book.

Saturday, November 3, 2018

Coffee Quest Trilogy Plans

The Coffee Quest (CQ) series started off as an attempt to create a web-based role-playing game using the then-new Java programming language. Java, while a very successful language in many areas, failed in the browser and has been replaced by JavaScript using HTML5 components and CSS3 style sheets. This tends to be collectively called HTML5. My original plans for porting to HTML5 was to simply use an engine that supported HTML5  and finally get around to getting my CQFS engine working by building off the back of another engine. I started experimenting with the Unity engine but really do not like that engine. Then I remembered that for a game jam I participated in back in 2012 that I started working on a FPS version of Coffee Quest. That existing work, while still in an early development stage, would be perfect for the first three games in the series so I decided I would do a Coffee Quest Trilogy game that would combine the first three games into a single package. As this game is developed, the individual episodes will be released on Spelchan.com giving visitors to my site early access to the game.


The enhanced HTML5 version of the game will be mixed-time combining both real-time and turn-based play. I may make the option of an FPS mode where the game would be fully real-time. Each game in the series will have multiple episodes to reflect the different maps, and possibly a number of new maps, that will be made available. I have not decided if in the final game to lock the maps and require players finish other maps to unlock additional maps or if to make everything accessible. A third option would be to have all the Coffee Quest 1 maps initially unlocked to the player and once they have finished any of the maps, to unlock all the Coffee Quest 2 maps. Once a Coffee Quest 2 map has been completed, then the Coffee Quest 3 maps would be made available.  

My ideal release plans, which knowing history are very unlikely to work out, are as follows:

Quarter 1 of 2019 would be the release of the Coffee Quest release candidate with a new map (or two). The goal here would be to have a better automap, better quest status area, and the ability to click on the automap to bring up a full-screen map screen.

Quarter 2 of 2019 will hopefully be the beta release of the Coffee Quest 2 module which introduces monsters and inventory to the game. The Coffee Quest series uses the concept of conditions to weapons where the weapon deteriorates in quality over time and will break if the weapon or armor deteriorates too much. One change that the enhanced version of the game will have is that picking up additional copies of the same weapon will simply improve the quality of the weapon if you already have that weapon instead of filling up slots in an inventory.

Quarter 3 of 2019 will hopefully be the release candidate version of Coffee Quest 2 with a new map and enhancements/fixes made to the game.

Quarter 4 of 2019 would be a new Christmas game using the CQ-Trilogy engine.

Quarter 1 of 2020 would be the beta of the Coffee Quest 3 game which would introduce multi-floor towers.

Quarter 2 of 2020 will be an easter-themed game using the CQ-Trilogy engine.

Quarter 3 of 2020 will be the final build of the Coffee Quest 3 module.

Quarter 4 of 2020 will be the beta release of the combined game and will have some new maps as well as a halloween themed game.

If I fall behind on one of the quarter objectives then I will release additional maps for that quarter’s release. This would delay the final release of the game by a quarter. If things go smoothly I will finish the enhanced version of the original Coffee Quest Trilogy by the end of 2020 but odds are there will be a couple of quarters that I will miss so most likely this project will not be completed until 2021 or 2022 in the worst case situation. Depending on my situation once this project is completed, I will look into doing a similar project for the porting of Coffee Quest 4 and the final creation of Coffee Quest 5 and 6.

Saturday, October 20, 2018

Site Plans Winter 2018


Working on my Masters of Science in Computer Science is proving to be very time consuming. While I am trying to allocate blocks of time towards my porting and site work, the amount of time that I am actually able to devote to these side tasks is not as much as I would like. This means that there may be changes to the blog post next year. As the book is mostly written, there will not be any changes to this blog. The emulator work has slowed down so I will have to decide how to handle things once I catch up with my current work. Worst case scenario is that I cut back to monthly updates though will likely write some side-trip articles covering other aspects of the development such as the creation of test games and assembly libraries.

Spelchan.com will continue to be updated each month with a port of an existing game. As you have already seen, the October game was changed to Pent Up Anger. While I was going to release Coffee Quest 2 next month, instead I am going to release Cribbage Square and will use my new Coffee Quest engine to do an enhanced version of Santa’s Search for the December game.

I do plan on releasing a Coffee Quest episode every quarter of next year, with more information on the Coffee Quest porting plans to be made next fortnight as next fortnight’s port will be on the making of HTML5 Coffee Quest.

Even though the Dozen Days of Dice series is not overly popular, I really don’t have time to do a worthy port of One of those Weeks, so until I have enough time to do a proper OotW port, the Dozen Days series will be a placeholder with an episode every quarter.

This leaves four games open.  These will probably be used for holiday games but I have not yet made up my mind what I will be releasing so consider the other four releases for next year to be mystery games. They may even be new games if I end up creating some for University assignments.

Next fortnight, as mentioned above, will be a look at my Coffee Quest port and what the plans are for that series.

Saturday, October 6, 2018

4.8 Winning and Losing


As you know, the game ends when the last gem has been taken. Also obvious is the fact that there are two possible outcomes for this game. The player can win the game, or the computer can win the game. Knowing this, our movie is going to have to be able to handle either situation. This will require a bit of JavaScript. Here is the final version of the gemRemoved function with the new lines bolded.



function gemRemoved(gemCount) {
   if (gemCount <= gemsRemaining) {
          gameMovie.stop();
          if (gemCount == 0) {
                 if (gamestate == GAMESTATE_PLAYER_ANIMATING)
                       gameMovie.gotoAndPlay("playerWins");
                 else
                       gameMovie.gotoAndPlay("computerWins");
          }
          if (gamestate == GAMESTATE_PLAYER_ANIMATING)
                 computerTurn();
          else {
                 gamestate = GAMESTATE_PLAYER_PLAYING;
          }
   }
}
Both sequences start out with the final gem growing larger while moving to the left side of the screen. This is a simple scaling operation combined with a movement operation. The end result is shown in the image below.







To keep the code simple, the end sequence will simply display the results for a few seconds before returning to the title screen. An alternative approach would be to have a button that the user clicks to return to the title screen. To return to the title screen we simply call a returnToTitle function at the end of the winning screen and at the end of the losing screen.
The line of code that needs to be added to both:



                            returnToTitle();



Finally, we need a function in the global script called returnToTitle that actually does the work:



function returnToTitle() {
   gameStage.gotoAndPlay("Title");
}



And now we have a our completed NIM game!

Saturday, September 22, 2018

4.7 State of the Game


Progress on the NIM game has gone well and we have the core components of the game implemented (see the earlier sections previously posted). While we now have the core game mechanics implemented, we do not have a game. Right now we just have the ability for the player to take gems unitl there are no more gems. To have a proper game we need to be able to alternate between two players (the human and the computer). We also want the user interface to not accept input while the game is animating or the computer is playing. For this we will need to know what the movie is doing at any point of time. The easiest way of tracking this is to have a gamestate variable that holds the current state of the game with constants defined for the four states that we are concerned with.



// explain the different states of the game
var GAMESTATE_PLAYER_PLAYING = 1;
var GAMESTATE_PLAYER_ANIMATING = 2;
var GAMESTATE_COMPUTER_PLAYING = 3;
var GAMESTATE_COMPUTER_ANIMATING = 4;
var gamestate = GAMESTATE_PLAYER_PLAYING;
This means that we can now update the button handling routines to make sure that it is the player’s turn before doing anything with the button click. The new code is bolded.



function handleOneButton(e) {
   if (gamestate != GAMESTATE_PLAYER_PLAYING)
          return;
   --gemsRemaining;
   gamestate = GAMESTATE_PLAYER_ANIMATING;
   gameMovie.play();
}
function handleTwoButton(e) {
   if (gamestate != GAMESTATE_PLAYER_PLAYING)
          return;
   gemsRemaining -= 2;
   gamestate = GAMESTATE_PLAYER_ANIMATING;
   gameMovie.play();
}
function handleThreeButton(e) {
   if (gamestate != GAMESTATE_PLAYER_PLAYING)
          return;
   gemsRemaining -= 3;
   gamestate = GAMESTATE_PLAYER_ANIMATING;
   gameMovie.play();
}
The gem removal routine can also be fixed up to nearly it’s final form by having it start the computer’s turn after the player’s turn has finished being animated and returning to the control to the player once the computer has finished it’s turn.



function gemRemoved(gemCount) {
   if (gemCount <= gemsRemaining) {
          gameMovie.stop();
          if (gamestate == GAMESTATE_PLAYER_ANIMATING)
                 computerTurn();
          else {
                 gamestate = GAMESTATE_PLAYER_PLAYING;
          }
   }
}



Of course, for there to be a computer player, the computer needs to know how to play the game. It is quite possible to have the computer play the game perfectly, but that is not much fun for the player so instead the computer will play randomly until near the end of the game where they will take the opportunity to win the game if it presents itself.



function computerTurn() {
   if (gemsRemaining <= 3) {
          gemsRemaining = 0;
          setMessage("Computer taking " + gemsRemaining);
   } else {
          var numToPick = Math.floor(Math.random() * 3) + 1;
          setMessage("Computer taking " + numToPick);
          gemsRemaining -= numToPick;
   }



Random number are technically not random, but are pseudo-random but the details is not important. What had to be understood is that the Math.random() function returns a number between 0 and up to but not including 1 so that number needs to be adjusted to a usable value. Multiplying by three gives us a random number between 0 and just under 3. We want a decimal number so we use the Math.floor function to round the number down giving us a number between 0 and 2. Add one to this and we have the number in the desired range.



This leaves us with one final issue, which is winning or losing the game. This will be covered next fortnight!

Saturday, September 8, 2018

4.6 Gem Removal


The game revolves around the removal of gems, so we obviously need a way of removing gems. As the goal of this movie was to limit the amount of Action Script that is to be used, we will have to animate the removal of all the gems by hand. This is not that difficult of a task, only requiring that we have forty short animation sequences. The question is how do we stop all forty gems from being removed?


Unfortunately, this will require a bit of action script at the end of each removal sequence. This means that each gem removal sequence also must have a script frame which contains a function call.


gemRemoved(numberOfGemsAtThisPoint);


This calls a function that handles the removal of gems. The logic here is simple. We have a common variable that holds the number of gems there should be. When gems are removed, this value gets reduced. The gemRemoved handler keeps the movie playing until the number of gems remaining matches the number of gems displayed on the screen.


As you develop a game, the code changes as new features are added. It is always good to follow the KISS (Keep It Super Simple) acronym and start by writing just the code you need to get the goal you are currently working on working. As the program develops it becomes more robust. At this point you can review the code you have and do what is known as a refactoring pass. This means that you clean up the code so that it is easier to understand and more maintainable. At this point we are only concerned about getting gems to be removed so the code in the remove gems function and the related player panel button handlers will just contain the code necessary for doing the gem removal. This code will be changed in the next section as we add the game states but for now is what is needed to get our gem removal goal completed.


function handleOneButton(e) {
   --gemsRemaining;
   gameMovie.play();
}
function handleTwoButton(e) {
   gemsRemaining -= 2;
   gameMovie.play();
}
function handleThreeButton(e) {
   gemsRemaining -= 3;
   gameMovie.play();
}
function gemRemoved(gemCount) {
   if (gemCount <= gemsRemaining) {
          gameMovie.stop();
   }
}

For the gem removal, I just randomly selected a way of removing gems and manually created that sequence. Before you can remove the gem, you need to remove the gem from it's gem layer and place a gem in the same position as the removed gem but on one of the animation layers. From there, you can freely animate the gem to be removed. I came up with three separate ways of removing gems. Shrinking, Fading, and Rockets.


The shrinking technique simply has the gem shrink into nothing. As variations on this technique, some rotation can also be applied to the gem. Essentially you have the first keyframe with the gem at normal size. You then have the last keyframe with the gem at a percentage of what it was, optionally rotated. You then have a Motion Tween between the two frames.


Fading is simply having the motion tween between the gem with 100% alpha and the gem with 0% alpha. Rotation can also be done to this, but with gems near the gem you will want to keep the rotation to only a small amount.


Finally, rocket is simply moving the gem from one location to another off-screen location.