Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
21. June 2012

 

A few weeks ago, I mentioned that I might put together an HTML5 Roleplaying game tutorial and inquired how much interest there was in the subject.  There was sufficient interest, so I dove into the subject a little bit closer and came to a bit of a conclusion.  It’s ultimately theHTML-5-RPG tools that make the game in this case.  So, in addition to a game, I would have to create an editor, which is actually where most of the guts would reside.

 

This presented an interesting problem for me, as I’ve done a lot of web development, I mostly worked server side in a traditional language like C# or Java.  For this project, I wanted it to be JavaScript end to end.  I have a few key requirements:

 

  • single language, end to end
  • server based editor, that can be run locally on the client
  • code reuse between game and editor
  • MVC/MVP or MVVM based.  ( if you don’t know these acronyms, don’t worry )
  • event driven
  • rich UI
  • run on a tablet’s browser
  • database and local/remote filesystem support
  • json-based level output, which can be used by clients in any language
  • game entity scripting, probably again, in JavaScript

 

Part of these requirements are driven by personal interest, I have always wanted to try making an MVC based game editor.  MVC means, model-view-controller ( MVP == model view presenter and MVVM == model view viewmodel ) and it is a manner of design for decoupling your data ( your game’s/editor’s objects ) from your view ( your application or webpage ).  There are a number of great advantages to implementing things this way, including testability, maintainability, reuse and perhaps most importantly, it imposes a clean separation of responsibilities between systems.

 

The single language end to end is an easy one.  JavaScript.  While JavaScript is by no means the best designed language in the world, it is a extremely well supported one with a very bright future.  It is increasingly becoming a language that every developer is going to need to know, so why fight the future?  Of course, I could use a slightly higher level implementation like Coffeescript, Closure or Dart, they all ultimately compile down to JavaScript in the end.  That said, one of the biggest reasons I want to use a single language from end to end, is so the most people can follow along without having to know or learn multiple programming languages, so I will probably go with plain Jane JavaScript.

 

Now the whole running on a server and locally, that presented a bit of a trick.  I want people to be able to follow along, and run it from their own computer for their own projects, so offline is a must.  However, I also wanted an editor available for people who are only interested in game side of the equation, which is why I want to host one on my server.  That said, I also don’t want to bog my own servers down too badly.  This presented a bit of a problem, but it was solved soon enough when I started looking into….

 

Database and local/remote file system support.  Behind the scenes, a lot of tools are actually built around a database, whether they realize it or not.  In the end, many tools end up creating their own crude database server around their own file format, or often XML.  In my view, this is awfully close to re-inventing the wheel.  If you are using database like functionality in your tool, use a database!  Fortunately when it comes to JavaScript, there are an absolute ton of options!  From redis, a simple to learn key/value based database and JSON based CouchDB to more traditional databases like MySQL and SQL Server.

 

HTML5 has some options when it comes to local storage, such as well… webStorage.  There are some pretty heavily limitations here, one of the biggies is the lack of support.  Size limits are also rather severe size limitations, in the area of 2.5-5MB, a limit that you will run into extremely quickly.  The alternative to persist these files on the server isn’t really appealing to me, when I am the one paying the server bills! Smile

 

This is where Node comes in.  Node nicely solves just about all of these problems.  Essentially I am going to develop the editor as a node based client/server, where the user has the option of installing the client and server locally, and running it just like any other application.  This gives me access to the local file system and whatever other libraries I need.  However, it also allows me to use the exact same code to provide a hosted version of the editor other users can simply run in their browser.  Essentially Node will act as the host for the DB, as a web server and as the interface between the local machine and the view.

 

Speaking of which, this leaves the view…

 

Again, as I said earlier, the majority of client/server programming I did was built over Java or C#, so the HTML5 / JavaScript approach was new to me, so I had to take a closer look at what options exist.  In short, there are an absolute ton of options… too many in fact.  However, my rather well defined needs narrows things down quite a bit.  In fact, I am down to a pair of options, and would love your opinion on them.

 

 

Option 1

 

jQuery for the UIjquery-logo1

jQueryMobiel for the mobile UI

Node for the backend

CouchDB or redis for the database layer

Express for the server bits

Backbone.js for the um, backbone ( this is where MVC comes in )

Moustache and icanhazjs for the templates

underscore, well, just to make things work

 

 

Option 2

 

YUI for the front end (desktop and mobile), routing, MVC and server bitsyuilib

Node for the backend

CouchDB or redis for the database.

Handlerbars for the templating.

 

 

 

Both have benefits and detriments, especially from the perspective of a tutorial.

 

