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.
I'm not sure if extJS is the right thing for this.
ReplyDeleteBut with some easy semaphores you can make the tasks that they don't overrun theirself
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