Subtitel

A blog by Juri Urbainczyk | Juri on Google+ | Juri on Twitter | Juri on Xing

Saturday, December 22, 2012

ExtJS Game of life – testing the Ext.draw library


I always wanted to check out the ExtJS graphics library (Ext.draw) and thus I decided to implement the Game of Life in ExtJS as a kind of prototype. The following screenshot shows the results, a running game of life on a 40x40 grid.

A running 40x40 game of life in ExtJS
 
Details about the Game of life can be found here: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

How can it be implemented in ExtJS? Since I wanted to test the ExtJS drawing functions, I chose an Ext.draw.Component as the basis. All grid cells are painted inside this component by creating a “sprite” for each grid. When a grid is alive I simply change the color of the sprite to black, otherwise I change it to white.

Now, that’s how the Ext.draw.Component is initialized. As you can see, it is created with one item (sprite) which just paints the blue border around the whole component.

var drawComponent = Ext.create('Ext.draw.Component', {
     viewBox: false,
     margin: '10 10 10 10',
     height: (DIMSIZE*(SPRITEWIDTH+SPRITEBORDER))+8,     
     width: (DIMSIZE*(SPRITEWIDTH+SPRITEBORDER))+8,
     items: [{
         type: 'rect',
         width: (DIMSIZE*(SPRITEWIDTH+SPRITEBORDER))+4,
         height: (DIMSIZE*(SPRITEWIDTH+SPRITEBORDER))+4,
         x: 0,  y: 0,
         stroke: 'blue',    
         'stroke-width': 2                    
     }]
}); 

In order to add new sprites to the Ext.draw.Component, you can just call the add() method. I noticed, that it was necessary to change one of the sprite’s attributes in order to make it appear on screen, so I just change the sprite type to ‘rect’ (as it was before). Of course, we have to implement a loop in order to create all necessary sprites.

myRect = drawComponent.surface.add({
     type: 'rect',
     width: SPRITEWIDTH,
     height: SPRITEWIDTH,
     fill: Ext.draw.Color.create(0, 0, 0, 1),
     x: 3+(x*(SPRITEWIDTH+SPRITEBORDER)),
     y: 3+(y*(SPRITEWIDTH+SPRITEBORDER)),
     xpos : x,
     ypos : y
});          

myRect.setAttributes({
     type: 'rect'
}, true);

The next picture shows which ExtJS classes are used to build the GUI:

ExtJS components in the game of life GUI

Furthermore, we need a timer, because we have to calculate the next generation and paint it again an again. This is achived with an ‘task’ object as seen in this piec of code:

var task = {
     run: function(){

         newGeneration();
         paintGeneration();              
     },
     interval: 500
}   

As you can see, the task interval (the time between to calls of the loop) is quite big: half a second. As a matter of fact, I learned that the interval could not become any smaller on my machine (and with Firefox or Chrome). Otherwise, the next run of the cycle would be called before the former generation was completed, botching the whole game. With a 40x40 grid, we already need 1600 sprites which seem to quite a lot, since the creation of the sprites takesca. 5 seconds. When I increase the grid size the time needed to instantiate the game grows heavily and the program becomes unusesable. 

As you can see, the ExtJS draw functions are not very fast and not well suited to graphics programming like this (I assume it is rather meant to be used for charting).

Thus, I decided to port the whole program to HTML5 canvas (or rather the grid part), which I will explain in a later blog post, so stay tuned.

2 comments:

  1. I'm not sure if extJS is the right thing for this.

    But with some easy semaphores you can make the tasks that they don't overrun theirself

    ReplyDelete
  2. Yes, you are right. I was searching for a task which would take the Ext draw functions to their limit. Meanwhile there is a canvas port - I'll write about that in some of my upcoming posts.

    ReplyDelete