enchant.js Developers Blog

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

Archive for November, 2011

Greetings! shi3z here.

This is my three-day cram course, so get ready for a flurry of postings.

Did you give our last session’s final program a go? The spaceship should follow the movements of your mouse cursor.

Of course, the secret to this movement lies in the program.

ship.tick = function(){ // Spaceship will follow your cursor
this.x += (mouseX-this.x)/10;
this.y += (mouseY-this.y)/10;
};

Let’s explain these one at a time.

(continued below)

First of all, the symbol “+=” that follows “this.x” means that the level of the expression to the right will be added to “this.x.” If “this.x+=1,” then this is the same meaning as “this.x=this.x+1.” This notation appears extremely frequently in games, so make a mental note.

Now then, what about this weird variable “mouseX?” As you may have guessed, this is a variable I made for this special game study system.

With this variable, the mouse cursor’s X coordinates are already stored in the computer’s memory. Which means that, yes, “mouseY” indicates the mouse cursor’s Y coordinates.

In this expression, a level of mouseX minus this.x is divided into 10 and into this.x itself.

What on earth are we talking about?

First of all, the program wants to move the spaceship near to the mouse cursor. There are several other methods for this that are easier to understand.

For instance, a program like this:

ship.tick = function(){ // Spaceship will follow your cursor
if(this.x > mouseX) this.x-=10;
if(this.x < mouseX) this.x +=10; if(this.y > mouseY) this.y-=10;
if(this.y < mouseY) this.y +=10;
};

How did the movements change? In the previous code, the ship slipped straight after the cursor.

In this code, after proceeding at a bit of angle, it should follow chase after the cursor horizontally or vertically.

What gives rise to this change in movement? It’s all in the source code.

This latter code, with lots of “if”s, should be easier to understand.

If the spaceship’s position (this.x and this.y) differs from the position of the mouse, the command tells it to move 10 dots at a time.

However, when for instance the cursor is at an angle other than 45 degrees, the amount of increase for x and y becomes 10 each, and the angle of movement eventually changes to 45 degrees.

This movement is extremely awkward and strange.

By comparison, the first example is simple and effective.

What sort of movement does this formula create?

When you subtract the spaceship’s current coordinates from those of the cursor, this becomes the hector stretching between the spaceship and the cursor.

If we add this, the spaceship will suddenly warp to the position of the mouse cursor.

You can try this out with a simpler program.

 ship.tick = function(){ // Spaceship will follow your cursor
this.x += mouseX-this.x;
this.y += mouseY-this.y;
};

Getting rid of the division by 10, the spaceship should suddenly move as though clinging to the cursor.

By dividing by ten, the closer the spaceship drew to the cursor the more precise its movements became, creating that unique sliding effect.

Why does this smooth movement agree with us?

For one thing, it has an air of reality about it.

It resembles the actual movement of real-life objects rather well.

Cars physically cannot stop abruptly. They must first drop their speed bit by bit.

If you run at full speed and then suddenly stop, you will stumble forward a few steps.

This movement contains that same sort of sensation.

Now then, it’s a bit dull with just a spaceship, isn’t it? Let’s try some other objects as well.

A rock seems appropriate. A “for” loop should be easy to use here.

function onLoad() { var ship= new Image('img/starship.png');
ship.tick = function(){ // Spaceship will follow your cursor
this.x += (mouseX-this.x)/10;
this.y += (mouseY-this.y)/10;
};

for(i=0;i<10;i++){
rock = new Image('img/rock.png');
rock.x = Math.random()*320;
rock.y = Math.random()*480;
}
gameStart();
}

When you execute, the results should be something like this:

A rock is puttering around a white expanse of space. It’s an asteroid.

However, nothing happens if this spaceship bumps into the asteroid. That’s rather boring, so let’s make it so that the game ends when the ship hits the asteroid.

