Skip to main content

The Power of Pride Bundle 2026 — $10 PWYC Edition
On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

My maze is rendered on a canvas roughly like the graphic shown below.So its mean I can assign a specific color to black and use those black pixels as impassable walls? (Hopefully I didn’t misinterpret how this works!)

I’m also curious about how wall collision detection is implemented in Sokoban. I’ve tried looking into its underlying logic to apply the same idea elsewhere, but I couldn’t find relevant code/methods and make sense of what I did find, and maybe i don’t even know where or how the collision parameters are configured in the first place.lollll

Oh wow! I totally forgot to hit the reply button omg 😂

(+3)

Decker Sokoban uses the general strategy I described above. Level elements are aligned to a 32x32 tile grid, and every tile of the card background of a level that contains any pixels of pattern 20 (that diagonal slashed pattern) are treated as "solid"; note how I always use a layer of this pattern when drawing level boundaries:



Most of the work happens in the script of the card named "game". Paraphrasing,

CELL:32 # grid size
on isTile pos tile do
 (card.image.copy[pos CELL,CELL].hist[tile])>0
end
on isWall pos do
 isTile[pos 20]
end

The "isTile[]" function is also used to identify "goals", where blocks are supposed to end up on each level, identified with a different pattern.

Collision and movement animation/physics in games is a very deep and complex realm, but here's a simple demo for you to play with as a starting point: an animated canvas that moves around in response to arrow keys using the gamepad interface, and cannot move past pattern 36 (pink).


on view do
 each in range 3
  if !card.image.copy[me.pos+gamepad.dir me.size].hist[36]
   me.pos:me.pos+gamepad.dir
  end
 end
end

As a paste-able example:

%%CRD0{"c":{"name":"home","image":"%%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","widgets":{"bug":{"type":"canvas","size":[21,17],"pos":[89,204],"locked":1,"animated":1,"script":"on view do\n each in range 3\n  if !card.image.copy[me.pos+gamepad.dir me.size].hist[36]\n   me.pos:me.pos+gamepad.dir\n  end\n end\nend","border":0,"image":"%%IMG3ABUAEQZAgHBILAaOxSQAuQyAngHl0Ak6Pq9VKbWKxUaT2233Oz2az+Kvucumqtlw6DsOJ7u9cTuenhWGq2JjU3yCRIFXd2SGaIxRioZGflJTkZNB","scale":1}}},"d":{}}

(There's a lot more this would need to make it feel good to play, like giving the bug animation, a sense of velocity and weight, allowing it to "slide" past walls while touching them, a smaller bounding box, etc.)

(+1)

I understand, I will try my best to make it!