A drag-and-drop mini-game
This guide builds a simple puzzle: three squares to slide into their slots. A piece follows the pointer, then snaps in when it is released near its target. The demonstration below is fully playable.
The pointer events
FlatInk distinguishes four moments when an object is handled with the pointer:
when pressed: the object has just been pressed.when dragged: the object is being moved, while it is held. It keeps receiving the event even when the pointer leaves its surface.when released: the object has been released.when held: the object is held still (long press).
No behavior is automatic: an object only moves if it is told where to go. This keeps the logic readable.
Making a piece follow
A piece’s position is kept in two variables, for example ax and ay. The piece is displayed at that position through two bindings, x and y. To prevent it from jumping under the pointer when grabbed, the gap between the pointer and the piece is stored, then subtracted while dragging.
object "PieceA" {
when pressed {
ox = mouse.x - ax
oy = mouse.y - ay
}
when dragged {
ax = mouse.x - ox
ay = mouse.y - oy
}
x = ax
y = ay
}
Snapping into a slot
On release, the piece is checked against its target. The near function from the collision package answers whether it is close enough. If so, the piece is placed exactly on the slot.
use "collision"
object "PieceA" {
when released {
if near(ax, ay, 200, 420, 55) {
ax = 200
ay = 420
}
}
}
near(ax, ay, 200, 420, 55) is true when the point (ax, ay) lies within 55 pixels of the slot at (200, 420).
Going further
The gesture package provides ready-made functions for this kind of handling:
snap(value, step)snaps to a grid.railXandrailYconstrain a move along a segment.angle(cx, cy, px, py)returns the angle toward the pointer, useful for a rotary knob.inZone(px, py, x, y, w, h)tests a rectangular drop zone.
To restrict a drag to a single axis, bind only one channel: keep x = ax and write no y binding. The piece will move horizontally only.