Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>From comment: </p> <blockquote> <p>Personally I would just switch to using SVG. It's more what it was made for. However it may be worth looking at <a href="http://easeljs.com" rel="nofollow">EaselJS</a> source. There's a method Stage.getObjectUnderPoint(), and their demo's of this seem to work perfectly fine.</p> </blockquote> <p>I ended up looking at the source, and the library utilises your first approach - separate hidden canvas for each object.</p> <p>One idea that came to mind was attempting to create some kind of a content-aware algorithm to detect anti-aliased pixels and with what shapes they belong. I quickly dismissed this idea.</p> <p>I do have one more theory, however. There doesn't seem to be a way around using ghost canvases, but maybe there is a way to generate them only when they're needed.</p> <p><strong>Please note the following idea is all theoretical and untested.</strong> It is possible I may have overlooked something that would mean this method would not work.</p> <p>Along with drawing an object, store the method in which you drew that object. Then, using the method of drawing an object you can calculate a rough bounding box for that object. When clicking on the canvas, run a loop through all the objects you have on the canvas and extract ones which bounding boxes intercept with the point. For each of these extracted objects, draw them separately onto a ghost canvas using the method reference for that object. Determine if the mouse is positioned over a non-white pixel, clear the canvas, and repeat.</p> <p>As an example, consider I have drawn two objects. I will store the methods for drawing the rectangle and circle in a readable manner.</p> <ul> <li><code>circ = ['beginPath', ['arc', 75, 75, 10], 'closePath', 'fill']</code></li> <li><code>rect = ['beginPath', ['rect', 150, 5, 30, 40], 'closePath', 'fill']</code></li> </ul> <p>(You may want to minify the data saved, or use another syntax, such as the SVG syntax)</p> <p>As I am drawing these circles for the first time, I will also keep note of the dimensional values and use them to determine a bounding box (<em>Note: you will need to compensate for stroke widths</em>).</p> <ul> <li><code>circ = {left: 65, top: 65, right: 85, bottom: 85}</code></li> <li><code>rect = {left: 150, top: 5, right: 180, bottom: 45}</code></li> </ul> <p>A click event has occurred on the canvas. The mouse point is <code>{x: 70, y: 80}</code></p> <p>Looping through the two objects, we find that the mouse coordinates fall within the circle bounds. So we mark the circle object as a possible candidate for collision.</p> <p>Analysing the circles drawing method, we can recreate it on a ghost canvas and then test if the mouse coordinates fall on a non-white pixel.</p> <p>After determining if it does or does not, we can clear the ghost canvas to prepare for any more objects to be drawn on it.</p> <p>As you can see this removes the need to store 960 x 800 x 100 pixels and only 960 x 800 <strong>x2</strong> at most.</p> <p>This idea would best be implemented as some kind of API for automatically handling the data storage (such as the method of drawing, dimensions...).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COThank you. The ghost canvas is fine and I have no problem with it. I like the idea of fast bounding functions that take an (x,y) and return true or false for each kind of shape. I'm looking for a resource for algorithms like that or other novel solutions I might have learned in an advanced graphics programming class. Stroked and filled circles, rectangles and straight lines seem simple, but complex shapes like areas, sliced circles (pie chart segment), or alpha transparent PNGs are going to be more complicated. There must be better ways known than looping over every pixel.
      singulars
    2. COYou're welcome. When calculating the bounding boxes, the idea is not be perfectly precise - _just enough_ to be able to encompass the shape without much whitespace surrounding it. Sliced circle bounding boxes can just be calculated the same way a normal circle and transparent PNG's can just rely on the images original dimensions. Since the idea of the bounding box is to simply _filter out_ drawing unnecessary shapes onto the ghost canvas, it will still work if the bounding boxes encompass extra whitespace. The _level of filtering_ is only affected, rather than the reliability of the collision.
      singulars
    3. COOfcourse, the bounding box idea is not even required. It is an optimisation technique - rather than having to redraw every object currently on the scene into the ghost canvas each click, it only redraws potential candidates for collision.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload