{"id":29,"date":"2020-10-26T12:14:00","date_gmt":"2020-10-26T17:14:00","guid":{"rendered":"https:\/\/cynthiamcmahon.ca\/blog\/index.php\/2020\/10\/per-pixel-sprite-sheet-collision-detection\/"},"modified":"2020-10-26T12:14:00","modified_gmt":"2020-10-26T17:14:00","slug":"per-pixel-sprite-sheet-collision-detection","status":"publish","type":"post","link":"https:\/\/cynthiamcmahon.ca\/blog\/2020\/10\/per-pixel-sprite-sheet-collision-detection\/","title":{"rendered":"Per Pixel Sprite Sheet Collision Detection"},"content":{"rendered":"<p>&nbsp;I&#8217;ve seen this question asked a few times but no public answers. How do you detect if two sprites in a sprite sheet collide using per pixel collision detection? The answer for entire sprites is available easily. I made two static methods that can be added to a project to check if two parts of a sprite sheet collide. Soon I will be posting code that handles rotated and scaled sprites as well.<\/p>\n<p><\/p>\n<pre><code><br \/>public static bool SpriteSheetCollision(<br \/>    Rectangle destinationA, <br \/>    Rectangle? sourceA, <br \/>    Texture2D textureA,<br \/>    Rectangle destinationB,<br \/>    Rectangle? sourceB,<br \/>    Texture2D textureB)<br \/>{<br \/>    \/\/ If the sourceA is null use entire texture<br \/>    if (sourceA == null)<br \/>    {<br \/>        sourceA = new Rectangle(0, 0, textureA.Width, textureA.Height);<br \/>    }<br \/><br \/>    \/\/ Grab the texture data for checking if the pixels collide in the source rectangle<br \/>    Color[] textureDataA = new Color[sourceA.Value.Width * sourceA.Value.Height];<br \/>    textureA.GetData(0, sourceA, textureDataA, 0, textureDataA.Length);<br \/><br \/>    \/\/ If the sourceB is null use the entire texture as the source rectangle<br \/>    if (sourceB == null)<br \/>    {<br \/>        sourceB = new Rectangle(0, 0, textureB.Width, textureB.Height);<br \/>    }<br \/><br \/>    \/\/ Grab the texture data for checking if the pixels collide in the source rectangle<br \/>    Color[] textureDataB = new Color[sourceB.Value.Width * sourceB.Value.Height];<br \/>    textureB.GetData(0, sourceB, textureDataB, 0, textureDataB.Length);<br \/><br \/>    \/\/ Call the per pixel collision detection code<br \/>    return ColorDataCollides(destinationA, textureDataA, destinationB, textureDataB);<br \/>}<br \/><br \/>public static bool ColorDataCollides(Rectangle a, Color[] textureDataA, Rectangle b, Color[] textureDataB)<br \/>{<br \/>    \/\/ Find the bounds of the rectangle intersection<br \/>    int top = Math.Max(a.Top, b.Top);<br \/>    int bottom = Math.Min(a.Bottom, b.Bottom);<br \/>    int left = Math.Max(a.Left, b.Left);<br \/>    int right = Math.Min(a.Right, b.Right);<br \/><br \/>    \/\/ Check every point within the intersection bounds<br \/>    for (int y = top; y &lt; bottom; y++)<br \/>    {<br \/>        for (int x = left; x &lt; right; x++)<br \/>        {<br \/>            \/\/ Get the color of both pixels at this point<br \/>            Color colorA = textureDataA[(x - a.Left) +<br \/>                                    (y - a.Top) * a.Width];<br \/>            Color colorB = textureDataB[(x - b.Left) +<br \/>                                    (y - b.Top) * b.Width];<br \/><br \/>            \/\/ If both pixels are not completely transparent,<br \/>            if (colorA.A &gt; 0 &amp;&amp; colorB.A &gt; 0)<br \/>            {<br \/>                \/\/ then an intersection has been found<br \/>                return true;<br \/>            }<br \/>        }<br \/>    }<br \/><br \/>    \/\/ No intersection found<br \/>    return false;<br \/>}<br \/><\/code><br \/><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp;I&#8217;ve seen this question asked a few times but no public answers. How do you detect if two sprites in a sprite sheet collide using per pixel collision detection? The answer for entire sprites is available easily. I made two static methods that can be added to a project to check if two parts of &hellip; <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-29","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/posts\/29","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/comments?post=29"}],"version-history":[{"count":0,"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/posts\/29\/revisions"}],"wp:attachment":[{"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/media?parent=29"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/categories?post=29"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cynthiamcmahon.ca\/blog\/wp-json\/wp\/v2\/tags?post=29"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}