Saturday, September 22, 2018

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

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.

About Me

I am a programmer who can program in a large variety of programming
languages (including some Assembly Language) but am currently focused
on interactive web development which means my current focus is on Flash
and JavaScript. When I am not programming for clients, I am working on my
game site.