Before I get to my game overview a brief update on my 2600 project. The assembler is functional now and while I do want to add more directives to it, will start on implementing the 6502 emulation adding new directives to the assembler as needed. I have a number of articles on my 2600 assembler ready and will be posting them next year. Now back to the evil gnome.
Evil
Gnome’s Revenge was my 2012 game jam entry for Ludum Dare #25 which had the
theme “You are the Villain.” At the time I really didn’t want to go down any of
the dark paths that I had thought of and having had created both Santa’s Search
and Santa’s Snowball years earlier I thought this would be a light-hearted way
of making the player the villain without having them do anything outrageous. I
can’t say that the herding concept was original as there are a number of games
that have a similar mechanism with Munch’s Oddysee probably being the biggest
influence.
The
development time on this port was pretty abysmal as I made the cardinal mistake
of working on it while watching TV. While I know that the human brain is not
designed for multitasking, the lackluster performance I had while coding this
clearly emphasizes how poor we humans are. The strange thing is that I normally
have podcasts or other background noise playing so I had expected to have my
normal development speed. When coding, however, I tend to tune out what I am
listening to while the TV tended to take most of my attention as I got caught
up with my shows before losing the contents of my PVR. The big lesson being
that you shouldn’t let your recorded backlog build up that much. Coding is best done without
distractions could also be considered a lesson if I didn’t already know that.
The first
surprise was that the game was created using the Starling library. This is a
molehill library that takes advantage of the 3D capabilities that later
versions of the Flash player added. When
I saw the starling imports I thought that perhaps I should consider StageGL,
the WebGL based renderer that is in testing now but will eventually replace the
stage.js library. The map for the game,
which is procedurally generated, is 64x64 with each tile being a movie clip
that goes to the appropriate frame to display the tile at that location. Once
set, however, the tiles do not change. Having 4096 sprites on the screen is
probably not very good for performance, but by creating a 2048x2048 pixel cache
then there is only one background image that the renderer is tracking giving
the game 60 fps performance on decent machines. It is easy to cache sprites, as the following code shows.
// for speed reasons, cache the tilemap
this.tileMap.cache(0,0, 64*32, 64*32);
One of the
substantial changes that I am making to all the games that I am porting is to
make sure that the games work with touch interfaces. Touch input meant
rewriting how the player moves as the original game used cursor or WASD for
movement. The obvious solution was to simply have the player click to where
they wanted to move to and head in that direction. The obstacles in the map,
however, made this a bit tricky. A path-finding algorithm could have been used
but I didn’t feel like writing one so I opted for a simple slide along the
object system. This simply checks to see if the player is stuck and if so tries
moving on just one of the axis. While this method still lets the player get
stuck, most of the time the player will move around the obstacle.
if (this.canEnterTile(targX, targY, mover) == false) {
if (this.canEnterTile(targX, mover.worldY, mover) == false) {
if (this.canEnterTile(mover.worldX, targY, mover) == false) {
// we are stuck!
} else {
mover.worldY = targY;
}
} else {
mover.worldX = targX;
}
} else {
mover.worldX = targX;
mover.worldY = targY;
}
This is
where things got strange. The game seemed to work fine with the change until
the mouse was moved at which point the game stalled for a few seconds. Out of
curiosity, I removed all the tiles from the tilemap image replacing It with a
2048x2048 shape. This solved the delay problem meaning that the problem was
with how create.js handles clicking. All the tiles are being checked with a
pixel accurate test to see if the tile is affected by the mouse event. The
solution was to not have the game screen process the mouse event but grab the
mouse events at the higher stage level then manually determine which tile was
clicked on. When you are dealing with thousands of objects, different
techniques must be used.
var clickX = e.stageX
var clickY = e.stageY;
this.gnome.targetX = (clickX - this.tileMap.x) / 32;
this.gnome.targetY = (clickY - this.tileMap.y) / 32;
With the
major issues out of the way, this was not a difficult game to port. This only
leaves the final game in the series which will be covered next week and then we can get back to my 2600 emulator.
No comments:
Post a Comment