TutorialsCocktail Shaker Sort

2  Your Hands on the Board

Goal

By the end of this chapter, your hands are on the board. Tap a piece, and its edge turns gold. Tap another, and the two trade places. Drag one onto another, and they trade the moment you let go. The keys do it too. Every exchange counts as a Move, and when the last piece comes home, the game says so.

The game as it is at the end of this chapter. Click the game to play.

If your game and this chapter part ways, here is the chapter’s finished project. Open it and compare, or start Chapter 3 from it.

Picture Puzzle, Chapter 2 finishedMyth project · 6.5 MB

To open it, start Myth Engine, choose File › Open Project... and pick the downloaded file.

2.1 The Idea

The Village lies on the board where Chapter 1 dealt it. Sailboats in the flower beds, a rooftop in the lake, the cat at the right edge, far from its wall. Click a piece, and nothing happens.

This chapter changes that. By its end you can put the picture back yourself, two pieces at a time.

Trading two pieces is called an exchange. You pick two pieces, any two on the board, and they trade slots. The first one you pick is the selection, and it wears a gold edge while it waits for its partner.

Here’s the part to keep hold of. On the screen, two pieces trade places. Underneath, two numbers trade places in Board Slots, the seating chart from Chapter 1. Exchange Slots already does that. Your hands only have to tell it which two slots.

So the board never gains or loses a piece. Each piece is still on it exactly once, wherever your exchanges have put it.

There are three ways to choose. A tap is a press and a release on the same piece. A drag is a press on one piece and a release on another.

And the keys choose too. A blue focus walks over the board with the arrow keys, and Enter picks the piece under it. All three ways end in the same place.

The computer will make exchanges too, from Chapter 3, but it will only ever trade two neighbors, side by side. Yours can be any two.

2.2 The Plan

Here’s how the pieces work together. Read each line from left to right, and come back to them at the end, when every name is something you’ve built.

  • A press on a piece -> Piece Pointer sends piecePressed to Puzzle Rules -> Piece Press keeps the pressed slot, and sends selectionChanged.
  • Each selectionChanged -> every Outline’s Show Outline paints its edge: normal, blue or gold.
  • A release on a piece -> Piece Pointer sends pieceReleased -> Piece Press sends pieceChosen for a tap, or piecesDropped for a drag.
  • Each pieceChosen -> Player Exchange selects the piece, or exchanges it with the one already selected.
  • Each piecesDropped -> Player Exchange exchanges the two at once.
  • An exchange -> Make Player Exchange calls Exchange Slots, adds 1 to Moves, and sends piecesExchanged.
  • Each piecesExchanged -> every Piece shows its new piece, and Pieces Home counts again.
  • Keys 1 to 9, or Enter -> Choose Slot sends pieceChosen to Puzzle Rules, exactly the way a tap on a piece does.
  • The arrow keys -> Move Focus moves the blue focus.
  • The count of pieces home changes -> Picture Complete sets the Game State to Solved or Playing.
  • Escape -> Puzzle Commands sends selectionCanceled -> the selection and any press are forgotten.

2.3 Set Up

Chapter 2 adds keys, a few Globals and a Game State. There are no new pictures.

The Set up card follows these paragraphs, so read them first, and then work down the card from its top.

COMMANDS are fifteen new keys: 1 to 9, the four arrow keys, Enter and Escape. You made two Commands in Chapter 1, so your hands know the way. For an arrow key, Enter or Escape, press the key itself in the No Input Assigned row, and the row writes its name. In later chapters on the Making page says more.

The Commands are named for what they do, never for their keys. Choose Piece 1 is key 1. Focus Left is the left arrow.

GLOBAL VARIABLES are five new values the whole game shares. Make them in any Logic Component’s Globals card, using New Global…, as you did in Chapter 1. Show Piece’s will do. Three of them start at -1, and -1 means no slot at all: nothing selected, nothing pressed, no focus shown.

GAME SETTINGS > General > Game State lists the two states the game can be in, Playing and Solved. Your project has Playing already. Add Solved, as In later chapters shows.

Leave PLACE THESE for later, since the Game Goal and the Player Counter are placed in their own parts.

