Sprite Occlusion

0 favourites
  • 13 posts
From the Asset Store
Minimal Sprite Font with Stroke for Pixel Art games.
  • Hi

    I think this may be my first post on here so - hello!

    I�ve been using C2 for a little while now and thanks to all of the amazing tutorial and forum posts by the community, have managed to figure out everything I have needed to without having to resort to the forums - so thank you! I have however, now reached a point where I am not really sure how to continue and as such would be really grateful if someone could give me a little nudge in the right direction as to what I might need to do.

    The demo I have is quite simple. Every time you touch the screen it creates a circular sprite (which scales the longer you hold it down � effectively a brush). I also have a different sprite (say a rectangle) on screen that will eventually be covered by the circular sprites if enough are drawn over it.

    What I am try to achieve is this:

    I would like to detect when the rectangle has been completely covered by circular sprites as illustrated in the image attached below.

    <img src="https://dl.dropbox.com/u/57403205/TestExample.png" border="0" />

    I have tried visibility, overlaps and have looked at some of the LOS tutorials, but none seem quite right for my needs. Is there anything in Construct that might enable me to come up with a workaround?

    Thanks in advance

  • That's a very interesting problem. I can't come up with anything terribly efficient at the moment...

    Maybe R0J0hound or Yann would be able to help with the Polygon or Canvas plugins.

    If there's no efficient way to do it, I could think of some ways to do it, but the calculations wouldn't be able to run every tick - only on a 'check' trigger or the like.

  • Thanks. If it helps with efficiency/CPU I should add that I will be limiting the number of circular sprites that can be displayed on screen at one time. Probably no more than 20. If needed, I could reduce this even more.

  • One not too efficient idea: use an array with size of screen width/height where you track which pixels are shown and which not. Whenever new object is created, 'create' it inside the array as well based on radius/coordinates.

  • Ok, that's interesting, thanks. Arrays I'm ok with but I'm a little unsure about the pixel tracking. Would you be able to elaborate a little more about how I might do this?


  • Well I'm not a mathematician at all. So when I see your problem, I have a newbie solution (I am the noob of course). But perhaps it can help the thinking :

    What about composing your "rectangle collision" with a multitude of little invisible pieces, like a puzzle. When one of these pieces is overlaped by a circle sprite, it add 1 to a variable (once). If the variable is = the number of pieces then we can consider the rectangle is hidden.

    I don't know if I'm clear. :(

    It's just a idea, perhaps not viable or efficient.

  • Thanks KaMiZoTo - that's a brilliant idea. I think I can integrate that idea into the design so that it achieves the same outcome that I'm looking for.

    Cheers! <img src="smileys/smiley4.gif" border="0" align="middle" />

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • You're welcome. :)

  • Boomlet yeah, that was the 'inefficient' idea I was considering - however if your rectangles are too big, you will allow blank spaces, and if they are too small the checking will be very slow!

    Still should work, anyway. Try it out!

  • sqiddster - Thanks also. Yes this is a definite risk. I have decided to change the design slightly so I don't need full object overlaps for this very reason. I'm going to use several 'sub-objects' instead which will achieve the same effect.


  • Boomlet OK, cool.

  • Global constant number TRUE  = 1
    Global constant number FALSE = 0
    + Function: On function "isCovered" :
       Local number result = 0
       -> System: set result to TRUE
       + System: for "y" from 0 to rectangle.Width
          + System: for "x" from 0 to rectangle.Height
             Local number covered = 0
             Local number px = 0
             Local number py = 0
             -> System: set px to rectangle.X - rectangle.width/2  + loopindex("x")
             -> System: set py to rectangle.Y - rectangle.height/2 + loopindex("y")
             + System: Foreach circle
             + System: distance(circle.X,circle.Y,px,py) <= circle.width/2
                -> System: covered = TRUE
                -> System: stop loop  // stop the foreach
             + System: covered = FALSE
                -> System: set result to FALSE
                -> System: stop loop  // stop the "x" loop
                -> System: stop loop  // stop the "y" loop
       -> Function: set return value to result[/code:a9ngkl9o]
    Untested. But the idea is to sample each pixel of your rectangle and see if there's a circle for which the distance from the center of the circle to this point is lower than its radius.
    I make several assumption here:
      - you only have one rectangle shape in your layout
      - your circle.width is exactly equal to your circle's diameter (I use width/2 for the radius)
      - the origin of your rectangle and circle is in the middle
    Be carefull the amount of computation will be proportionnal to rectangle.width*rectangle.height*circle.Count  at worst case, which is if the rectangle is completely covered since all the loop are stopped as soon as an out of circle point is found.
    If you happen to use some kind of grid snapping, you can probably lower the amount of computation since you shouldn't have to check every single point of the rectangle (but not sure)
    In any case you shouldn't run this function every tick, but probably only when you drop a circle.
    Also using any kind of C2's built-in overlap check isn't really reliable since a circle's collision polygon is usually an octogon and also, checking for radius is probably faster than using polygon based collision detection.
    here's a working implementation:
    as you can see it can get quickly slow.Yann2013-03-26 08:36:17
  • Yann - Thank you so much for this. I'm genuinely blown away that someone would go to all this effort to help out <img src="smileys/smiley4.gif" border="0" align="middle" />

    It definitely works exactly as required and more importantly it's given me something tangible to start playing around with. If I can do anything else clever with it then I'll definitely share.

    Thanks again for your help - this forum rocks <img src="smileys/smiley4.gif" border="0" align="middle" />

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)