Jump to content

Fire on canvas (sailing boat) irregularly


none-9999
 Share

Recommended Posts

Hello everyone, I'm html5 game programmer, I've done some simple games. Javascript pure (no frameworks, it is that I'm stubborn :))
In my current project, a set of sailboats, I need the boat sails to catch fire, and fire make optimized with particles, but not how to detect the pixels that correspond to sail the boat, there is some algorithm, anything?

 

barco1.png

Link to comment
Share on other sites

I'm not sure exactly what you want to achieve but I think you just need a to create particles within the shaded area, which means you just need to know points in that area.

You could create a mask image that overlays each boat, randomly choose a point and test to see if it overlays the mask. So, a black image with a the shaded area above as white. Select a random point, grab the pixel data, if it is white it is valid (in the area), if black then not. This is a fairly naive but easy to implement solution.

As your area is basically triangular you can do a fairly easy point-in-triangle check. So, choose a random point, check if that point is in the triangle, use it if it is or discard and pick another point. To reduce your failures only generate random points in the bounding box around the triangle (you can also use rotation so that your triangle becomes half the square, then you only have a 50% failure rate). You can get your failure rate down further but its more complicated, generating random points inside squares is trivial, not quite so with other shapes. This is helpful, but you can probably find an implementation that will just return points inside a triangle.

Link to comment
Share on other sites

Check out the "isPointInPath()"-method provided by the Canvas API. First you have to define a path on the canvas, then you can check whether a given point is within this path. This is extremely more efficient than checking single pixels by color. 

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isPointInPath

Link to comment
Share on other sites

What makes you think the pointInPath api is quick?

It's a hefty amount slower. Not to mention more awkward to use.

Checking pixels in the pixel data is just an array access, which is quick.

I am surprised the api is that slow though (its a fairly simple check to work out if a point is inside a shape), there might be a better test around.

Link to comment
Share on other sites

With the term "efficient" I didn't mean the quickness of the operation: Using a pixel data array may be faster, but if you use it to extensive, you will possibly have a huge memory problem. Especially if you have to handle multiple mask images.

I've made a screenshot of the problem: What you see are some heap snapshots of a simple test where I am using "getImageData()" multiple times on an 1024x1024 canvas. Storing only 3 pixel data arrays increases your heap memory consumption at about 12 Megabytes

This can be a problem, especially on mobile devices. And if you want to implement pixel perfect mouse collision detection for multiple sprites this way, you possibly have to store hundreds of such arrays.

MemoryLeak.png

Link to comment
Share on other sites

29 minutes ago, JazzAceman said:

I've made a screenshot of the problem: What you see are some heap snapshots of a simple test where I am using "getImageData()" multiple times on an 1024x1024 canvas. Storing only 3 pixel data arrays increases your heap memory consumption at about 12 Megabytes

This can be a problem, especially on mobile devices. And if you want to implement pixel perfect mouse collision detection for multiple sprites this way, you possibly have to store hundreds of such arrays.

I don't get why you're using an example of 3 arrays much less hundreds. Even if you decide you can't use the alpha channel, you can still represent 16 million different objects in a single such image array, with the simple assumption that each pixel colour represents one thing (seems reasonable for the cases discussed). For a 1024x1024 image that's around 4MB, and you could probably get away with slightly courser than that.

I'm not saying it's a good idea, but it doesn't seem as bad as you're making it out to be.

I would also lean towards testing a polygon using a custom library function though. I don't know why Chrome is so slow (havn't tried Matt's link with other browsers) but this is a case where we may know something about the problem the browser may not be optimising for - we can limit outselves to polygonal areas while it looks like the library function has to handle any paths (lines, splines, arcs...). I doubt a pixel perfect fit is required, the polygon just has to be close enough... (I say polygon rather than triangle as my hunch is multiple triangles may not be better then hittesting fewer shapes with more points/sides)

Link to comment
Share on other sites

  • 1 month later...

I think this is being over complicated. Unless the particles NEED to be generated exactly within the bounds of the sail and NEED to be randomly distributed within the sail, why not just:

1. Pick several points (x, y) for each sail and store them with the ship data

2. When it is time for the sail to ignite, generate particles randomly around each of those points, ie:

// particles stored here
var particles = [];

var pointsArray = [
    // array of a few coordinates that are within the bounds of the sail
];

for (var point in pointsArray) {
    
    // generate random coordinates near point
    var x = pointsArray[point].x + randomBetween(-50, 50);
    var y = pointsArray[point].y + randomBetween(-50, 50);
    
    // make a particle
    particles.push(new Particle('fire', x, y));
}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...