jQuery is easily the most popular UI library out there, and there is a gigantic amount of support available ( and dozens of books ), with a gigantic community.  Backbone and Moustache are less used, but still well supported.  Unfortunately, this also means introducing a half dozen pieces of tech, a very confusing prospect.  Development on all of these products moves extremely fast, which is a double edges sword.  Finally, and this is highly personal, I hate the look of jquery and underscore code, it feels so… hackey.

 

YUI on the other hand, is from a single vendor, with much less supporting material but very good documentation and a very clean modular design.  More to the point, it is an end to end system so it is very consistent.  However, if something goes wrong the community is much smaller and the supporting materials aren’t as readily available.  Perhaps the biggest downside with YUI is the newness of it.  YUI3 is still in transition away from YUI2, and YUI App ( the YUI equivalent to Backbone ) is young and at times it shows.  From an engineering perspective though, YUI just feels more solid and less like a clever hack.

 

Right now, ease of explanation is winning out, and I am leaning towards using YUI.  Going with on all encompassing library is much easier to configure and explain to readers, so that is a big plus.

 

Any thoughts or opinions on the subject? 

 

Oh, and if this is all sounding extremely confusing, don’t worry, it really isn’t that bad.  The end product should still be a single archive you download and execute with a simple click. 

 

So, over the next few weeks ( or more ), we are going to be going off on a slightly odd tangent here at game from scratch, and crossing over into the world of web app development, I hope many of you find it interesting.  For those that don’t, don’t worry, I will still be publishing game development specific contents and tutorials too!

Design


19. June 2012

 

A couple months back took a long look at Appcelerator and initially I loved what I saw.  For those of you unaware, Appcelerator allows you to develop “native” applications for Android and iOS in JavaScript that execute in a special version of the V8 JavaScript Engine. I started developing a prototype app of a simple Android game for my daughter and got surprisingly good results quickly.  It was a very encouraging start, but then the wheels fell off.  I notice a number of people end up on this site from search engines looking for an Appcelerator review ( for some reason? ) so I thought I would share my experiences.

 

For whatever reason, I got distracted and put it down for a while, I came back to it recently and intended to finish off that prototype.  Here is the kicker, the exact same code from a couple months ago, unchanged, no longer works on my Transformer tablet.

 

I will say, this is frustrating to say the least.  Now, since the code didn’t change it was obviously an update to Android that broke things, I can’t exactly blame that on Appcelerator Titanium ( oh the joys of Android device compatibility… ) but I can blame them for what came next…

 

You can’t debug on device.  At all.  With the exception of printing comments to logcat, you are basically blind.  This obviously leads to a problem, as here is what happens when I run the app.  ( Which by the way, still runs perfectly fine on my Galaxy Note running Android 2.3.x, its just on my Asus Transformer that it breaks ):

 

appcell

 

Since I can’t debug on device, this is the results I get from connecting with the Delvik Debug Monitor:

 

06-19 09:56:51.090: I/TiApplication(1823): (main) [0,0] checkpoint, app created.
06-19 09:56:51.130: I/TiApplication(1823): (main) [46,46] Titanium 2.0.2 (2012/05/30 10:21 2ff31a3)
06-19 09:56:51.170: D/dalvikvm(1823): GC_CONCURRENT freed 268K, 5% free 6703K/7047K, paused 2ms+2ms
06-19 09:56:51.380: D/dalvikvm(1823): GC_CONCURRENT freed 314K, 6% free 6898K/7303K, paused 2ms+2ms
06-19 09:56:51.450: E/TiApplication(1823): (KrollRuntimeThread) [318,364] APP PROXY: [email protected]

 

 

And, that is it.  Since I can’t debug on the device, I am pretty much DOA here.  The forums answer nothing ( although I did find other people having similar problems ).  I of course could debug in the emulator with two exceptions.  a) the error only occurs on the actual device b) the debugging experience on Android is still awful.

 

This is another area with Appcelerator Titanium I always found infuriating… the emulator.  Getting it to actually run with your running emulator was a nightmare, you had to match up the Android build version and run configuration exactly with the version of the running emulator, then it was still a 50/50 chance that it would actually use your emulator, or start a new one.  If you’ve worked with Android before, you know how fun waiting for the emulator is!  There is light and the end of the tunnel with the recently release Intel emulator running a heck of a lot quicker, but unfortunately the JavaScript V8 virtual machine Appcelerator relies on doesn’t work with it.

 

It’s a shame to be tripped up on such a thing, but actually being able to debug on your device is an absolute requirement, as is demonstrated by this situation.  There are other annoyances with using Appcelerator certainly…  the binaries it generates are “large” to be extremely kind, performance can be a bit spotty at times and you virtually have to write two applications if you want to support iOS and Android, but none of these was enough to make me give up. 

 

Not being able to debug on device, coupled with some remarkably meh support.. that is.  Combined with the fact my application was broken by an Android update… if I can’t get my code working with my three devices reliably, what happens when I release to the masses with their millions of different devices?

 