Set upWhat this chapter adds
COMMANDS (Game Settings > Input Manager)
Choose Piece 1Button
Keybindings1
Choose Piece 2Button
Keybindings2
Choose Piece 3Button
Keybindings3
Choose Piece 4Button
Keybindings4
Choose Piece 5Button
Keybindings5
Choose Piece 6Button
Keybindings6
Choose Piece 7Button
Keybindings7
Choose Piece 8Button
Keybindings8
Choose Piece 9Button
Keybindings9
Focus LeftButton
KeybindingsLeft Arrow
Focus RightButton
KeybindingsRight Arrow
Focus UpButton
KeybindingsUp Arrow
Focus DownButton
KeybindingsDown Arrow
Select Focused PieceButton
KeybindingsEnter
CancelButton
KeybindingsEscape
GLOBAL VARIABLES
$movesNumberstarts at 0
$chosenSlotNumberstarts at 0
$selectedSlotNumberstarts at -1
$pressedSlotNumberstarts at -1
$focusSlotNumberstarts at -1
GAME SETTINGS > General > Game State
Available Game StatesPlaying, Solved
SCENE Picture Table: PLACE THESE
ObjectXY
Game Goal500-80
Player Counter815-732

Save your project, and again at the end of each part.

2.4 The Edges Take Their Color

The board’s edges learn to answer your hand.

In the finished game, every piece sits on a dark green-gray square, a thin edge of it showing all round. When you press a piece, its edge turns blue. When you select one, it turns gold, the color of a piece that’s waiting. The edge is how the board talks.

The colors live in a table, Outline Colors, one row for each: normal, focus and selected. The Logic never spells a color itself. It asks the table. Change a row, and every edge that uses it changes too.

Outline Colors’ columns come from Outline Colors Entry. Make those fields before adding its rows.

Data StructureOutline Colors Entry

One row of the "Outline Colors" Data Table.

colorColordefault #46615a
Data TableOutline ColorsData Structure: Outline Colors Entry
Row 0normal
color#46615a
Row 1focus
color#2579bc
Row 2selected
color#f3d49c

2.4.1 Show Outline

Show Outline lives on every Piece Outline, and it keeps no color of its own. It waits for one message, selectionChanged. That message means something about the selection, the press or the focus may be different now.

When the message comes, the Outline paints itself, in coats. First the normal color. Then it asks whether its slot is the focus or the pressed one. If so, blue goes on. Then it asks whether its slot is the selected one, and if so, gold goes on last. The last coat is the one you see, so a selected piece that also has the focus shows gold.

Each question compares two numbers. One is the Outline’s own slot, self.slotNumber.slot, and the other is a Global, such as $selectedSlot. The paint is Change Sprite Tint Property, with a color from the table.

The focus question has two rows, joined by Or, because either one turns the edge blue. If, Else and Repeat shows how to add the second row.

Logic ComponentShow OutlineAttach to: Piece Outline

Colors this Outline for the player: the keyboard focus and a pressed piece are blue, the selected piece is gold, and every other Outline keeps the normal color.

Attach toAny Object
DATA STRUCTURES
Slot Numberself.slotNumber
On Selection Changed
WhenselectionChangedCustom Event
1Change Sprite Tint Property
Value
data('Outline Colors', 'normal', 'color')
2Ifself.slotNumber.slot == $focusSlot || self.slotNumber.slot == $pressedSlot
Then
3Change Sprite Tint Property
Value
data('Outline Colors', 'focus', 'color')
4Ifself.slotNumber.slot == $selectedSlot
Then
5Change Sprite Tint Property
Value
data('Outline Colors', 'selected', 'color')

Attach it to the Piece Outline. The Changes card shows where.

ObjectPiece OutlineAddDelete
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 70, Y 70
Sprite
Z Index Within Object-1
SpriteOutline Square
Tint#46615A
Transform > SizeX 70, Y 70
Data Structure
From LogicLay Out Slot, Show Outline
From LogicLay Out Slot
Data StructureSlot Number
Logic
Lay Out Slot
Show Outline

Nothing sends selectionChanged yet, so every edge keeps its starting color. The next part sends it, and the first press paints a blue edge.

2.5 A Press on a Piece

Now the board starts to feel your hand.

Press a piece and hold it, and a thin blue edge rings it. Let go, and the blue goes. Nothing trades yet, but the board has noticed you, and that’s where every exchange begins.

