Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

This class is used to draw an old school flame on a canvas element. I'm wondering if there is any way to speed up the fire method. The class is based on old C code.

LayerFire = {
    init : function(options, elem) {
        this.options = $.extend({
                width  : '320',
                height : '240'
            },
            this.options, options);
        this.elem  = elem;
        this.$elem = $(elem);

        // Create our buffer
        this.bufferp = [];
        this.buffer = [];
        var i = this.options.width * this.options.height * 4;
        while (i--) {
            this.bufferp[i] = 0;
            this.buffer[i] = 0;
        }

        // Create the palette
        this.palette = [];
        this.makePalette();

        // Initilize our main loop
        var t = this;
        this.updater = setInterval(function() {t.fire.apply(t);}, 125);
    },
    makePalette : function ()
    {
        // make a nice looking color palette for a flame
        for (i = 0; i < 256; i++) {
            this.palette[i] = Object.create(VideoColor);
        }

        for (i = 0; i < 32; i++)
        {
            /* black to blue, 32 values*/
            this.palette[i].b = i << 1;
            this.palette[i].a = 255;

            /* blue to red, 32 values*/
            this.palette[i + 32].r = i << 3;
            this.palette[i + 32].b =  64 - (i << 1);
            this.palette[i + 32].a = 255;

            /*red to yellow, 32 values*/
            this.palette[i + 64].r = 255;
            this.palette[i + 64].g = i << 3;
            this.palette[i + 64].a = 255;

            /* yellow to white, 162 */
            this.palette[i + 96].r = 255;
            this.palette[i + 96].g = 255;
            this.palette[i + 96].b = i << 2;
            this.palette[i + 96].a = 255;
            this.palette[i + 128].r = 255;
            this.palette[i + 128].g = 255;
            this.palette[i + 128].b = 64 + (i << 2);
            this.palette[i + 128].a = 255;
            this.palette[i + 160].r = 255;
            this.palette[i + 160].g = 255;
            this.palette[i + 160].b = 128 + (i << 2);
            this.palette[i + 160].a = 255;
            this.palette[i + 192].r = 255;
            this.palette[i + 192].g = 255;
            this.palette[i + 192].b = 192 + i;
            this.palette[i + 192].a = 255;
            this.palette[i + 224].r = 255;
            this.palette[i + 224].g = 255;
            this.palette[i + 224].b = 224 + i;
            this.palette[i + 224].a =  255;
        } 
    },
    fire : function() {
        // create a ransom flame at the bottom of the screen
        y = this.options.width * (this.options.height- 1);
        for (x = 0; x < this.options.width; x+=3)
        {
            var random = 1 + (16 * ((Math.random() * 32767) / 32767) + 1.0);
            if (random > 11) {
                /*hot*/
                this.bufferp[y + x] = 200; 
                this.bufferp[y + x + 1] = 255;
                this.bufferp[y + x + 2] = 200;
            } else {
                this.bufferp[y + x] = 50; 
                this.bufferp[y + x + 1] = 20;
                this.bufferp[y + x + 2] = 50;
            }
        }

        // move the flame up                        
        var top = this.options.height;
        if (top > 110)
            top = 110;  
        for (index = 0; index < top ; ++index)
        {
            for (x = 0; x < this.options.width; x++)
            {
                if (x == 0) /* at the left border*/
                {
                    temp = this.bufferp[y];
                    temp += this.bufferp[y + 1];
                    temp += this.bufferp[y - this.options.width];
                    temp /= 3;
                }
                else if (x == this.options.width - 1) /* at the right border*/
                {
                    temp = this.bufferp[y + x];
                    temp += this.bufferp[y - this.options.width + x];
                    temp += this.bufferp[y + x - 1];
                    temp /= 3;
                }
                else
                {
                    temp = this.bufferp[y + x];
                    temp += this.bufferp[y + x + 1];
                    temp += this.bufferp[y + x - 1];
                    temp += this.bufferp[y - this.options.width + x];
                    temp /= 4;
                }
                if (temp > 1)
                    temp -= 1; /* decay */

                this.bufferp[y - this.options.width + x] = Math.round(temp);
            }
            y -= this.options.width;
        }

        // copy the palette buffer to display buffer
        for (x = 0; x < this.options.width; x++)
        {
            for (y = 0; y < this.options.height; y++)
            {
                var index = (y * this.options.width + x) * 4;
                var c = this.bufferp[(y * this.options.width) + x];
                //console.log(c);
                this.buffer[index+0] = this.palette[c].r;
                this.buffer[index+1] = this.palette[c].g;
                this.buffer[index+2] = this.palette[c].b;
                this.buffer[index+3] = this.palette[c].a;
            }
        }
    }
};

Working demo here.

share|improve this question
2  
Do you have a runnable example (perhaps in a jsFiddle)? It's hard to run performance tests on a piece of code that you can't run because you're missing pieces that are need to make it run or don't know what sequence to call it to make it run. – jfriend00 Mar 21 '12 at 3:29

1 Answer

I'm not really an expert on speed optimization, but here are some thoughts:

  • You should keep references/copies to often used objects/values instead of accessing them repeatedly through properties, e.g:

var bufferp = this.bufferp;
var width = this.options.width;
var height = this.options.height;
  • There are some variables (such as x and y which you haven't declared as local with var).

  • What is the point of (Math.random() * 32767) / 32767? As far as I can tell it does nothing.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.