The logic mostly directly transfers to events. Doesn't matter if it's C2 or C3, and nothing has been suggested yet that isn't possible in either version.
If examples help i could post some, but they tend to be dense. Ideally we'd like to help you be able to do the events in a way you understand. If you're stumped you either just start trying stuff out, or try to break the problem down into simpler doable steps.
So far you have a grid of blocks that you can drag around. You want to drag blocks onto adjacent blocks and have them swap positions.
You can know when a block is being dragged with the "is dragging" condition. You could know the direction you are dragging by using the angle() expression between the block's starting position and it's current position. You can also find the distance it's been dragged with the distance() expression.
That could look something like this:
var startX=0
var startY=0
block: on drag start
-- set startX to block.x
-- set startY to block.y
var ang=0
var dist=0
block: is dragging
-- set ang to angle(startX, startY, block.x, block.y)
-- set dist to distance(startX, startY, block.x, block.y)
So presumably you'd only want to swap the object's position if you drag far enough, and even then you'd only want to swap with blocks in the cardinal directions (up,down,left,right). Maybe half the block width would be a good distance to drag to trigger a swap. So with 32x32 tiles you could see if the distance is more than 16. To get a cardinal direction we could round the angle to the nearest 90 degree. round(ang/90)*90 is one such formula to round it.
So your events could look like this now:
var startX=0
var startY=0
block: on drag start
-- set startX to block.x
-- set startY to block.y
var ang=0
var dist=0
block: is dragging
-- set ang to angle(startX, startY, block.x, block.y)
-- set ang to round(ang/90)*90
-- set dist to distance(startX, startY, block.x, block.y)
-- compare: dist > 16
-- -- ... swap with block in direction ang...
That "swap" bit is what we'd want to figure out next. We need to be able to access both the block we are dragging and the block we are dragging onto. Families are one way to pick two different instances at once yet individually, but usually the way to go about it is to pick one at a time.
The dragged block is already picked, so to pick another block we need to first use "pick all block", then some other conditions to pick it.
We could use the ang to get the position of a tile in that direction. x=startX+32*cos(ang), y=startY+32*sin(ang), and then use that with the "pick closest" condition. However there are many other ways to do it.
var startX=0
var startY=0
block: on drag start
-- set startX to block.x
-- set startY to block.y
var ang=0
var dist=0
block: is dragging
-- set ang to angle(startX, startY, block.x, block.y)
-- set ang to round(ang/90)*90
-- set dist to distance(startX, startY, block.x, block.y)
-- compare: dist > 16
-- -- system: pick all block
-- -- block: pick closest to (startX+32*cos(ang), startY+32*sin(ang))
-- -- -- ... 2nd object is picked ... just need to swap ...
Ok, cool, now we just need to swap the two objects. set the second object's position to startx/y and add 32*cos(ang),32*sin(ang) to startx/y. A little bookeeping too. when drag ends we need to set the block position to startx/y to end the move. We want clean values so throw a round() over the sin/cos as well. Finally we need to make the is dragging event an "or" event and add "on drag end" to that too.
var startX=0
var startY=0
block: on drag start
-- set startX to block.x
-- set startY to block.y
var ang=0
var dist=0
var dx=0
var dy=0
block: is dragging
- or -
block: on drag end
-- set ang to angle(startX, startY, block.x, block.y)
-- set ang to round(ang/90)*90
-- set dist to distance(startX, startY, block.x, block.y)
-- compare: dist > 16
-- -- set dx to round(32*cos(ang))
-- -- set dy to round(32*sin(ang))
-- -- system: pick all block
-- -- block: pick closest to (startX+dx, startY+dy)
-- -- -- block: set position to (startx, starty)
-- -- -- add dx to startx
-- -- -- add dy to startY
block: on drag end
-- block: set position to (startX, startY)
Anyways, that is one way to do it, with some ideas behind it. The one I gave in the previous one works too.
Here is the solution from my previous post. Doesn't get much more compact than that. It has an addition to limit it to only swap between adjacent blocks.
dropbox.com/scl/fi/aavs1gwox2b6ontf2j8tf/swap_drag.capx
Another solution that uses drag and drop, and eases:
dropbox.com/scl/fi/egxhufb92axrisdpfyzuy/swap_drag4.capx