Way back in 2014, I participated in a game
jam called the Zero Hour Game Jam, with the idea being that you had to write
the game between 2AM and 2AM when the times switched for daylight savings time.
This “missing” hour would we the time you wrote your game in. The rules were “there
are no rules.” Wanting to keep the spirit of the Jam, I decided to do my coding
during the jam, but allow myself to prepare artwork beforehand. While I did not
have to do the same thing with the port, as the time switch was happening on
November 1st and because there is talk of getting rid of daylight
savings time (had something called Covid-19 happened, it is possible that there
wouldn’t be daylight savings time in BC as voters overwhelmingly want to get
rid of it as it serves no practical purpose but does pose medical problems to some
people) so this may be the last chance I have to do a game in 0 hours. While
there are Zero Hour jams running this year, I opted to do my own Zero Hour Port
where I take my original Zero Hour game and re-write it in JavaScript so it
will be playable since Flash is no more.
My rules for this port were simple. Pre-Jam
preparations were allowed which simply consisted of using my old copy of Flash
to create a sprite sheet of the assets in the original game and to convert the
resulting JSON file from this sprite sheet that was generated into my own
condensed format. A sample of my JSON format is shown below. I am also allowing
myself to use my Vampire Attack game from last month as skeleton code to
quickly hack out a working game.
ZHAtlas = {
"KeyABtn" : {"x":0,"y":0,"w":94,"h":84, "over_x":102,"over_y":0,"down_x":102,"down_y":0},
"KeyDBtn" : {"x":204,"y":0,"w":94,"h":84, "over_x":306,"over_y":0,"down_x":306,"down_y":0},
"KeyQBtn": {"x":510,"y":0,"w":94,"h":84, "over_x":612,"over_y":0,"down_x":612,"down_y":0},
"KeySBtn": {"x":714,"y":0,"w":94,"h":84,"over_x":816,"over_y":0,"down_x":0,"down_y":0},
"KeyWBtn": {"x":918,"y":0,"w":99,"h":84,"over_x":0,"over_y":92,"down_x":0,"down_y":92},
"KeyEBtn": {"x":214,"y":92,"w":94,"h":84,"over_x":316,"over_y":92,"down_x":316,"down_y":92},
"continueBtn": {"x":418,"y":92,"w":216,"h":50,"over_x":642,"over_y":92,"down_x":0,"down_y":184},
"Zombie": {"x":448,"y":184,"w":546,"h":656},
"backdrop": {"x":0,"y":848,"w":512,"h":256}
}
As you can see by looking at the above JSON
code, objects in the games are named and given information about coordinates
and size. Buttons also have additional coordinate information for their over
and up states. The sprite sheet is too big to put here but is available in the
git repository for those of you who wish to view it.
Once the missing hour started, I copy and
paste code into a new project. The HTML boilerplate is pretty much unchanged just
with some redundant code removed and the name of the game and script changed. The
js file linked to from the html file really doesn’t need too much to be copied
from Vampire Attack. First I paste in my JSON file and turn it into an object,
that is the one thing I do love about JSON. Then I copy the button class and
turn my ScreenHandler class into the game class. I am figuring that I can
simply have the title screen and win/lose screens built into this one screen,
which in hindsight was a bit more work than I expected.
Drawing the backdrop is trivial so for my
rendering routine I simply draw the backdrop image. Then, which is not shown in
my final code, I want to make sure the buttons are rendering properly so I
render all of them using a for loop. The button class uses a callback mechanism
so implementing the handler is trivial. For quick testing the handler just
displays a console message but game logic will be going here shortly.
With the user interface implemented, it is
time for the gameplay. This involves the zombie moving toward the player. Here
is where I wish that more time was spent examining the original code for doing
this. While writing scaling code is trivial, having the zombie at the center of
the screen didn’t look very good as the zombie was floating in the air. The
obvious quick fix for this problem is to shift down the y coordinate. This
solves the footing problem, but as we are scaling at a constant rate the zombie
appears to slow down as it starts reaching the player. Playing a few times it
is a bit surreal but sort of like what you would experience as your adrenaline
started kicking into overdrive so figured I would leave this alone unless there
was time at the end to fix it.
Now clicking on a button adjusts the zombie
distance, and when the zombie is far enough away we log a win. If the zombie
gets too close we log a loss. The problem is that all the keys will let the
player run, making the game too easy. This is easily fixed by picking one of
the keys at random and only rendering/accepting that key. This meant that
keyboard support had to be added which isn’t hard. The keyboard handler for key
down looks at the key being pressed and checks to see the character is the same
as the expected character and if so calls the player step method for moving the
player. The button handler does likewise so we have both keyboard and
mouse/touch suppprt.
this.zscale -= .06;
this.cur_key = Math.floor(Math.random()* 6);
if (this.zscale < .1)
this.nextScreen(); // note this was a console log earlier
}
At this point I am thinking that I am
almost done and will be able to add sound, music, and maybe even fix the zombie
motion. First, however, we need title, win, and lose screens. Choices here are
to cut an paste the screen handling code from Vampire Attack and have different
screens. Or as there are just messages to display I could just do everything
within the existing screen. Feeling the later would be faster, I opted to go
for that approach. I don’t think it ended up being faster and added some ugly
code to my project so was ultimately a poor decision.
To add a title screen, a showTitle flag was
added. When set the title text gets shown. A playing flag determines if the
game is in progress. If the game is not being played, a separate message (for
winning, losing, and extra title text) will be shown. To handle the transition
between the different states, a next screen method was written as shown below.
This code gets called whenever a screen transition should occur which includes winning,
losing, clicking to return to title, and starting the game from the title.
if (this.playing === true) { // game ended
this.cur_key = 6;
this.playing = false;
if (this.zscale >= 1) {
this.message = "You have died!";
} else
this.message = "You Escaped!!!";
} else if (this.showTitle === true) {// game starting
this.cur_key = Math.floor(Math.random()* 6);
this.zscale = .5;
this.showTitle = false;
this.playing = true;
} else { // return to title
this.cur_key = 6;
this.message = "Billy Spelchan's Zero Hour Game port";
this.showTitle = true;
}
}
Once I finally finished the screen
transition logic there was few minutes left but I was too tired to continue so the
sound effects, which probably could have been added in only a couple of
minutes, was dropped and I figured I would go to bed and put up the game when I
woke up. The code for this game is
available in the git repository for those who are interested. Not sure what
will be next month, but I do have an interesting multi-part series where I
create a game then demonstrate different approaches to solving that game. If I
have time to do a Christmas game (slim but non-zero) then I will do a
postmortem on that game otherwise I will start the new series.