2.5.1 Piece Pointer

Piece Pointer is on every Piece, and it only reports. When a press begins on this Piece, or ends on it, it says so. It never decides what the press meant, and it never needs to.

Two Events do the listening. Mouse Pressed on Object runs when a click or a touch begins on this Piece. Mouse Released on Object runs when one ends on it, even if it began on another Piece. That’s how a drag gets noticed at its end.

A message carries no numbers. So before it speaks, the Piece writes its slot into $chosenSlot, where Puzzle Rules will look. Only then does it send piecePressed, or pieceReleased, and only to Puzzle Rules.

Logic ComponentPiece PointerAttach to: Piece

Tells Puzzle Rules when the pointer is pressed on this Piece and when it is released on it. Puzzle Rules decides what the press and the release mean.

Attach toAny Object
DATA STRUCTURES
Slot Numberself.slotNumber
SHARED VARIABLES
NameTypeKindStarting Value
puzzleRulesObjectConstantNone
When Left Is Clicked
WhenMouse Pressed on ObjectMouse button: left
1Change Variable
Variable
$chosenSlot
Value
self.slotNumber.slot
2Trigger Custom Event on Object
Applies to
@self.puzzleRules
Custom Event
piecePressed
When Left Is Released
WhenMouse Released on ObjectMouse button: left
1Change Variable
Variable
$chosenSlot
Value
self.slotNumber.slot
2Trigger Custom Event on Object
Applies to
@self.puzzleRules
Custom Event
pieceReleased

Attach it to the Piece.

ObjectPieceAddDelete
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 68, Y 68
Sprite
Z Index Within Object-1
SpriteVillage Pieces 64
Transform > SizeX 68, Y 68
Data Structure
From LogicShow Piece, Lay Out Slot, Piece Pointer
From LogicShow Piece, Lay Out Slot
Data StructureSlot Number
Logic
Show Piece
Lay Out Slot
Piece Pointer
Shared Variables
puzzleRulesPuzzle Rules

2.5.2 Piece Press

Piece Press lives on Puzzle Rules, and it’s the one that decides. It’s the chapter’s one hard idea, so take it beat by beat, starting with the plain case.

A press arrives, and Piece Press keeps its slot in $pressedSlot, then sends selectionChanged, and the pressed edge turns blue. A release arrives. Is a press still under way? If the release is on the same slot, that’s a tap, and it sends pieceChosen. On another slot, it’s a drag, and it sends piecesDropped. Either way, the press is over, so $pressedSlot goes back to -1.

That would be enough, if every release landed somewhere a Piece could hear it. It doesn’t. Let go over the table, between the buttons, and no Piece hears it. The press would hang there forever, blue.

So Piece Press listens to the mouse button too, wherever the pointer happens to be when it goes up. Mouse Release runs for every release of the button, anywhere. But it runs before the Piece under the pointer hears its own release. If Piece Press forgot the press right then, a real release on a piece would find nothing to finish.

So it waits for the end of the frame. Mouse Release switches End Step to its Release Seen Mode. Only then does Release Seen answer. If a press is still hanging, End Step forgets it and returns to No Release. That Starting Mode has no Actions.

Losing focus is a different ending. You might click another window while still holding a piece. No release arrives. Input Interruptions, built next, sends the same cancellation as Escape.

Escape forgets a press too. That’s selectionCanceled, the last Event on the card.

Make End Step and both its Modes before the Mouse Release’s Switch Mode. That Action picks On End Step and Release Seen from lists, so both must exist first. They are two Modes of one Event.

Logic ComponentPiece PressAttach to: Puzzle Rules

Follows one press of the pointer on a piece: released on the same piece it is a tap, released on another piece it is a drag, and released anywhere else it is forgotten. A press cut off (the game lost focus, or the touch was cut off) is forgotten too, when Input Interruptions sends selectionCanceled.

