enchant.js Developers Blog

The Latest News on the HTML5 + JavaScript Game Engine enchant.js

Archive for the ‘Report’ Category

I woke up this morning with a lot of energy, so I sat down and packaged the Group class!

I’m now able to write a program like the one you see below.

group = Group.new
bear = Bear.new(32,32,"chara1.gif")
label = Label.new("Hello enchant.js");
button = Button.new(100,100,"Button");
group.addEventListener('enterframe'){|e|
self.y+=1
}
group.addChild(bear)
group.addChild(label)
group.addChild(button)
Game.rootScene.addChild(group)

Now, we can make the entire program we wrote previously move down!

Let’s take a look at what we changed in the HotRuby.js source code. As usual, we’re expanding HotRuby.prototype.classes.

Group is entity that makes another entity into a group, so it succeeds the Entity class.

"Group" : {
"initialize" : function(recver, args) {
recver.__instanceVars.entity = new Group();
HotRuby.prototype.classes.extendRubyClass("Group","Entity");
},
"addChild" : function(recver, args) {
recver.__instanceVars.entity.addChild(args[0].__instanceVars.entity);
},
"removeChild" : function(recver, args) {
recver.__instanceVars.entity.removeChild(args[0].__instanceVars.entity);
}
},

By gaining Group, we’ve acquired a simple but powerful ally.

In enchant.js techniques to make scrolling backgrounds into groups and control the priority of entities displayed on the screen are often used.

With what we’ve learned so far, I’ve been able to transport the majority of the games I’ve made with enchant.js.

We also use Scene’s push and pop quite frequently. enchant.js scenes are organized in stacks, with scenes on top of one another. When on an upper scene, events in the scenes below will be suppressed.

For instance, the processing that brings up “START” and stops the screen is performed using scene stacks.

In order to bring this to life, we’ll need to tweak the Game class.

"Game" : {
"assets" : function(recver, args) {
return args[0];
},
"rootScene" : function(recver, args) {
return HotRuby.prototype.classes.
newRubyObject("Scene",{scene:game.rootScene});
},
"pushScene" : function(recver, args) {
game.pushScene(args[0].__instanceVars.scene);
},
"popScene" : function(recver, args) {
game.popScene();
}
},

This time it’s super easy. The Scene class is already defined as the HotRuby class, all you need to do is deliver __instanceVars.scene as it is from “args” to Game.pushScene.

This will allow you to create a program like the one below.

testScene = Scene.new
startButton = Label.new("Tap to start!");
startButton.addEventListener('touchend'){|e| //Pop scene when label is clicked
Game.popScene()
}
startButton.x = 30
startButton.y = 140
testScene.addChild(startButton)
Game.rootScene.addChild(group)
Game.pushScene(testScene)

Here, testScene has been added above the previous scene. When you click “Tap to start!,” testScene is popped, and group moves.

We’ve now completed most of the preparations necessary to make a game. We’re still missing the Map class wrap, but as this is pretty advanced we’ll leave it for later.