Which is disappointing, as I really liked working with Appcelerator.  I even liked Appcelerator Titanium as an IDE, which is shocking as I hate Eclipse, which it is based on. 

 

There is potentially light at the end of the tunnel, as there is an open ticket for debugging on device.  Unfortunately, its been assigned medium priority and has already been open for almost a year.

 

Appcelerator Titanium is an interesting and encouraging product, but for the above reasons, I just can’t commit to using it.  Add native debugging support, and I will certainly reconsider.

General


17. June 2012

 

In this tutorial we are going to look at adding keyboard and mouse support to your cocos2D application.  cocos2D was traditionally used on the iPhone, so keyboard and mouse support is very touch centric, so if you are used to desktop development and things seem a bit strange, this is why.

Alright, let’s jump right in.  We are going to create a simple game with our jet sprite from tutorial 3.  The big difference is it will respond to your mouse and keyboard activity.  Clone your previous project, this time I am calling it MyThirdApp.  Yeah, tons of thought went into these names! 

 

Now create a new file in the Classes directory named JetSprite.js. Inside, write the following code:

 

var JetSprite = cc.Sprite.extend({
    _currentRotation:0,
    ctor:function(){
        this.initWithFile("images/jet.png");
    },
    update:function(dt){
        this.setRotation(this._currentRotation);
    },
    handleKey:function(e)
    {
        if(e === cc.KEY.left)
        {
            this._currentRotation--;

        }
        else if(e === cc.KEY.right)
            this._currentRotation++;

        if(this._currentRotation < 0) this._currentRotation = 360;
        if(this._currentRotation > 360) this._currentRotation = 0;
    },
    handleTouch:function(touchLocation)
    {
        if(touchLocation.x < 300)
            this._currentRotation = 0;
        else
            this._currentRotation = 180;
    },
    handleTouchMove:function(touchLocation){
        // Gross use of hardcoded width,height params.
        var angle = Math.atan2(touchLocation.x-300,touchLocation.y-300);

        angle = angle * (180/Math.PI);
        this._currentRotation = angle;

    }
});

 

Here we are deriving our new class JetSprite from cc.Sprite using the extend() function.  During the constructor, we first call back to cc.Sprite’s constructor, then load our sprite from the file jet.png located in the images folder.  ( If you like me started your project by cloning MySecondApp, it should already be there, otherwise make sure you have an image there ).

 

The update() function is going to be called once every frame, this will make sense later.  Essentially this is where you put your object’s logic.  In this case we are simply rotating our sprite to the value in _currentRotationhandleKey(), handleTouch() and handleTouchMove() are three user defined functions that are going to be used to pass I/O events into our JetSprite object.

 

handleKey() is passed the key value ( it’s a number ) of the currently pressed key.  cocos2D defines a number of key values to represent each key in the cc.KEY value.  If you want more details check out CCKeyboardDispatcher.js in the cocos2D directory for more details.  In the event the left arrow key is held down, we decrement our rotation value, if the right arrow key is down we increment the rotation value.  Finally, if we roll over 360 or under 0 degrees, we update accordingly.  Effectively this rotates our sprite left and right on arrow key press.

 

handleTouch() is very simple.  It is passed in the touchLocation, which is an x,y value representing where on screen was touched ( or in our case, clicked ).  If its on the left half the screen, we point up ( 0 degrees ), if the touch occurred on the right half of the screen, we rotate to straight down ( 180 degrees ).  One limitation of cocos2D seems to be the lack of ability to handle right clicks, but this may just be an oversight on my behalf.  Right now, a “touch” is any mouse button click.

 

handleTouchMove() is passed in the x,y coordinates of the mouse’s currently location.  As you can tell by the comment, I rather crudely used a hardcoded value for representing half the screen width ( 300 ), obviously in non-demo code you wouldn’t do this!  What we want to do here is figure out the angle of the mouse relative to the center of our sprite ( which is located at 300,300 ).  This is done by taking the atan2 of the distance of the mouse’s coordinate from sprite’s center.  We then convert that value ( atan2 returns a value in radians ) to degrees.  Finally, we take our calculated angle and apply it as our rotation.  Essentially this will cause our sprite to rotate relative to the mouse location.

 

Now lets take a look at the heart of our application.  Create a new script file ( or rename MySecondApp.js ) called MyThirdApp.js and enter the following code:

 