Attach toAny Object
On Piece Pressed
WhenpiecePressedCustom Event
1Change Variable
Variable
$pressedSlot
Value
$chosenSlot
2Trigger Custom Event
Custom Event
selectionChanged
On Piece Released
WhenpieceReleasedCustom Event
1If$pressedSlot >= 0
Then
2If$pressedSlot == $chosenSlot
Then
3Trigger Custom Event on Object
Custom Event
pieceChosen
4Otherwise
5Trigger Custom Event on Object
Custom Event
piecesDropped
6Change Variable
Variable
$pressedSlot
Value
-1
7Trigger Custom Event
Custom Event
selectionChanged
When the Left Mouse Button Is Released
WhenMouse ReleaseMouse button: left
1Switch Mode
Event
On End Step
Mode
Release Seen
On End Step
WhenEnd Step
ModeNo Release (Starting Mode)
(no Actions)
On End Step
WhenEnd Step
ModeRelease Seen
1Change Variable
Variable
$pressedSlot
Value
-1
2Trigger Custom Event
Custom Event
selectionChanged
3Switch Mode
Event
On End Step
Mode
No Release
On Selection Canceled
WhenselectionCanceledCustom Event
1Change Variable
Variable
$pressedSlot
Value
-1
2Trigger Custom Event
Custom Event
selectionChanged

Attach Piece Press to Puzzle Rules. Run the game, and press a piece without letting go. A blue edge rings it while the other edges keep their plain color. Let go, and the blue is gone.

Nobody will ever notice Piece Press. They’ll only notice that, whatever their hands do, the board never gets stuck with a blue edge on it.

2.5.3 Input Interruptions

A held piece must let go when your hand leaves the game. Input Interruptions listens for Focus Lost and Touch Cancelled. Either sends selectionCanceled, the same message Escape sends. Piece Press forgets its press, and Player Exchange will forget its selection.

Logic ComponentInput InterruptionsAttach to: Puzzle Rules

Cancels a selection and a press under way when the player's input is cut off: the game window lost focus, or a touch was cut off. Either way it sends selectionCanceled, as Escape does.

Attach toAny Object
On Focus Lost
WhenFocus Lost
1Trigger Custom Event on Object
Custom Event
selectionCanceled
On Touch Cancelled
WhenTouch Cancelled
1Trigger Custom Event on Object
Custom Event
selectionCanceled

Attach it to Puzzle Rules. Press a piece, then click another window. Return to the game and look at the edge. The blue edge is gone.

2.6 Two Pieces Trade Places

Now the moment the whole chapter is for.

Tap a piece. Its edge turns gold, and a line at the foot of the screen says Choose another piece. Tap a second piece, and the two trade places. The gold is gone, and under the Preview, Moves reads 1.

The words come from Messages, which gains two rows, one for a selection and one for the finished picture.

Data TableMessagesData Structure: Messages EntryAddDelete
Row 0reset
wordsReset.
Row 1selected
wordsChoose another piece.
Row 2solved
wordsPicture complete.

The Game Goal is a new Object. It tells a new player what to do, in one gray line under the title.

ObjectGame Goal
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextDrag or tap two pieces to exchange them.
Font Size15
EmphasisMedium
Color#526478
RenderingVector

Place it at 500 and -80, under the title.

2.6.1 Player Exchange

Player Exchange hears what Piece Press and the keys decide. Its main Event is pieceChosen, and it has to behave in two different ways, depending on what’s already on the board. With nothing selected, a chosen piece becomes the selection. With a piece already selected and waiting in gold, the next one chosen is its partner.

So that Event has two Modes, one for each situation, and only one answers at a time. Nothing Selected is where it starts. It makes the chosen slot $selectedSlot, puts Choose another piece on the Message Line, and switches the Event to One Selected. One Selected checks that the second piece isn’t the first one again. If it isn’t, the two are exchanged. Either way, the selection ends, and the Event switches back to Nothing Selected.

So a tap on the gold piece itself changes your mind. Nothing trades, and the gold goes.

A drag needs no selection at all. piecesDropped exchanges the pressed slot and the released one at once.

Two small Functions do the shared work, and Player Exchange calls both. Switching the Mode back isn’t part of that work. Switch Mode is never offered inside a Function, because a Mode belongs to the Logic whose Event it is. So Player Exchange switches its own pieceChosen back, just before it calls Clear Selection. Its Switch Modes pick the Event and the Mode from lists, so build in this order. Make Player Exchange’s Events and their Modes first, with no Actions yet, and attach it to Puzzle Rules. Its card is below the two Functions. The Events are pieceChosen, with Nothing Selected and One Selected, then piecesDropped, selectionCanceled and boardArranged. Then make the two Functions. Then come back, and fill in Player Exchange from its card.

