none-9999 Posted January 21, 2016 Share Posted January 21, 2016 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? Quote Link to comment Share on other sites More sharing options...
mattstyles Posted January 22, 2016 Share Posted January 22, 2016 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. samlancashire 1 Quote Link to comment Share on other sites More sharing options...
JazzAceman Posted January 22, 2016 Share Posted January 22, 2016 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 Quote Link to comment Share on other sites More sharing options...
mattstyles Posted January 23, 2016 Share Posted January 23, 2016 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. Quote Link to comment Share on other sites More sharing options...
JazzAceman Posted January 23, 2016 Share Posted January 23, 2016 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. Quote Link to comment Share on other sites More sharing options...
chg Posted January 23, 2016 Share Posted January 23, 2016 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) Quote Link to comment Share on other sites More sharing options...
samlancashire Posted February 28, 2016 Share Posted February 28, 2016 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)); } Kyros2000GameDev and mattstyles 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.