We haven’t covered everything, but this should let us make a game. Next time, we’ll try making a simple game with HotRuby!

  • Comments Off
  • Filed under: Report
  • Our story about using Ruby on enchant.js with HotRuby is nearing its climax. Up until now we’ve focused on whether enchant.js can be called up from Ruby, but this time I tried to actually package it with class succession.

    Corrections to HotRuby.protype.classes were among the main additions to the code. Up until now we did anything and everything with Sprites, but here we’ve added Scene and Entity classes.

    Entity is the parent class for Sprite, and I prepared a Label for other classes using Entity.

    "Sprite" : {
    "initialize" : function(recver, args) {
    var sprite = new Sprite(args[0],args[1]);
    recver.__instanceVars.entity = sprite;
    HotRuby.prototype.classes.extendRubyClass("Sprite","Entity");
    },
    "image" : function(recver,args) {
    return HotRuby.prototype.classes.
    newNativeObject("String",
    recver.__instanceVars.entity.imageName);
    },
    "image=" : function(recver,args) {
    recver.__instanceVars.entity.imageName=args[0].__native;
    return recver.__instanceVars.entity.image=
    game.assets[args[0].__native];
    }
    },
    "Label" : {
    "initialize" : function(recver, args) {
    var label = new Label(args[0].__native);
    recver.__instanceVars.entity = label;
    HotRuby.prototype.classes.extendRubyClass("Label","Entity");
    },
    "text" : function(recver,args) {
    return HotRuby.prototype.classes.
    newNativeObject("String",
    recver.__instanceVars.entity.text);
    },
    "text=" : function(recver,args) {
    return recver.__instanceVars.entity.text=args[0].__native;
    }
    },
    "Entity" : {
    "initialize" : function(recver, args) {
    var obj = HotRuby.prototype.classes["Entity"];
    'x y scaleX scaleY rotation frame'.split(' ').forEach(function(prop) {
    obj[prop] = function(recver,args){
    return recver.__instanceVars.entity[prop];};
    obj[prop+"="] = function(recver,args){
    recver.__instanceVars[prop]=args[0];
    return recver.__instanceVars.entity[prop]=args[0];};
    obj["@"+prop+"="] = function(recver,args){
    recver.__instanceVars[prop]=args[0];
    return recver.__instanceVars.entity[prop]=args[0];};
    obj[prop+"+="] = function(recver,args){
    return recver.__instanceVars.entity[prop]+=args[0];};
    obj[prop+"-="] = function(recver,args){
    return recver.__instanceVars.entity[prop]-=args[0];};
    obj[prop+"*="] = function(recver,args){
    return recver.__instanceVars.entity[prop]*=args[0];};
    obj[prop+"/="] = function(recver,args){
    return recver.__instanceVars.entity[prop]/=args[0];};
    obj[prop+"++"] = function(recver,args){
    return recver.__instanceVars.entity[prop]++;};
    obj[prop+"--"] = function(recver,args){
    return recver.__instanceVars.entity[prop]--;};
    obj[prop+"<"] = function(recver,args){
    return recver.__instanceVars.entity[prop] < args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"<="] = function(recver,args){
    return recver.__instanceVars.entity[prop] <= args[0] ? this.trueObj : this.falseObj;};
    obj[prop+">"] = function(recver,args){
    return recver.__instanceVars.entity[prop] > args[0] ? this.trueObj : this.falseObj;};
    obj[prop+">="] = function(recver,args){
    return recver.__instanceVars.entity[prop] >= args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"=="] = function(recver,args){
    return recver.__instanceVars.entity[prop] == args[0] ? this.trueObj : this.falseObj;};
    });
    },
    "setupEventListener" : function(recver,args) {
    var classObj = ruby.__proto__.classes[recver.__className];
    var hr = this;
    'enterframe touchstart touchend touchmove'.split(
    ' ').forEach(function(eventName){
    if(classObj[eventName]){
    var func = function() {
    var hr = arguments.callee.hr;
    var proc = arguments.callee.proc;
    hr.runOpcode(
    proc.__opcode,
    proc.__parentStackFrame.classObj,
    proc.__parentStackFrame.methodName,
    recver,
    hr.nativeAryToRubyObjectAry(arguments),
    proc.__parentStackFrame,
    true);
    };
    func.hr = hr;
    func.proc={};
    func.proc.__parentStackFrame=ruby.topSF;
    func.proc.__opcode= classObj[eventName];
    recver.__instanceVars.entity.addEventListener(
    eventName,func);
    }
    });
    },
    "addEventListener" : function(recver,args) {
    var func = function() {
    var hr = arguments.callee.hr;
    var proc = arguments.callee.proc;
    hr.runOpcode(
    proc.__opcode,
    proc.__parentStackFrame.classObj,
    proc.__parentStackFrame.methodName,
    recver,
    hr.nativeAryToRubyObjectAry(arguments),
    proc.__parentStackFrame,
    true);
    };
    func.hr = this;
    func.proc = args[1];
    recver.__instanceVars.entity.addEventListener(
    args[0].__native,
    func);
    },
    },

    As you can see, up until now most of the Sprite contents was divided up as Entity shared contents, and only image (Sprite-native parameter) is treated as a Sprite class.

    Also, Label (which like Sprite has the superclass Entity) only provides elements distinct to the “text” Label.

    HotRuby class succession is realized with functions like what you see below:

    extendRubyClass:function(subClass,superClass,recver,args){
    //Ruby class succession
    var subClass = HotRuby.prototype.classes[subClass];
    var superClass = HotRuby.prototype.classes[superClass];
    superClass["initialize"](recver,args); //Calls up parent class constructor
    //Class construction rewriting only happens once
    if(subClass[superClass+"_done"]){
    return;
    }
    subClass[superClass+"_done"]=true; //Class construction initialization ending flag
    for(var i in superClass){ //Copies parent class members (succession)
    if(!subClass[i]){
    subClass[i]=superClass[i];
    }
    }
    },

    HotRuby’s internal construction is such that all included classes are all stored as associative arrays in HotRuby.prototype.classes.

    For succession, all you need to do is copy the elements of the super class. At this point, it’s still a fairly whatever-works sort of construction, so it doesn’t work when not calling up the superclass constructor (in normal object orientation the super class constructor is not called up unless explicitly stated).

    In any event, here I was able to package Label. The Ruby code looks something like this:

    class Bear < Sprite
    def initialize w,h,image
    super(w,h)
    self.image = Game.assets(image)
    self.y=50
    self.setupEventListener();
    end
    def enterframe
    self.x+=1
    end
    end
    bear = Bear.new(32,32,"chara1.gif")
    label = Label.new("Hello enchant.js");
    Game.rootScene.addChild(bear)
    Game.rootScene.addChild(label)

    The “Hello enchant.js” displayed in the opening screenshot is based on work of the Label class.

    Of course, you can set both Label and Sprite to subclass event handlers.

    class Button < Label
    def initialize x,y,text
    super text
    self.x = x
    self.y = y
    self.setupEventListener();
    end
    def touchend
    self.text="Thank you!"
    end
    end
    button = Button.new(100,100,"Tap Here");
    Game.rootScene.addChild(button)

    If you click the “Tap Here” label displayed on the screen, the display should change to read “Thank you” courtesy of the program you just wrote.

    Seems like we’ve picked up enough of the essentials to create a game. You can probably create a simple game with this info alone.

    If we prepare the Group and Map classes, we should be able to put together most any enchant.js game.

    The Group class can be packaged with comparative ease, but he Map class looks a bit tricky. Won’t know until we try though, will we? It might be fairly easy with Ruby’s two dimensional arrays.

    Let’s take a breath and move on to the next challenge!

  • Comments Off
  • Filed under: Report
  • Can enchant.js be used on Ruby? Yesterday’s experiment continues. This time I revised HotRuby.js while analyzing HotRuby.

    If you take a look at the guts of HotRuby.js, you realize that it’s rather rough. It’s like the classes are just simply packaged and that’s it.

    The packaging in this area is around line 1110 of HotRuby.js.

    HotRuby.prototype.classes = {
    "Object" : {
    "==" : function(

    In order to make it respond to enchant.js, it’s relatively easy to fiddle around with this area.

    Let’s forget about game.preload for the time being and try packaging the Sprite class.

    "Game" : {
    "assets" : function(recver, args) {
    return args[0];
    }
    },
    "Sprite" : {
    "initialize" : function(recver, args) {
    var sprite = new Sprite(args[0],args[1]);
    game.rootScene.addChild(sprite);
    sprite.image=game.assets['andy.gif'];
    recver.__instanceVars.sprite = sprite;
    var obj = HotRuby.prototype.classes["Sprite"];
    //Package each parameter's operator manually
    //Still a bit rough, but puts into action
    'x y scaleX scaleY rotation frame'.split(' ').forEach(function(prop) {
    obj[prop] = function(recver,args){
    return recver.__instanceVars.sprite[prop];};
    obj[prop+"="] = function(recver,args){
    recver.__instanceVars[prop]=args[0];
    return recver.__instanceVars.sprite[prop]=args[0];};
    obj["@"+prop+"="] = function(recver,args){
    console.log("hoge");
    recver.__instanceVars[prop]=args[0];
    return recver.__instanceVars.sprite[prop]=args[0];};
    obj[prop+"+="] = function(recver,args){
    return recver.__instanceVars.sprite[prop]+=args[0];};
    obj[prop+"-="] = function(recver,args){
    return recver.__instanceVars.sprite[prop]-=args[0];};
    obj[prop+"*="] = function(recver,args){
    return recver.__instanceVars.sprite[prop]*=args[0];};
    obj[prop+"/="] = function(recver,args){
    return recver.__instanceVars.sprite[prop]/=args[0];};
    obj[prop+"++"] = function(recver,args){
    return recver.__instanceVars.sprite[prop]++;};
    obj[prop+"--"] = function(recver,args){
    return recver.__instanceVars.sprite[prop]--;};
    obj[prop+"<"] = function(recver,args){
    return recver.__instanceVars.sprite[prop] < args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"<="] = function(recver,args){
    return recver.__instanceVars.sprite[prop] <= args[0] ? this.trueObj : this.falseObj;};
    obj[prop+">"] = function(recver,args){
    return recver.__instanceVars.sprite[prop] > args[0] ? this.trueObj : this.falseObj;};
    obj[prop+">="] = function(recver,args){
    return recver.__instanceVars.sprite[prop] >= args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"=="] = function(recver,args){
    return recver.__instanceVars.sprite[prop] == args[0] ? this.trueObj : this.falseObj;};
    });
    },
    //Accessor for image property is treated and packaged specially
    "image" : function(recver,args) {
    return HotRuby.prototype.classes.
    newNativeObject("String",
    recver.__instanceVars.sprite.imageName);
    },
    "image=" : function(recver,args) {
    recver.__instanceVars.sprite.imageName=args[0].__native;
    return recver.__instanceVars.sprite.image=
    game.assets[args[0].__native];
    },
    //The key here, event listener, is called up and packaged with a block-equipped method
    "addEventListener" : function(recver,args) {
    //Block area extracted as a JavaScript function
    var func = function() {
    var hr = arguments.callee.hr;
    var proc = arguments.callee.proc;
    hr.runOpcode(
    proc.__opcode,
    proc.__parentStackFrame.classObj,
    proc.__parentStackFrame.methodName,
    recver, // Object is recver
    hr.nativeAryToRubyObjectAry(arguments),
    proc.__parentStackFrame,
    true);
    };
    func.hr = this;
    func.proc = args[1]; //Block is accepted as secondary argument
    // Connects to enchant.js event listener
    recver.__instanceVars.sprite.addEventListener(
    args[0].__native,
    func);
    },
    //Used during class definition style. Mentioned later.
    "setupEventListener" : function(recver,args) {
    var classObj = ruby.__proto__.classes[recver.__className];
    var hr = this;
    'enterframe touchstart touchend touchmove'.split(
    ' ').forEach(function(eventName){
    if(classObj[eventName]){
    var func = function() {
    var hr = arguments.callee.hr;
    var proc = arguments.callee.proc;
    hr.runOpcode(
    proc.__opcode,
    proc.__parentStackFrame.classObj,
    proc.__parentStackFrame.methodName,
    recver,
    hr.nativeAryToRubyObjectAry(arguments),
    proc.__parentStackFrame,
    true);
    };
    func.hr = hr;
    func.proc={};
    func.proc.__parentStackFrame=ruby.topSF;
    func.proc.__opcode= classObj[eventName];
    recver.__instanceVars.sprite.addEventListener(
    eventName,func);
    }
    });
    },

    As I wrote in the comments, the key here is the packaging of addEventListener.

    enchant.js’s secret for simply creating games lies in its event driven model.

    If this is clearly defined on the Ruby end of things, we’ve made quite a lot of progress.

    Last time we forcefully pulled things out of the JavaScript end, but in order for the Ruby side to be packaged neatly, this time we’re making use of Ruby’s trademark block method.

    Thanks to these improvements in HotRuby.js, this Ruby code is much more akin to enchant.js.

    bear = Sprite.new(32,32)
    bear.image = Game.assets "chara1.gif"
    bear.addEventListener('enterFrame'){|e|
    self.x+=1
    }

    You can display these bears and animate them to move to the right. Quite like enchant.js on JavaScript!

    Because functions aren’t a first-level object in Ruby, we can’t deliver nameless functions as in JavaScript. It feels quite unnatural.

    In addition, because Ruby is a programming language with such precisely defined classes, you can think of event processing by overriding class methods, like enterFrame, as the muscle.

    Consider the following example.

    class Bear < Sprite
    def initialize w,h,image
    super(w,h)
    self.image = Game.assets(image)
    self.y=50
    self.setupEventListener(); //Sets up event listener
    end
    def enterframe
    self.x+=1
    end
    end
    bear = Bear.new(32,32,"chara1.gif")

    This is a much easier way of writing things. Of course, part of Ruby’s appeal is the fact that you don’t need to select a way of writing things.

    In the C++-based MFC (Microsoft Foundation Class Library) and the Java-based AWT (Abstract Window Toolkit), it’s normal to package event processing by overriding.

    However, in these types of programming frameworks, the system for receiving events from the OS is not a direct callup method. As a result, some of the elegance is lost, but by calling up setupEventListener within initialize the JavaScript-side events are set.

    I’m no HotRuby expert, so perhaps there’s a slicker method out there (perhaps processing within “super?”).

    However, I feel like our reasons for writing in Ruby and not JavaScript have become clear. When all the objects appearing in a game are expressed as classes, it’s quite elegant and simple to write as event listeners overriding in classes.

    I feel like we’ve approached our goal here. If we make incompatible Scenes, Groups, and Labels functional in Ruby, it’s not that difficult to make an HTML5 game on Ruby and enchant.js.

    I’ve only just started to read the HotRuby source code. If you know of a more elegant way of handling it, please let me know!

  • Comments Off
  • Filed under: Report
  • JavaScript is a terrific programming language, but it has its limits. In particular, class definitions can be a bit troublesome. This bothers more than a few people. enchant.js’s Class.create reduces the problem, but it’s still not ideal.

    But Japan has its own kickass programming language: Ruby.

    One day I thought to myself: enchant.js is already quite easy to use, but wouldn’t Ruby make it even easier? In order to use Ruby in a browser you can try stuff like JSRuby or HotRuby. Of course you can also use JRuby in Java and express as an applet, but this won’t work on smartphones.

    In both cases there doesn’t appear to be a prototype out yet. However, it appears that JSRuby attempts to use the Ruby interpreter in JavaScript, and that HotRuby uses YARV from Ruby 1.9 in JavaScript, with the Ruby compiler on the server.

    JSRuby still lacks some essential constructions, and the appeal of Ruby doesn’t fully come through. With that in mind, this time I used HotRuby and tried to see what would happen when I plugged enchant.js into it.

    For starters, I installed HotRuby to the server. For HotRuby to work I had to first install Ruby 1.9.0. It had to be 1.9.0, specifically. Otherwise, VM: Instruction will not be available for use.

    This is an important class that calls up the YARV compiler from Ruby. After this, all I had to do was install HotRuby on the web server.

    Next up was the actual Ruby code connecting. This turned out to be rather tricky.

    In the case of HotRuby, you first send the Ruby code to the server, compile and receive the YARV interim code. We’re still at the testing stage now, so I decided to basic enchant.js initialization on the JavaScript side.

     enchant(); //Initialize enchant.js
    window.onload=function(){
    game = new Game(320,320);
    game.preload("andy.gif"); //Load Android image
    game.onload = function(){
    andy = new Sprite(16,16); //Make Android sprite
    andy.image = game.assets["andy.gif"];
    andy.setXY = function(x,y){this.x=x;this.y=y;} //Make setter to easily call up from Ruby
    game.rootScene.addChild(andy);
    ruby = new HotRuby(); // Initialize HotRuby
    ruby.runFromScriptTag('http://shi3z.yier.in/compileRuby.cgi'); //Call YARV compiler installed in server
    setTimeout(function(){ //Executes when compile is finished
    game.rootScene.addEventListener('enterframe',function(){
    // Directly calls up compiled interim code object
    ruby.invokeMethod(ruby.topSF.localVars[2], "enterFrame",
    [], ruby.topSF, "VM_CALL_ARGS_SPLAT_BIT" , false);
    });
    },1000);
    }
    game.start();
    }

    When this experimental code is executed, the actual Ruby code should turn out something like what you see below.

    <script type="text/ruby"></script>

    When executed, I got the following screen.

    The Android icon gradually moves to the right as time passes. The Ruby-side “andy” object’s enterFrame method is being called up from game.rootScene.addEventListener(‘enter frame’….) on the JavaScript side.

    By the way, HotRuby is quite interesting when considered in the context of a hypothetical Ruby device.

    If you display Ruby in the Safari console, you can understand visually how the internal YARV data is put together.

    For instance, all classes you create are stored in ruby.classes. If you look into each class in more detail, you find that they are stored in the parent class.

    However, because of native access you can access the JavaScript-side object via a global variable called $native.

    However, the appeal of enchant.js lies in its callback-based event model. If you want to do callbacks carefully, you’ll probably have a hard time without compensating in HotRuby.js.

    It’s necessary to set the Ruby side to “divide up this object, this method, to this event,” and kick this into the JavaScript side.

    If you do this, it becomes comparatively easy to use enchant.js on Ruby. Anyone up for the challenge?

  • Comments Off
  • Filed under: Report
  • Greetings! Alan here.

    If you want to learn programming, HTML5 and JavaScript game development is your best bet for getting started.

    Why? Because you can pick up object orientation…a particularly dull aspect of programming…with startling ease. Consider the game “Aegis Commander.”

    In this game you attempt to shoot down missiles from the decks of the Aegis.

    Everything you see displayed on this screen is an object.

    What’s more, it’s ridiculously easy to write a program that uses these objects.

    For instance, smoke appears behind intercepted missiles. Here’s how that smoke class is defined.

    Smoke = enchant.Class.create(enchant.Sprite,{ //Belongs to Sprite class
    initialize:function(x,y){
    enchant.Sprite.call(this,16,16); //Initializes Sprite at 16x16
    this.image = game.assets['smoke.png']; //Sets image file
    stage.addChild(this); //Brings up smoke on stage
    this.x = x-6; //Sets initial coordinates
    this.y = y-4;
    this.scaleX=0.25; //Displays smoke smaller than actual size
    this.scaleY=0.25;
    this.addEventListener('enterframe',this.move); //Animates every other frame with move method
    this.cnt=0; //Resets countdown
    },
    move:function(){
    this.cnt++; //Updates countdown
    if(this.cnt%4==0){ //Animates smoke only once in 4 frames
    this.frame++;
    }
    if(this.cnt&gt;16){ //After 16 frames, self-destructs and removes this object
    this.removeEventListener('enterframe',this.move);
    stage.removeChild(this);
    delete this;
    }
    }
    });

    And that’s it.

    This was thrown together in just about 2 hours to make it in time for a weekly publication. As a result, there was no refactoring, etc…and yet we still ended up with this wonderfully simple expression.

    It wasn’t long ago that it was well nigh impossible to simply program something like smoke puffing up behind a missile.

    Truth be told, I’d be too chicken to try something like this in C++. I know what can happen with malloc and free cost, and the resulting fragmentation.

    However, you don’t need to worry about any of that with today’s JavaScript. Elaborate care is taken to ensure storage of memory on potential user devices, and whereas in the past it was all but essential to write memory control to avoid compromising performance, in JavaScript there’s no need to stress about hardware issues. It will perform just as you wrote it.

    Keio University SFC professor Toshiyuki Masui called this hardware-worry-free programming style “Luxury Programming.”

    With JavaScript and HTML5, this sort of “Luxury Programming” is even possible on cell phones. I’ve been programming for a long time, and this amazes me.

    In the old days programmers were locked in a constant battle with hardware, and the ability to use a machine to its limits was a sign of skill.

    enchant.js was created to easily develop games using HTML5 and JavaScript along the lines of simple BASIC games. However, because web browsers and hardware have evolved so much, you can now easily write without worrying about the processing that would have been hell on BASIC.

    Of course, this doesn’t mean that we’re completely free of limits. But up until now it was practically impossible to experience the process of creating a complicated, object oriented game like this.

    For example, if trying to learn object orientation with Ruby or Python, the “object” in object orientation didn’t feel like a box with numbers in it or a vessel to put a method in.

    At its heart object orientation was born from an image of objects exchanging messages and in the process acting harmoniously.

    What we call methods today used to be called “messages,” and were born from an image of messages sent between objects.

    The connection between words and images is particularly important for beginners. It is far easier to understand “objects” as things like explosions and missiles, rather than something intangible.

    Class succession and polymorphism, duck typing, and other difficult-to-grasp concepts become clearer in games.

    Moreover, without any particular trickery, the code you write becomes the image you see. “It turned out just as I expected.” This is exactly the experience we want beginners to have.

    A game programmer can be born in just half a day, and his or her skills can grown from there. Think of this as the fast lane towards becoming an HTML5/JavaScript programmer.

    Here at ARC, we’ve seen complete amateurs able to write programs that functioned just as they hoped after less than a day of studying JavaScript programming.

    The act of turning programming into a puzzle, a fun riddle to be solved, allowed them to make programming their own.

    We’re currently investigating the possibility of creating educational programs to help beginners learn programming basics through enchant.js.

    We’ll give an educational event or two a try. If it goes well, we’ll open the program up so that anyone can host an event for their friends and coworkers in their hometown.

    In any event, JavaScript is super easy and fun. That much is clear.

  • Comments Off
  • Filed under: Report
  • enchant.js meetup! held in Tokyo.

    21 Oct.
    Enchant.js meetup that was held in Tokyo
    This meetup came to more than 180 visitors.

  • Comments Off
  • Filed under: Report
  • about “enchant.js”

    enchant.js is an HTML5 + JavaScript based game engine. It is a standalone library that enables cross-platform application development for PC, Mac, iPhone, iPad, and Android from just 30 KB of source code.

    enchant.js was developed at Ubiquitous Entertainment Inc.'s Akihabara Research Center, and released April of 2011. Nearly 200 games have been created in its first two months of release, making it the world's most-used HTML5 game engine.

    enchant.js Official Website

    Category

    facebook Like