2.6.2 Make Player Exchange

Make Player Exchange is your hands’ exchange. It calls Exchange Slots, from Chapter 1, with the two slots. It adds 1 to $moves. Then it sends piecesExchanged to every Object that listens.

Remember Exchange Slots, holding one cup aside while it pours the other? The shuffle used it in Chapter 1. Now you do.

FunctionMake Player Exchange

The player's exchange: the pieces of two slots trade places, Moves counts it, and every Piece is told.

PARAMETERS
NameTypeStarts at
firstSlotNumber0
secondSlotNumber0
ACTIONS
1Exchange SlotsFunction
firstSlot
firstSlot
secondSlot
secondSlot
2Change Variable
Variable
$moves
Operator
+=
Value
1
3Trigger Custom Event
Custom Event
piecesExchanged

2.6.3 Clear Selection

Clear Selection ends a selection, whichever way it ends. It sets $selectedSlot back to -1. Then it looks at the Message Line. If it still says Choose another piece, those words leave with the selection. Any other words, such as Reset, stay where they are.

Last, it sends selectionChanged, so the gold comes off.

FunctionClear Selection

Forgets the selected piece: the words "Choose another piece." leave the Message Line, and the Outlines are told.

ACTIONS
1Change Variable
Variable
$selectedSlot
Value
-1
2If$message == data('Messages', 'selected', 'words')
Then
3Change Variable
Variable
$message
Value
""
4Trigger Custom Event
Custom Event
selectionChanged

Now fill in Player Exchange. Its last two Events tidy up. selectionCanceled is Escape. boardArranged comes after Reset or Shuffle, when Moves starts again from 0.

Every Event that ends a selection ends the same way, with two Actions: a Switch Mode, then Clear Selection. The Switch Mode works on Player Exchange itself, so its Applies To stays Self. Pick On Piece Chosen in its first list and Nothing Selected in its second.

Logic ComponentPlayer ExchangeAttach to: Puzzle Rules

The player exchanges two pieces: the first piece chosen is selected, the second one trades places with it (choosing the selected piece again cancels). A drag from one piece to another exchanges them at once.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
puzzleRulesObjectConstantNone
On Piece Chosen
WhenpieceChosenCustom Event
ModeNothing Selected (Starting Mode)
1Change Variable
Variable
$selectedSlot
Value
$chosenSlot
2Change Variable
Variable
$message
Value
data('Messages', 'selected', 'words')
3Switch Mode
Event
On Piece Chosen
Mode
One Selected
4Trigger Custom Event
Custom Event
selectionChanged
On Piece Chosen
WhenpieceChosenCustom Event
ModeOne Selected
1If$chosenSlot != $selectedSlot
Then
2Make Player ExchangeFunction
firstSlot
$selectedSlot
secondSlot
$chosenSlot
3Change Variable
Variable
$message
Value
""
4Switch Mode
Event
On Piece Chosen
Mode
Nothing Selected
5Clear SelectionFunction
On Pieces Dropped
WhenpiecesDroppedCustom Event
1Make Player ExchangeFunction
firstSlot
$pressedSlot
secondSlot
$chosenSlot
2Change Variable
Variable
$message
Value
""
3Switch Mode
Event
On Piece Chosen
Mode
Nothing Selected
4Clear SelectionFunction
On Selection Canceled
WhenselectionCanceledCustom Event
1Switch Mode
Event
On Piece Chosen
Mode
Nothing Selected
2Clear SelectionFunction
On Board Arranged
WhenboardArrangedCustom Event
1Change Variable
Variable
$moves
Value
0
2Switch Mode
Event
On Piece Chosen
Mode
Nothing Selected
3Clear SelectionFunction

Three pieces of Logic you already have learn one new message each. Show Piece and Pieces Home hear piecesExchanged, so the pictures change and the count keeps up. Puzzle Commands gains the Cancel key, Escape.

Logic ComponentShow PieceAttach to: PieceAddDelete

Shows the picture frame of the piece that Board Slots puts in this Piece's slot. Make Board gives each Piece its slot in its Slot Number (0 is the top-left slot, counting right, then down).

