Akihabara Tutorial, Part 1: Title Screen
This is a multi-part tutorial where we will teach you how to make an 8-way shooter in HTML5 and JavaScript using the Akihabara framework. Akihabara is a set of Javascript libraries that take advantage of some of HTML5’s unique features to facilitate game creation. One of the best things about writing a game in HTML5 is that it will run in any browser that supports HTML5 on any platform. This includes Chrome, Firefox, Safari, and WebKit browsers on iPhone/iPad, WebOS devices, and other mobile platforms.
In part 1, we will walk you through the very basics of Akihabara and show you how to render a title screen.
The Final Product
To see the end product of this tutorial, a title screen for a game called 8by5, go here.
Installing Akihabara
Download Akihabara 1.3.1 and open it. The zip file contains the directories akihabara, extras, and resources, and the Capman demo. Capman is good to look at later (and fun to play!), but for now the only thing you need is the folder called akihabara which contains some images for buttons, the documentation, and the core .JS files. Put the akihabara folder in a project directory. Then create a blank file in your favorite text editor called index.html and place that in the project directory. Finally, download font.png and logo.png and save them to your project directory. The project directory should now contain index.html, logo.png, font.png, and the akihabara folder.
The Document Format
Open index.html and create a basic page framework:
[html]<html>
<head>
</head>
<body></body>
<script>
</script>
</html>[/html]
The head tag is where you’ll include all the Akihabara JS files and set the appropriate information about scaling for different displays. The script tag is where all the code for you game goes. The body tag is going to remain blank!
The Document Header
The header is where we import the JS files we need. As of Akihabara 1.1, you need to import all JS files even if you aren’t explicitly using some of them. So no matter what your game is, your header should look like this:
[html] <head>
<script type="text/javascript"
src="akihabara/gbox.js"></script>
<script type="text/javascript"
src="akihabara/iphopad.js"></script>
<script type="text/javascript"
src="akihabara/trigo.js"></script>
<script type="text/javascript"
src="akihabara/toys.js"></script>
<script type="text/javascript"
src="akihabara/help.js"></script>
<script type="text/javascript"
src="akihabara/tool.js"></script>
<script type="text/javascript"
src="akihabara/gamecycle.js"></script>
<style>BODY { -webkit-user-select: none; margin: 0px
}</style>
<meta name="viewport"
content="width=device-width; initial-scale=1.0;
maximum-scale=1.0; user-scalable=0;" />
</head>
[/html]
Each <script> tag tells the browser to load a JavaScript library. The <style> tag sets some CSS so that the game renders well in WebKit (iPhone), and the <meta> tag sets some information that mobile web browsers use for scaling purposes.
There’s not much else to the header, so let’s move on to the game code itself.
Loading Your Resources
From here on, we’re discussing code that is contained in the main <script> tag in your HTML document, right below the <body> tag. Because games can be pretty graphics-heavy, we want to load all the game’s resources before we begin the game. First we create our game:
[js]var maingame;[/js]
By putting this at the top of the script it acts as a global variable storing all the game info so we can get it from within any function.
Now we do some magic to make sure that the resources load first, before the game begins. We’ll use JavaScript’s addEventListener function, which takes the general form window.addEventListener(eventType, functionName, useCapture);
This tells JavaScript to run the function called functionName after an event of type eventType. We won’t worry about useCapture here, just know that it’s a boolean that you should set to false. In the case of our game, we’re going to use the eventType called “load”. Our event listener looks like this:
[js]window.addEventListener(‘load’, loadResources, false);[/js]
Here’s what this does: once the browser has loaded the HTML document, it runs the function loadResources. That’s it. So now we should define loadResources. The code below is commented pretty well but just read through it and then we’ll go over it step by step.
[js]function loadResources() {
// This initializes Akihabara with the default settings.
// The title (which appears in the browser title bar) is the
text we’re passing to the function.
help.akihabaraInit(‘8by5’);
// Here we tell the game to look for an image called
‘font.png’ in the same directory as the HTML file
and call it ‘font’ internally
gbox.addImage(‘font’, ‘font.png’);
// Same thing for our logo here.
gbox.addImage(‘logo’, ‘logo.png’);
// Fonts are mapped over an image, setting the first letter,
the letter size, the length of all rows of letters and a
horizontal/vertical gap.
gbox.addFont({ id: ‘small’, image:
‘font’, firstletter: ‘ ‘, tileh: 8,
tilew: 8, tilerow: 255, gapx: 0, gapy: 0 });
// When everything is ready, the ‘loadAll’
downloads all the needed resources, and then calls the
function "main".
gbox.loadAll(main);
}[/js]
Pretty simple. We use the default initializer function, help.akihabaraInit(…), and pass it the title we want for the HTML document. We call gbox.addImage(…) to load our font set and our logo. Then we call gbox.addFont(…), which is kind of weird and complicated and we’re not gonna go over it. Just know that it’s a sprite font, which means that it looks at a big sheet of numbers, letters, and symbols (font.png in this case) and chops it up in a certain order so it knows which graphics correspond to which character. In our demo we’re using an 8×8 pixel sprite font that comes with the Akihabara demos.
Finally, we call gbox.loadAll(main), which does the loading of resources and then calls the main() function, which begins our game!
Now We Actually Do Stuff
Here’s where the rubber hits the road and we create a game loop and start rendering stuff to the screen. First we set up our basic main function, which is where all the game code lives.
[js]function main() {
gbox.setGroups([‘game’]);
maingame = gamecycle.createMaingame(‘game’,
‘game’);
// We’ll add more here in the next step…
gbox.go();
}[/js]
The first line of the function creates a group called “game”. A group is a designation that tells the game what order to render things in. This part of the tutorial only has one group so we’re not gonna worry about it too much, but basically it’s a way for you to say “render everything in the background group underneath stuff in the player group so the player is always on top of background stuff.”
The next line takes our maingame global variable that we set at the top of our code and makes it into a bona fide game object with its associated state machine, which provides the basic overall structure of our game. We call the gamecycle.createMaingame function so that our maingame variable knows about things like intro animations, the main game, game over, player death, game end, etc. We pass it ‘game’ twice just to let it know that it’s going to be operating in our game group, so it’ll be processed with high priority (though we do not yet have other priorities, since there’s only one group).
Finally, we call gbox.go() to tell Akihabara to run the game.
At this point you can test your game in a web browser and you’ll see a default title screen that says “GAME TITLE”.
This is because the gamecycle.createMaingame function defines a default title screen and is smart enough to know that the title screen is the first thing that the game should load up. But we don’t want the default title screen because who wants their game to be called “GAME TITLE” anyway?
Our Custom Title Screen
If you poke around in gamecycle.js you’ll find a function called gameTitleIntroAnimation() which is what actually renders that dumb “GAME TITLE” thing. We’re not going to mess with gamecycle.js directly — what we’re going to do is override the function, i.e. replace the default function with our own. Fortunately in JavaScript all you need to do to override a function is to define it again using an “=” operator. Place this right before gbox.go(), replacing the “We’ll add more” comment we had:
[js]maingame.gameTitleIntroAnimation=function(reset) {
if (reset) {
toys.resetToy(this, ‘rising’);
}
gbox.blitFade(gbox.getBufferContext(),{ alpha: 1 });
toys.logos.linear(this, ‘rising’, {
image: ‘logo’,
sx:
gbox.getScreenW()/2-gbox.getImage(‘logo’).width/2,
sy: gbox.getScreenH(),
x:
gbox.getScreenW()/2-gbox.getImage(‘logo’).width/2,
y: 20,
speed: 1
});
};[/js]
The if statement only runs when reset is true, which is only in frames before the intro animation begins. In this line we’re saying that before the intro animation begins, we’re letting the toys class know to expect a local data store called rising and that rising is part of the maingame object (which is what this refers to since we’re working inside maingame in the first place).
The gbox.blitFade function just clears the screen. The toys.logos.linear function sets the actual animation. We’re telling it to run it in maingame (i.e., this), to use the rising data store that we set aside, and then we pass it a structure containing a bunch of data. We’re passing it image (the logo), sx and sy (the source coordinates where the logo begins), x and y (the destination coordinates where the logo ends), and the speed of movement. We tell it that the image is ‘logo’, which we defined in loadResources at the beginning. We define sx and x as the same thing, since we want the image to move on the y axis but not on the x axis. In this case we’re setting it to half the screen width minus half the logo width, effectively centering the logo on the screen. Then we define sy as the screen height (which places the top of the image at the very bottom of the screen, just out of sight) and y as 20. This will make the logo rise from just below the screen to 20 pixels under the top of the screen.
Press Z to start
One of our biggest complaints about Akihabara is that by default the title screen says, “Press A to start,” but really it wants to you press the Z key on your keyboard. This is due to some design decisions around mobile device control overlays that we’re not going to go into. Fortunately this is a simple fix: we need to override the function that displays that message so it says Z instead of A. Right after the code you just entered, put this:
[js] maingame.pressStartIntroAnimation=function(reset) {
if (reset) {
toys.resetToy(this,"default-blinker");
} else {
toys.text.blink(this,"default-blinker",gbox.getBufferContext(),{font:"small",text:"PRESS
Z TO
START",valign:gbox.ALIGN_MIDDLE,halign:gbox.ALIGN_CENTER,dx:0,dy:Math.floor(gbox.getScreenH()/3),dw:gbox.getScreenW(),dh:Math.floor(gbox.getScreenH()/3)*2,blinkspeed:10});
return gbox.keyIsHit("a");
}
};[/js]
It overrides the functionality of the maingame.pressStartIntroAnimation function with a modification to the text field in the toys.text.blink call. You’ll notice there’s a gbox.keyIsHit(“a”) call in there as well. The Z key still maps to “A” internally. As far as Akihabara is concerned Z = A, X = B, C = C… fortunately your player won’t have to worry about that anymore!
Hello, World
And that’s it! You can run the game now by opening the HTML file in a web browser and you should see something like this.
You’ll first see a loading screen with the title logo of your game in the lower-right corner. Then the program begins running, showing you the title screen that you can press “Z” to get past. You’ll notice that you can also press the “Z” key on the keyboard to select a difficulty, at which point the game goes to black. This happens because maingame knows all about the game flow, so it automatically puts up a difficulty selector, and then sends you into the game. We didn’t actually code a game yet so you get nothing but darkness after selecting your difficulty.
[aki_tut_toc full_url=”“]
{ 12 comments… read them below or add one }
I want to cry. Thank you for writing this! I’ll follow *all* the issues! Really really really good work! Thank you for pointing me your work! Kudos!
Great tutorials.
I came across akihabara a couple of weeks ago on twitter.
Loved the games.
I’ve developed my own game in js for webOS using GMP.
I’m currently porting it to iPhone with phoneGap. The iphone version was initially alot slower than the webOS version but I’m nearly there now. I’ve blogged my porting journey at iAppLogic.com
Anyway it will be interesting when I get home to test Legend of Sadness on my iPhone and Palm Pre. I only just noticed the touch versions now.
With these tutorials I’ll look seriously at akihabara for my next game.
Thanks
Thanks! I can’t wait for the rest!
interesting stuff!
lots of use for this with the ipad… but do you have any pointers to how to interface with touch input? i see theres an iphopad.js file, but not sure how/what events fall through to the maingame, and how to pick up and handle them.. any tips would be appreciated.
@dc — we’ll be covering touch controls, though not for a while. I haven’t even begun to look at it myself. Sorry!
Great job!
I’ve translated the part 1 into Chinese without your permission, forgiving me…
At here: http://www.mikespook.com/index.php/archives/622
If you permit, I would follow your job, continue translating others part into Chinese.
@mikespook — Great to see you took the initiative on this! We’d be delighted to have you continue to translate them, so long as you keep linking back to the originals. =)
Thanks for this guys!
Needs an update to point to version 1.3!
So peeved I couldn’t catch you at the Boston Post Mortem last night…
I have read the tutorial. Its great. I am starting to develop my game for Android soon.
The documentation is better than other JS Game libs. out there, but I think it still can become more better.
anyways, thanks for tutorials. Loved it.
Awesome tutorial. Thank you so much for this.
Question: can Akihabara handle sprite scaling?
Really noob question. I copied the code the from the first part and when I open the .htm file in Chrome, nothing appears.
I’m guessing it has something to do with directories.
I’m using Kod(kodapp.com)as my text editor, and I put index.htm, font.png, logo.png and the Akihabara folder all in one folder.
What am I doing wrong?
Thank you.
Hi Torao,
In all likelihood, it’s actually broken in Chrome right now. It’s hard to keep these tutorials up to date because Akihabara can be tricky to debug and of course Chrome and the rest of HTML5 world evolves rapidly.
If you figure out what’s wrong, please post here again and we’ll fix it.
Thanks!
{ 7 trackbacks }