Discord
Login
Community
DARK THEME

Plasma & Fire old school demo effects (little hack to make it fast)

Hi,

I had noticed that using setRGB(A) on images is very slow to mimic a fake screen with 256 color indexed palette as it seems to do a putImageData call for each set pixel you do. But i found a way around the issue by keeping track of my fake screen and doing the putImageData call myself on the context of the canvas of an image object and then drawing the image object with a dragImage, in the draw call. I'm not sure if this is valid usage but at least for faking such screen it seems to work fine and fast.

Using this "trick" / "hack" its possible to create fast demo scene effects running with 356 x 200 fake screens or even higher

To show it in action I've (re)created 2 little old school demo effects, a Fire and a Plasma effect. You can see them in action below.

:embed https://microstudio.io/joyrider3774/fire/

:embed https://microstudio.io/joyrider3774/plasma/

It seems @Loginus had found out the same and made a nice little extension to the image class being fastrgb that does exactly the same but in a much more elegant way this would have probably worked also. You can find his extension here https://microstudio.dev/i/Loginus/fastrgb/

I created updated versions of the effects making use of this extension, the benefit is that the code is a lot cleaner and clearer:

You can change the code a bit to avoid creating the same objects over and over again.

function init() {
    plasma1 = new Uint8Array(dw * dh);
    plasma2 = new Uint8Array(dw * dh); 
    palette = new Uint8Array(256 * 3); // Using a flat array for RGB values
    img = new Uint8Array(width * height * 4); // Using a flat array for RGBA values

    image = new msImage(width, height, false)    
    let context = image.canvas.getContext('2d');
    imageData = context.getImageData(0, 0, width, height);
    
    screen.setPixelated(true);
    initticks = system.time();
    ticks = system.time();
    setPalette();
    calculatePlasma();    
}

function draw() {
    imageData.data.set(img);
    image.canvas.getContext('2d').putImageData(imageData, 0, 0);

    //draw the image to the screen keeping aspect ratio
    screen.drawImage(image,0,0, screen.width);
}

Ah thanks, i was not sure if the canvas or its context could change over time, but thats indeed much better. I prefer the versions with your FastRGB though, its equally fast and much simpler to use / understand.

I also just created a mashup version of the 2 effects together to create fiery text, plasma fiery text, plasma text etc.

https://microstudio.dev/i/joyrider3774/fireplasma/

:embed https://microstudio.io/joyrider3774/fireplasma/

Post a reply

Progress

Status

Preview
Cancel
Post
Validate your e-mail address to participate in the community