Attach toAny Object
DATA STRUCTURES
Slot Numberself.slotNumber
On Placed on Board
WhenplacedOnBoardCustom Event
1Set Frame
Frame
data('Board Slots', self.slotNumber.slot, 'piece')
On Board Arranged
WhenboardArrangedCustom Event
1Set Frame
Frame
data('Board Slots', self.slotNumber.slot, 'piece')
On Pieces Exchanged
WhenpiecesExchangedCustom Event
1Set Frame
Frame
data('Board Slots', self.slotNumber.slot, 'piece')
Logic ComponentPieces HomeAttach to: Puzzle RulesAddDelete

Keeps $piecesHome, the count the Board Caption shows, equal to the number of pieces in their home slots.

Attach toAny Object
On Board Made
WhenboardMadeCustom Event
1Count Pieces HomeFunction
On Board Arranged
WhenboardArrangedCustom Event
1Count Pieces HomeFunction
On Pieces Exchanged
WhenpiecesExchangedCustom Event
1Count Pieces HomeFunction
Logic ComponentPuzzle CommandsAttach to: Puzzle RulesAddDelete

The keys ask for the same things as the Buttons: R for Reset, N for a new arrangement. Escape cancels a selection.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
puzzleRulesObjectConstantNone
When Reset Is Pressed
WhenCommand PressedCommand: Reset
1Request ResetFunction
puzzleRules
@self.puzzleRules
When New Is Pressed
WhenCommand PressedCommand: New Arrangement
1Request ShuffleFunction
puzzleRules
@self.puzzleRules
When Cancel Is Pressed
WhenCommand PressedCommand: Cancel
1Trigger Custom Event on Object
Custom Event
selectionCanceled

Last, the Player Counter, a new Object, which shows $moves under the Preview.

ObjectPlayer Counter
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextMoves {$moves}
Font Size14
EmphasisSemibold
Color#263D54
RenderingVector

Place it at 815 and -732.

Run the game, tap a piece, then tap another. They trade, and Moves reads 1. Now look at the Preview’s top-left corner, and find that piece on the board. Drag it onto the board’s top-left slot, and watch the caption. It reads 1 / 64.

2.7 The Keyboard

Next, the keys learn to do what your hands do.

Press the left arrow, and a blue edge appears on the top-left slot. Walk it round the board with the arrows. Press Enter, and the piece under it turns gold, as if you’d tapped it. Keys 1 to 9 choose the first nine slots straight away.

2.7.1 Choose Slot

Choose Slot is a tap without the pointer. It writes the slot into $chosenSlot and sends pieceChosen to Puzzle Rules. From there on, Player Exchange can’t tell a key from a tap, and it doesn’t need to.

FunctionChoose Slot

Tells Puzzle Rules that the player chose a slot, as a tap on a piece does. Keys 1 to 9 and Enter use it.

PARAMETERS
NameTypeStarts at
puzzleRulesObjectPuzzle Rules
slotNumber0
ACTIONS
1Change Variable
Variable
$chosenSlot
Value
slot
2Trigger Custom Event on Object
Applies to
puzzleRules
Custom Event
pieceChosen

2.7.2 Move Focus

Move Focus walks the blue focus by some number of slots, its distance. It counts in reading order. So 1 is one slot right, and -1 is one slot left.

One row down is a whole row of slots further on, $gridSize of them, and one row up is that many back. Off the right end of a row, the focus comes out at the start of the next.

A hidden focus first appears on the first slot, and the move starts from there. So the right arrow shows it one slot along. A move that would leave the board does nothing, so the focus stops at the first slot and the last.

FunctionMove Focus

Moves the keyboard focus by distance slots in reading order: 1 is one slot right, -1 one slot left, gridSize one row down. The focus stops at the first and the last slot of the board.

PARAMETERS
NameTypeStarts at
distanceNumber1
ACTIONS
1Declare Variable
Name
nextSlot
Value
0
2If$focusSlot == (-1)
Then
3Change Variable
Variable
$focusSlot
Value
0
4Change Variable
Variable
nextSlot
Value
$focusSlot + distance
5IfnextSlot >= 0 && nextSlot < ($gridSize * $gridSize)
Then
6Change Variable
Variable
$focusSlot
Value
nextSlot
7Trigger Custom Event
Custom Event
selectionChanged

