-
Notifications
You must be signed in to change notification settings - Fork 53
Getting Started With Akihabara
By Darius Kazemi
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 include 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.
To see the end product of this tutorial, a title screen for a game called 8by5, go here.
Download Akihabara 1.1 and open it. The zip file contains a bunch of demos of Akihabara. Those are 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 and the core .JS files. Put the akihabara folder in a project directory. Then create a blank file in your favorite text editor called 8by5.html and place that in the project directory. Finally, grab font.png and logo.png and save them to your project directory. The project directory should now contain 8by5.html, logo.png, font.png, and the akihabara folder.
Open 8by5.html and create a basic page framework:
- <html>
- <head>
- </head>
- <body>
- </body>
- <script>
- </script>
- </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 header is where we import the JS files we need. Important: as of Akihabara 1.1, you need to import all Akihabara 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:
- <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>
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.
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:
- var maingame;
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 before the game. 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:
window.addEventListener(‘load’, loadResources, false);
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.
- 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 });
- // The ‘main’ function is registered as a callback: this just says ‘when we’re done with this
- gbox.setCallback(main);
- // When everything is ready, the ‘loadAll’ downloads all the needed resources.
- gbox.loadAll();
- }
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.
The next part is a little confusing. We call gbox.setCallback(main), which tells Akihabara that when gbox.loadAll() is done loading resources, we call the main() function, which begins our game! Finally, we call gbox.loadAll(), which does the loading of resources and then calls our callback function, main, that we just set.
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.
- function main() {
- gbox.setGroups([‘game’]);
- maingame = gamecycle.createMaingame(‘game’, ‘game’);
- // We’ll add more here in the next step…
- gbox.go();
- }
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?
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:
- 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 });
- };
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.
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 notice that you can also press the “Z” key on the keyboard (which maps to “A” button in-game) and 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.