Here is an excerpt from an old project written before generic drag events were available:
(I post it here because your sample code requires an if/then/else branch for every Sprite, which should not be necessary if you have lots of sprites and keep them in a list.)
Note: The swap at touch up is specific to the sample app, and is overkill for your application.
When P1.Dragged
Each of the 9 sprites has a Dragged event block. They all call the common procedure handle_drag, passing it that Sprite component, and the currentX and currentY of the drag event.
(This was written before generic Events became available - ABG)
handle_drag
This procedure contains code to avoid sprite cannibalism, where extra sprites try to follow your finger as you drag another sprite near them. The two tests handle that - a global true/false value dragging to indicate that we are in the middle of a drag operation, and a global variable dragged_sprite to hold the component that we decided to drag when we started a drag operation.
If this sprite is the currently dragged sprite, then we move it, with some adjustments so it doesn’t get obscured by our finger as it’s dragged.
If a drag operation starts while the dragging variable is false, then we handle it like it was a touchDown event, and call procedure handle_touchDown.
handle_touchDown
This procedure is called at the start of a drag sequence. We announce in the global dragging variable that a drag has started, and save the current sprite parameter in the global dragged_sprite. We also save the X and Y values of this sprite in the two globals dragged_start_X and dragged_start_Y, for the snapBack operation when we let go of the drag.
To show the dragged sprite better, we raise its Z value.
When P1.TouchUp
The drag operation ends when we release the dragged sprite, signalling a TouchUp event for that sprite. We pass the component to procedure handle_touchUp.
handle_TouchUp
This procedure also protects against sprite cannibalism in the surrounding IF/THEN test, to insure it will happen only for the currently dragged sprite, and only during a drag operation.
If the two tests are satisfied, it sets the global dragging variable false, and resets the Z of the sprite to 1. Since the drag might stop outside of any other sprite, or on the overlap of two sprites, we have to go through all the other sprites and check for overlap, using the procedure is_inside, collecting the result in local list landing_sprites. If there are no landing sprites, there’s nothing to swap, and nothing to save. We take the first landing sprite in the result list to settle any tie, and call swap_pictures to swap pictures with that sprite, and save_sprite_pictures to save the new picture order in TinyDB for any future load operation. Either way, we snap the dragged sprite back to its original position using routine snap_back.
is_inside
This procedure tests if a dragged sprite is inside a target sprite, judging by the center of the dragged sprite and the four walls of the target sprite. That comes out to 2 tests by X, and 2 tests by Y.