2.7.3 Keyboard Focus

Keyboard Focus is fifteen Events, one for each new Command, and most of them are one line long. Keys 1 to 9 call Choose Slot with slots 0 to 8, because the first slot is 0. The arrows call Move Focus with their distances. Enter chooses the focused slot, but only when a focus is showing.

The card is long. After the second Event, your hands will know the rest.

Its last Event hears piecePressed. The moment you touch a piece, the pointer takes over, and the blue focus hides. The next arrow key brings it back, starting from the first slot.

Logic ComponentKeyboard FocusAttach to: Puzzle Rules

The keyboard plays like the pointer: keys 1 to 9 choose a slot, the arrow keys move a blue focus over the board, and Enter chooses the focused slot.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
puzzleRulesObjectConstantNone
When Piece1 Is Pressed
WhenCommand PressedCommand: Choose Piece 1
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
0
When Piece2 Is Pressed
WhenCommand PressedCommand: Choose Piece 2
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
1
When Piece3 Is Pressed
WhenCommand PressedCommand: Choose Piece 3
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
2
When Piece4 Is Pressed
WhenCommand PressedCommand: Choose Piece 4
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
3
When Piece5 Is Pressed
WhenCommand PressedCommand: Choose Piece 5
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
4
When Piece6 Is Pressed
WhenCommand PressedCommand: Choose Piece 6
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
5
When Piece7 Is Pressed
WhenCommand PressedCommand: Choose Piece 7
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
6
When Piece8 Is Pressed
WhenCommand PressedCommand: Choose Piece 8
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
7
When Piece9 Is Pressed
WhenCommand PressedCommand: Choose Piece 9
1Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
8
When Left Is Pressed
WhenCommand PressedCommand: Focus Left
1Move FocusFunction
distance
-1
When Right Is Pressed
WhenCommand PressedCommand: Focus Right
1Move FocusFunction
distance
1
When Up Is Pressed
WhenCommand PressedCommand: Focus Up
1Move FocusFunction
distance
-$gridSize
When Down Is Pressed
WhenCommand PressedCommand: Focus Down
1Move FocusFunction
distance
$gridSize
When Select Is Pressed
WhenCommand PressedCommand: Select Focused Piece
1If$focusSlot >= 0
Then
2Choose SlotFunction
puzzleRules
@self.puzzleRules
slot
$focusSlot
On Piece Pressed
WhenpiecePressedCustom Event
1Change Variable
Variable
$focusSlot
Value
-1
2Trigger Custom Event
Custom Event
selectionChanged

Attach Keyboard Focus to Puzzle Rules. Run the game, press the right arrow a few times, and press Enter. Move on, and press Enter again. Two pieces trade, and your hand never once went near the mouse while they did.

2.8 The Finished Picture

Last, the game learns to notice when you’ve won.

The caption above the board already counts the pieces that are home, one by one, as you bring them in. What’s missing is the moment it reaches 64 / 64: the Message Line says Picture complete, and the game knows it’s solved.

2.8.1 Picture Complete

Picture Complete watches one number, $piecesHome. Its Event is Variable Changed, which runs whenever that Global has changed, so nothing has to check the board every frame.

When every piece is home, it sets the Game State to Solved and puts Picture complete on the Message Line. Otherwise it sets Playing. A Game State is the mode the whole game is in. Nothing reads it yet. In Chapter 5, it’s what lays the whole picture over the board.

Variable Changed waits for the end of the frame. That small wait matters. Your last exchange clears the Message Line first, and Picture complete arrives after it, so it stays.

Logic ComponentPicture CompleteAttach to: Puzzle Rules

Sets the Game State: Solved once every piece is home, Playing while any piece is away from home.

Attach toAny Object
On Variable Changed · Pieces Home
WhenVariable ChangedGlobal Variable: piecesHome
1If$piecesHome == ($gridSize * $gridSize)
Then
2Set Game State
Game State
Solved
3Change Variable
Variable
$message
Value
data('Messages', 'solved', 'words')
4Otherwise
5Set Game State
Game State
Playing

Attach Picture Complete to Puzzle Rules. Its Changes card shows all five new Logic Components in their places, using the same puzzleRules Shared Variable.