var MyThirdApp = cc.LayerColor.extend(
{   _jetSprite:null,
    init:function(){
        this._super();
        this.initWithColor(new cc.Color4B(0,0,0,255));
        var size = cc.Director.getInstance().getWinSize();

        this._jetSprite = new JetSprite();
        this.setTouchEnabled(true);
        this.setKeyboardEnabled(true);

        this.setPosition(new cc.Point(0,0));

        this.addChild(this._jetSprite);
        this._jetSprite.setPosition(new cc.Point(size.width/2,size.height/2));
        this._jetSprite.scheduleUpdate();
        this.schedule(this.update);

        return true;
    },
    onEnter:function(){
        this._super();
    },
    update:function(dt){
    },
    onTouchesEnded:function (pTouch,pEvent){
        this._jetSprite.handleTouch(pTouch[0].getLocation());
    },
    onTouchesMoved:function(pTouch,pEvent){
        this._jetSprite.handleTouchMove(pTouch[0].getLocation());
    },
    onKeyUp:function(e){

    },
    onKeyDown:function(e){
        this._jetSprite.handleKey(e);
    }
});



MyThirdAppScene = cc.Scene.extend({
    onEnter:function(){
        this._super();
        var layer = new MyThirdApp();
        layer.init();
        this.addChild(layer);
    }
})

 

The bulk of this code is very similar to previous code with one major difference.  In previous examples, we created a layer, then added a color layer to it.  In this case, we simply extend from LayerColor and add our children directly to ourselves.  There is very little functional differences between the two approaches, except this one is a bit more concise.  Now let’s take a closer look at our code.

 

In our init() method, we init with a black background colour.  We then create our JetSprite object and tell cocos2D that our layer handles touch and keypad events.  In cocos2D, input is handled at the layer level, and setting these two values will result in touch and keyboard delegates being added to our object so we can handle IO events.  We then position our layer, add our _jetSprite as a child positioned in the center of our layer.  The scheduleUpdate() call is very important.  This will result in our JetSprite’s update() function getting called every frame.  If you don’t call this method, or sprite wont do anything!

 

Next up is onEnter() which is what is called when a layer becomes the active layer.  In our case, this call is very important, as it ( in cc.Layer.onEnter ) is where the touch and keyboard delegates are actually attached to our layer!  If you remove the call to this._super(), you will not receive any keyboard and mouse events!

 

Now that we are wired up to receive touch and keyboard events, we need a couple methods that will be called when they occur.  In our case we are going to use ccTouchesEnded, ccTouchesMoved, keyUp and keyDown.  When an event occurs, these methods will be called, which in turn simply call the appropriate method on our JetSprite.

 

There are two things to be aware of here.  There are ccTouch____ and ccTouches____ versions of events; to my experience, the ccTouch____ version will never be called!  If you want to handle touch/mouse events, use the ccTouches version.  The next is the way we are handling key presses,  right now since we used keyDown, holding down the key will result in it being called over and over.  If however you want to respond only once per key hit ( regardless to if it is held down or not ), use keyUp instead.

 

We also need to make sure our new classes are included in our project.  Just like the last tutorial, make the following changes to the bottom of cocos2d.js

appFiles:['MyThirdApp.js','JetSprite.js']

 

We also need to update the Scene name in main.js

var myApp = new cocos2dApp(MyThirdAppScene);

Here is the end result of all of our code.  Mouse over the canvas and the mouse will follow you.  Left and right arrow will rotate the sprite, while clicking (either button) on the left half of the screen will point the jet up, while clicking the right half will point the sprite down.

 

 


 

If you are running Chrome be aware the clicking doesn’t appear to work.  It is actually working, the sprite is being rotated.  However it is also triggering a mouse move event, immediately snapping the sprite back to where you mouse pointer is! Smile

 

As always, you can download the whole project right here.  It includes a zip of the cocos2D version I used, in case you have trouble working with the current release.

 

 

Read Tutorial 5

Programming


15. June 2012

 

I have recently become more and more interesting in HTML5 game development.  However,HTML5_Logo_256 upon initial investigation I realized there are an absolute ton of libraries and tools out there.  Some of them are amazing, others… not so much.  During my research I put together notes on the key libraries, tools, books, frameworks and IDEs used for HTML5 development.  This is the results of that research.

 

So, if you are looking to get into HTML5 game development, this page could be a very good place to start.

 

This list is by no means complete, it just represents the best of what I have found so far.  If you have recommendations for inclusion ( especially for the links section! ), please let me have them!  There are links as well to non-game related frameworks like Backbone.js, YUI, Mustache, etc. I am intending to do some game tool development in JavaScript for an upcoming RPG project, so those are there as much for my use as anything.

 

I hope you find it handy.

 

Links of interest for HTML5 game developers.

Programming


8. June 2012

 

Just a quick note to say I’ve organized my recent Cocos2D posts into a traditional tutorial series, like this site’s C++ and PlayStation Mobile tutorials.  You can now access them from the right hand navigation list, or by clicking here

 

Right now we are at 3 tutorials, plus one related post.  More tutorials are on the way.

News


GFS On YouTube

See More Tutorials on DevGa.me!

Month List