Cocos2D HTML–Porting to the most recent version


I received a comment from a Cocos2D-HTML developer saying that the API is complete for the upcoming beta release, so that I could update the tutorials on this site.  So today I jumped in to see exactly what changed and the answer is quite a bit!  In the process of updating the code to work with the newest Cocos2D code, I went through a great deal of pain tracking down those changes.  This post is to illustrate what has changed, so you don’t have to go through the same process.


The code being ported is the example code from this tutorial.



Filename changes


I encountered a few filename changes ( which JavaScript can make exceedingly annoying to find ).  First off, a few files have had their casing changed, which you won’t notice you are working in Windows, but under Linux you will.  Mostly it’s a matter of files being renamed from cc to CC.  Additionally the folder keypad_dispatcher is now keyboard_dispacter, and CCKeypadDelegate.js and CCKeypadDispatcher.cs have been renamed to CCKeyboardDelegate.js and CCKeyboardDispatcher.cs respectively.


Function changes


ccp is now Point

ccc2/3/4/ is now Color2B,Color3B,Color4B

Layer.setIsRelativeAnchorPoint has been removed.

Director.sharedDirector() is now Director.getInstance();

setIsTouchEnabled() is simply isTouchEnabled()

setIsKeypadEnabled() is now isKeyboardEnabled()


Events have been renamed, for example:

ccTouchesEnded is now onTouchesEnded


The Keyboard delegate have renamed events from:

keyDown and keyUp to onKeyDown and onKeyUp

cc.key.[name] is now cc.KEY.[name]

cc.Touch ( the value passed to touch handlers ) has changed from .locationInView() to .getLocation()

cc.AudioManager.sharedEngine() is now cc.AudioEngine.getInstance();

cc.Log is now cc.log


Bootstrap change


This is where the biggest changes occurred.  The startup process is completely different.  First of all, library loading is no longer the responsibility of the  application, it is instead handled by jsloader.js.


This changes cocos2d.js massively:


(function () {      var d = document;      var c = {          COCOS2D_DEBUG:2, //0 to turn debug off, 1 for basic debug, and 2 for full debug          box2d:false,          showFPS:true,          frameRate:60,          tag:'gameCanvas', //the dom element to run cocos2d on          engineDir:'../cocos2d/',          appFiles:['MyFirstApp.js']      };      window.addEventListener('DOMContentLoaded', function () {          //first load engine file if specified          var s = d.createElement('script');          s.src = c.engineDir + 'platform/jsloader.js';          d.body.appendChild(s);          s.c = c; = 'cocos2d-html5';          //else if single file specified, load singlefile      });  })();

If you haven’t seen this syntax before, it is basically an anonymous function that will execute at the end of declaration ( because of the () it ends in ).  The majority of what is going on here is the creation of a configuration file ‘c’, where a number of settings are, um, set.  tag is the name of the canvas element in your html file, engineDir is where you installed cocos2D to, appFiles are additional files you write ( in addition to your main.js ).  Basically every file you create needs to be added to this array.  It then adds an event that will be fired once the DOM has been populated, which will then create a new <SCRIPT> tag in your HTML document, then pass in the path to the jsloader, which will then load all of the cocos2D libraries, as well as anything your specified in the appFiles array.  Finally it stores the configuration settings in ‘c’ in the newly created script tag.


In a change I disagree with, the framework now forces you to add a file named main.js, which will be called by jsloader at the end of the loading process.  IMHO, this should be added as part of the configuration you set above.  This file replaced AppDelegate.js from the tutorials.  Let’s take a look at the new main.js:

var cocos2dApp = cc.Application.extend({      config:document.querySelector('#cocos2d-html5')['c'],      ctor:function (scene) {          this._super();          this.startScene = scene;          cc.COCOS2D_DEBUG = this.config['COCOS2D_DEBUG'];          cc.setup(this.config['tag']);          cc.Loader.shareLoader().onloading = function () {              cc.LoaderScene.shareLoaderScene().draw();          };          cc.Loader.shareLoader().onload = function () {              cc.AppController.shareAppController().didFinishLaunchingWithOptions();          };          cc.Loader.shareLoader().preload([          ]);      },      applicationDidFinishLaunching:function () {          // initialize director          var director = cc.Director.getInstance();          director.setDisplayStats(this.config['showFPS']);          director.setAnimationInterval(1.0 / this.config['frameRate']);          director.runWithScene(new this.startScene());            return true;      }  });  var myApp = new cocos2dApp(MyFirstAppScene);

Things have changed a fair bit here, but the process is pretty much the same.  First thing to notice is it pulls the configuration data ‘c’ and stores it in the variable config, which is then used to setup cocos2D.  The next major thing to notice is we now create an instance of our app, and pass in the scene to start with. 


Now let’s take a look at the changes to MyFirstApp.cs:

var MyFirstApp = cc.Layer.extend({      init:function()      {          this._super();            var s = cc.Director.getInstance().getWinSize();            var layer1 = cc.LayerColor.create(new cc.Color4B(255, 255, 0, 255), 600, 600);          //layer1.setPosition(new cc.Point(s.width/2,s.height/2));          //layer1.setIsRelativeAnchorPoint(true);          layer1.setAnchorPoint(new cc.Point(0.5,0.5));                      var helloLabel = cc.LabelTTF.create("Hello world", "Arial", 30);          helloLabel.setPosition(new cc.Point(s.width/2,s.height/2));          helloLabel.setColor(new cc.Color3B(255,0,0));          var rotationAmount = 0;          var scale = 1;          helloLabel.schedule(function()              {                  this.setRotation(rotationAmount++);                  if(rotationAmount > 360)                      rotationAmount = 0;                  this.setScale(scale);                  scale+= 0.05;                  if(scale > 10)                      scale =1;              });            layer1.addChild(helloLabel);          this.addChild(layer1);                      return true;      }    });    var MyFirstAppScene = cc.Scene.extend({      onEnter:function(){          this._super();          var layer = new MyFirstApp();          layer.init();          this.addChild(layer);      }  })


Things have changed a bit here.  First we now extend a scene to create a new object MyFirstAppScene.  This in turn creates a layer and adds it to itself.  The onEnter event is called when the scene is activated ( via RunWithScene ).  Otherwise all of our changes are those described above ( function renames, removal, etc… ).



I hope that helps you port your existing code to the newest codebase.  All of the changes are improvements ( except perhaps the whole forced main.js thing, I still don’t like that ), so it is worth the pain.  I hope to get the tutorials all updated shortly, but unfortunately, these changes more or less will result in complete re-writes of 3 tutorials, so it might take a bit! Sad smile

Programming Cocos2D

Scroll to Top