3
\$\begingroup\$

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.

asked Mar 21, 2012 at 2:36
\$\endgroup\$
1
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ Commented Mar 21, 2012 at 3:29

2 Answers 2

1
\$\begingroup\$

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.

answered Mar 21, 2012 at 8:55
\$\endgroup\$
-2
\$\begingroup\$

(Math.random() * 32767) / 32767 - induced giggles. :)

(Not very helpful I know but hey, ‘we can’t all be Astronauts’)

answered Dec 23, 2017 at 10:12
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This looks a comment to RoToRa's answer - just comment there, and or post your own answer. \$\endgroup\$ Commented Dec 23, 2017 at 10:29

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.