ObjectPuzzle RulesAddDelete
Data Structure
From LogicMake Board
Data StructureMake Board Data
Logic
Make Board
Arrange Board
Pieces Home
Puzzle Commands
Player Exchange
Piece Press
Input Interruptions
Keyboard Focus
Picture Complete
Shared Variables
puzzleRulesPuzzle Rules
outlinePiece Outline
piecePiece

Now you can finish the Village by hand. It takes a while, and it’s the whole puzzle, played for real.

Play it!

Watch for each of these.

  • Under the title, in gray: Drag or tap two pieces to exchange them.
  • Under the Preview, Moves 0.
  • Every edge starts dark green-gray. A press paints blue, and a selection paints gold.
  • Press a piece and hold it, and a thin blue edge rings it. Let go over the table, away from every piece, and the blue goes. Nothing trades.
  • Tap a piece. Its edge turns gold, and the bottom line says Choose another piece. Tap it again. The gold and the words both go.
  • Tap one piece, then another, and they trade places. Moves reads 1.
  • Drag one piece onto another. They trade the moment you let go, and Moves goes up by 1.
  • Press 1, and the top-left piece turns gold. Press Escape, and it’s forgotten.
  • Press the left arrow. A blue edge appears on the first slot. Walk it with the arrows, and it stops at the board’s first slot and its last.
  • Bring a piece home. The caption over the board counts up by one.
  • Press N or R, and Moves goes back to 0.
  • Put every piece home. The caption reads 64 / 64, and the bottom line says Picture complete.
How it works

Piece Pointer reports a press. Piece Press decides whether it was a tap or a drag. Player Exchange decides what a choice means. Make Player Exchange trades the two slots and counts the Move. Every Piece shows its new piece, and every Outline paints its edge.

Underneath, it’s Chapter 1’s idea again. The table is the puzzle, and your hands never move a picture. They trade two numbers in Board Slots, and the pictures follow. The computer will do exactly the same, from the next chapter, one neighboring pair at a time.

2.9 If It Didn’t Work

A chapter with this many messages has a few places to slip. That’s normal. Run the game, watch what the board does, and think it through.

The edges never change color at all? Perhaps no one hears selectionChanged. Look for Show Outline on the Piece Outline, in its Attached Logic. Check the message’s name in Show Outline’s When bar, and in Piece Press, capital C and all.

A press turns nothing blue? The press may never reach Puzzle Rules. Look at Piece Pointer on the Piece, and at the Piece’s puzzleRules Shared Variable. Then look for Piece Press on Puzzle Rules.

The gold appears, but the second tap selects instead of trading? Player Exchange may never have switched. Look at the Switch Mode at the end of Nothing Selected, which should name One Selected. Or the two Modes may have their Actions the wrong way round.

The pieces trade, but your next tap doesn’t turn a piece gold? Then pieceChosen is still in One Selected. Look at the Switch Mode just before One Selected’s Clear Selection. It should name On Piece Chosen and Nothing Selected.

Moves counts, but the pictures don’t change? Show Piece needs its third Event, piecesExchanged. If the pictures change but the caption doesn’t, Pieces Home needs the same Event.

A drag does nothing, though a tap works? Look at Piece Press’s pieceReleased, and its If inside an If. The drag is the inner If’s Else.

A press stays blue after you let go outside the board? Look at Piece Press’s End Step. It needs both Modes, and Release Seen switches back to No Release at its end.

The arrows move the focus the wrong way, or by a whole row? Check each arrow Event’s distance. Up and Down are a whole row, $gridSize, with a minus sign in front for Up.

Each of these is one small fix. Make it, run the game again, and you’re back with the chapter. Every wrong turn showed you one more place where a message goes. And the catch-up download in the Goal is this chapter’s game, finished, if you’d like to compare.

Challenge

How few Moves can you finish the Village in? Reset first, so you start from the very first deal, the one every later chapter counts from too. Here’s one way to think about it, if you’d like a start. Every exchange can bring at least one piece home: take the piece that belongs in some slot, and trade it into that slot. Sometimes an exchange brings two home at once. See how many of those you can find, and watch Moves when the caption reads 64 / 64.

The picture is whole again, and your hands did it. In Chapter 3, the computer takes its first look.