function onLoad() {

function onLoad() {
var ship= new Image('img/starship.png');
ship.tick = function(){ // Spaceship will follow your cursor
this.x += (mouseX-this.x)/10;
this.y += (mouseY-this.y)/10;
};

ship.onHit = function(){ // Crashed!
alert("CRASHED!");
}

for(i=0;i<10;i++){
rock = new Image('img/rock.png');
rock.x = Math.random()*320;
rock.y = Math.random()*480;
}
gameStart();
}

However, this is a bit of a persistent program, and when you crash, the “CRASHED” warning will stay open.

In order to stop it, you need to move the cursor to the correct position and reload.

“alert” is one of the commands (functions) that JavaScript possesses, and has the function of displaying warning windows. The “ship.onHit” function is another special function called up by the system, summoned when the object hits another Image.

Here, when the “ship” hits another object, the game opens the warning window.

With this as your base, give the following problems a try. See you again soon!

1)  Line up “rock” with a “for” loop without using random numbers, and create an electric pen of nervousness game!

2) Define rock.tick and try moving the meteorites too.

3) Try making both moving and non-moving meteorites.

  • Comments Off
  • Filed under: Tutorial
  • Greetings! enchant.js Technology Evangelist Eric here.

    The gears in my biological clock had barely greased themselves back into Japan time when another flight across the big blue yanked them out of whack once again. Fortunately, the hemming and hawing of a confused Circadian rhythm found solace in the unexpected warmth of a little city called Boston.

    Yes, we (the “we” being Akihabara Research Center director Ryo Shimizu, fellow enchant.js-er Hidemy, and me) were in Boston to take part in the monthly Boston HTML5 Game Development Meetup!

    By pure chance, our presentation marked the one year anniversary of the meetup, which is co-organized by Pascal Rettig and Darius Kazemi (who also organized this month’s New Game Conference).

    The event was hosted by the lovely folks at MocoSpace in their gloriously creaky 100-year old office. The event organizers were kind enough to grant us the first speaking slot of the evening. We started out with some live coding from Mr. Shimizu:

    After a discussion of enchant.js’ origins, development, and key features, I took the stage to present a more detailed look at what the engine has to offer.

    You may be looking at the photos and thinking, “this meetup looks awfully small.” If so, you’re correct: just over 20 people were in attendance. But conversely, this intimate setting proved a boon. Nearly everyone present asked at least one question, and the resulting discussion felt like just that: a conversation with real back and forth.

    Best of all, we got not one, not two, but three invitations for future speaking engagements. Boston, could you be any friendlier?

    After our talk we enjoyed a presentation from Microsoft’s Chris Bowen about IE9′s use of HTML5…as well as some tantalizing glimpses of still-secret Windows tech.

    And what would an event be without swag? We’re pleased to report that all but two of the enchant.js t-shirts we brought went home with attendees.

    I wish I could say that the evening ended with a bang. Unfortunately, it ended with some rather dubious crabcakes from a legal seafoodery.

    All the same, a pretty darn good evening.

    We’ll be on hand next month at DevCon5 in Santa Clara. Hope to see you there!

  • Comments Off
  • Filed under: Event
  • Greetings! shi3z here.

    The other day I had fun as both a guest and a participant at the Pacific Rim Mini Game Development Olympics, but I felt a bit bad about winning the Grand Prize. I’ve got lots of experience, and knew what to do, and next time I think it best that I not take part.

    But I had a lot of fun, both with the event and the mini games themselves.

    I hope to do it again.

    However, most of my programmers had reached the limits of their energy, and I was left with only two.

    In a fix, I decided to take it upon myself to teach Hidemy…who had zero experience in game programming…the basics in three days and send her to participate in the contest. Would this work?

    Continued below:

    In fact, the “Super Easy Programming” guides were originally put together so that Hidemy would be able to learn the basics.

    Truth be told, I wasn’t sure how quickly an English Literature major like her could pick it up.

    Last night, after we had all eaten, I said, “After you’ve read Alan’s guide, make a program of your own and send it in.”

    This was 8 o’clock.

    Then, to my amazement, at 12 o’clock…just 4 hours later…Hidemy sent the following in:

    //Flower
    function flower(){
    for(i=0;i<180;i++){
    if( i<10 ){
    move(2);
    turn(1);
    }if( i>170 ){
    move(2);
    turn(1);
    }else{
    move(1);
    turn(1);
    }
    }
    }

    function onLoad(){
    logo.init();
    penDown();
    for(j=0;j<9;j++){
    flower();
    turn(90);
    }
    penUp();
    }

    She sent in two others as well:

    I was stunned at the speed with which she absorbed this information.

    I thought to myself, “This just might work.”

    With that in mind, I decided to start the guide to game programming.

    Alan’s guide is easy to understand but takes a while to get through, so I’ve gather below a .zip file of everything you need to make a game.

    Please download the file below.

    Game Basics: (game.zip)

    It’s similar to the files that Alan came up with.

    The only real difference is the presence of a file called “game.js” and an “img” folder.

    First, open main.js in the text editor.

    For those of you who’d rather use a browser, here’s a link:

    http://junk.wise9.jp/game/

    Our first program is to display a game character.

    function onLoad() {
    banana = new Image('img/banana.png'); // The character appears here
    }

    The key point of this program is “new Image.”

    This command creates a new image and inserts the variable “banana.”

    This “Image” is a new program I defined specifically for the purpose of teaching game programming. In JavaScript, you can call up clusters of programs from within another.

    We call these clusters of programs “classes” or “libraries.” Actually, classes and libraries are in truth something slightly different, but for the moment we won’t worry about that. If you’re interesting you can look it up, or wait for Alan to discuss it in his series.

    Game development is filled with dull and troublesome tasks. With that in mind, I’ve put together this group of the minimum ingredients necessary to create a game. If this were food, it would be a shrink-wrapped instant meal. We can’t call it gourmet, but anyone can make it and be satisfied. Think of it that way.

    This sort of class contains all the experiences of the programmer who determined the classes. This Image class is one of those.

    Think of it as the secret sauce.

    Now then, see what happens when you execute this program!

    Take notice. Game programs are quite intense. That’s why once you hit “Execute Game,” if you want to stop it or rewrite the source code, you’ll have to reload once.

    Even if you reload, your code won’t disappear, so don’t get too anxious.

    Let’s take a look at those strange characters that come after “new Image.”

    new Image(‘img/banana.png’);

    This, as you may have guessed, is the “File name.” “img” points to the file name, and “banana.pg” becomes the file name. The folder and file name are connected by “/”. You’re probably pretty familiar with all this.

    In “banana.png” there’s a picture of a banana. It may not look like a banana, but just have faith in me here. In this zip file, I’ve prepared basic images necessary for creating a game.

    There’s a lot more besides bananas in there, so please take a peak inside. Next, let’s make our character move. A moving banana’s kind of creepy, so let’s change it to a spaceship. Give the following program a shot.

    function onLoad() {
    ship = new Image('img/starship.png'); //A
    ship.tick = function(){ //B
    this.x = this.x + 1;//C Here we define the movement of the spaceship
    };
    gameStart(); //D
    }

    A few new commands have shown up.

    If line A sets the “Image” as a ship, what does line B do?

    As it turns out, JavaScript variables are all object variables, and you can insert not just numbers but programs as well.

    This is the “tick” variable we’ve set inside the ship variable. This “tick” is a special variable called up at regular intervals.

    The contents of “tick” in line C are quite simple.

    this.x = this.x +1 ;

    A version of “this.x” plus 1 is substituted again for “this.x.” This “this” refers to the object defined by the variable, in this the “ship” itself. Just as there is a “this.x,” there is naturally a “this.y.” Why is it structured this way?

    This is a source of considerably frustration when studying math in school.

    You’d think, “This sort of this.x is impossible.”

    However, this is a substitution and not an equation. It’s not meant to solve anything.

    If you’re confused, consider the following image:

    this.x ← this.x +1 ;

    The “this.x” on the right is a past “this.x,” while the “this.x” on the left is a future “this.x.” Remember the direction of the arrow.

    For example, if “this.x” is 0 when this equation is executed, the end product of this.x will be 1.

    The first stumbling block in programming is mixing up substitutions and equations.

    It’s quite easy when you understand it, but if you don’t establish it first people will be get overwhelmed.

    If you give this a try, the spaceship should appear in the center of the screen and move slowly to the right.

    This is because as levels are added regularly to “this.x,” the coordinates of “this.x” change.

    We’re almost done with part one, so finally I’d like to try a program that let’s the character move where you want him to. I’ll explain in detail next time.

    Please give it a try!

    function onLoad() {
    ship = new Image('img/starship.png');
    ship.tick = function(){ // The spaceship will follow your cursor
    this.x += (mouseX-this.x)/10;
    this.y += (mouseY-this.y)/10;
    };
    gameStart();
    }
  • Comments Off
  • Filed under: Tutorial
  • 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+"&lt;"] = function(recver,args){
    return recver.__instanceVars.entity[prop] &lt; args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"&lt;="] = function(recver,args){
    return recver.__instanceVars.entity[prop] &lt;= args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"&gt;"] = function(recver,args){
    return recver.__instanceVars.entity[prop] &gt; args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"&gt;="] = function(recver,args){
    return recver.__instanceVars.entity[prop] &gt;= 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 &lt; 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 &lt; 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+"&lt;"] = function(recver,args){
    return recver.__instanceVars.sprite[prop] &lt; args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"&lt;="] = function(recver,args){
    return recver.__instanceVars.sprite[prop] &lt;= args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"&gt;"] = function(recver,args){
    return recver.__instanceVars.sprite[prop] &gt; args[0] ? this.trueObj : this.falseObj;};
    obj[prop+"&gt;="] = function(recver,args){
    return recver.__instanceVars.sprite[prop] &gt;= 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 &lt; 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
  • Greetings! enchant.js evangelist Eric here.

    Just returned to the comforts of Holiday Inn after day two of New Game Conference. The day saw the handing out of the last of our swag, the shuffling feet of programmers hung over from last night’s blue cocktails, and quite possibly the weirdest cupcakes I’ve ever beheld.

    In case you can’t tell from the photo, they’re glittering. Yeah. I’m not sure how many edible substances *glitter.* Perhaps we’d best save that discussion for another day.

    In any event, vampire cupcakes or not, the day was a good one! It got started with a keynote from Paul Bakaus, CTO of Zynga Germany.

    Paul took us through his own experiences attempting to develop an HTML5 game engine, beginning at a time when no such thing existed. The lack of competition made his work that much more difficult. Vast strides have been made in Canvas, WebGL, and more, but there’s still considerable room for improvement. Paul discussed how web developers rarely make good game developers (and vice versa) and speculated on some of the reasons why HTML5 has not been more widely adopted (his theories: Devs don’t want to learn it, and companies don’t want to ditch versions of IE below 9). HTML5 wasn’t created with games in mind, and as a result the HTML5 game developer’s situation is an exciting, fun, but painful one.  In elaborating on the challenges ahead, he touched on the example of 3D, showing how overdeveloping is not always good. Consider this realistic take on a certain Sesame Street character:

    Later, we checked out “The State of HTML5 Games in Asia” by Robbert Van Os and Chen Qi of spilgames.

    The pair discussed their experiences marketing games internationally and the pitfalls involved in localizing. They boasted the first HTML5 game portal in China, a hugely difficult task given that Facebook is banned outright, the “Great Firewall” makes local hosting a necessity, and fragmented nature of the market. Still, the huge user base…one that is rapidly adopting smartphones…makes the challenge worth it. HTML5 has the potential for hugely expanded opportunities in the future, the pair said.

    Finally, we sat in on “Paladin: 3D Gaming on the Open Web” by Alan Kligman and Bobby Richter.

    The pair shared their own HTML5 game development journey, which all began with a JavaScript demo animation entitled “Flight of the Navigator.” Demos often pushed forward web innovation, they said, but games push it even further. With that in mind, they are actively pursuing Paladin, a project with Mozilla to weaponize the web platform for 3D gaming. At the moment it’s in pre-alpha, but by the end of the year it should be developed enough to make an actual game with it. Alan and Bobby gave us a glimpse of things to come with their minigame “RescueFox.”

    Besides all that, it was a day of chatting, listening, and evangelising like a fanatic!

    For those of you in Boston, be sure to come listen when we speak at this month’s Boston HTML5 Game Development Meetup! Until then, beware of sparkling cupcakes.

  • Comments Off
  • Filed under: Event
  • Greetings! enchant.js evangelist Eric here!

    As you can see in the pic above, I’m currently lurking at the Yerba Buena Arts Center in San Francisco, an art museum cheerfully doubling as a convention center for New Game Conference! Fellow enchant.js-er Hidemy is fighting the good fight alongside me.

    Day 1 started bright-eyed and bushy-tailed at 7 a.m., a grueling situation made less so by the free breakfast.

    There were shiny little stickers scattered hither and yon.

    And naturally, our own swag was amongst the mix!

    Not to mention our logo lurking in the corner of the official game slides, right next to IE, the other gold sponsor…

    The day started with a bang courtesy of Richard Hilleman, creative director at EA, and his keynote “Finding the Missing Pieces: Completing the HTML5 Gaming Platform Picture.”

    A running theme throughout the day was the ongoing challenges laced amongst all the potential of HTML5 gaming. Richard postulated that two developments are key to making the system work: a Killer App, and that hard-to-define “magic” that makes users embrace a new system. Richard pondered whether or not the hugely popular “Angry Birds” might be that killer app. The potential is there, but in his view, the real game-changing pieces are still to come. HTML5’s potential lies in time…the ultimate asset for a user.

    Next, we check out a presentation from Moblyng COO Justin Quimby, who talked about “Hard-won Lessons from the Trenches.”

    After three years of experience, Justin stressed that HTML5 has huge potential but a long way to go. Android and iOS devices are flooding the market, but the testing level for speed and performance remains uneven. He argued for the need for higher standards and more universal quality across the spectrum of devices.

    After a bit of a break, we checked out Bocoup programmer and evangelist Darius Kazemi’s “Fieldrunners HTML5: Bringing a Hit iOS Game to the Web.”

    Darius explored the myriad challenges in porting an iOS hit into HTML5, a process that was projected to take 8 weeks but ended up requiring 12. After rewriting some 24,596 lines of code, Darius urged programmers facing the same task to think hard about their target platform and audience. He reminded us of a tradeoff: highest quality, or widest audience? How can we strive for both?

    Onan Games’s Miguel Angel Pastor covered a similar topic in his “From Apple Store to CWS.”

    Miguel used a platform called Mandreel, the handiwork of his 5-man company (which is also responsible for hit games like Kroll and Bug Village). Again, the porting process was fraught with difficulties, and Miguel closed with a “wish list” of features to solve various HTML5 logistical problems.

    The day ended with a short session from appMobi’s engineer Sam Abadir and his talk on “Extreme Mobile HTML5 Canvas.”

    He discussed how browsers were not built for gaming, and how HTML5 was primarily envisioned as a mobile platform. He revealed how DirectCanvas was created as a temporary stopgap measure, and then introduced his browser extension Mobius (available at appmobi.com/documentation)

    Through it all, we were busy evangelisin’ away on enchant.js, before, during, and after the sessions. Look how serious we were! Ahem.

    The day ended with booze galore at the official conference party, including a blue cocktail in honor of sponsor Microsoft. Hmm…where’s our enchant.js bubbly?

    Stay tuned for a peak into day 2!

  • Comments Off
  • Filed under: Event
  • enchant PRO Beta 2 + 9leap app updated!

    Greetings! Ryohei here.

    We just released enchant PRO Beta 2. Here’s the lowdown on what’s new:

    • Added collada.pro.enchant.js plugin for reading collada format 3D model data
    • Now support lighting and camera position changes for 3D drawing

    Check out the SDK download here (zip format)。You can find the source code at github.

    We’ve also updated the 9leap game app 9leap Beta using enchant PRO SDK!

    You can also check out and test play games made using SDK on the 9leap app!

  • Comments Off
  • Filed under: Release Note
  • Greetings! Ryohei here.

    Check out the official enchant.js site for our just-released Reverse-Lookup Reference!

    • Development Basics
    • Reverse-Lookup Reference
      • Words of Caution
        • Basic enchant.js Template
      • The Basics (Drawigin)
        • Making/Deleting a Scene
        • Making an Image
        • Making Text
        • Making Sound
      • The Basics (Control)
        • Loading Materials
        • Processing Frames
        • Processing Touch (Click)
      • Maps
        • What are Maps?
        • Making a Map
        • Looking for Obstacles on Maps
      • Sprites
        • Moving Sprites
        • Rotating/Expanding/Contracting Sprites
        • Making Sprites Transparent
        • Using the Canvas with Sprites
        • Collision Detection and Sprites
      • Text (Label)
        • Changing Text Color, Font
        • Moving Text
        • Making Text Transparent
      • Other
        • Changing Scene Background Color
        • Changing Game fps
        • Changing Game Screen Magnification
        • Changing Scene Displayed During Loading
        • Preloading Materials

    enchant.js Reference

    Please note that the Japanese file is now called enchant-ja.js.

    If you see bugs in the source code, errors in the translation, or anything else, please drop us a line. You can use issues in github or write a comment on this blog.

  • Comments Off
  • Filed under: Announcement
  • 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