- Learn
- Tutorials
- Algorithms
- Cocktail Shaker Sort
- 2 Your Hands on the Board
2 Your Hands on the Board
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.
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
piecePressedto Puzzle Rules -> Piece Press keeps the pressed slot, and sendsselectionChanged. - 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 sendspieceChosenfor a tap, orpiecesDroppedfor 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
pieceChosento 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.
123456789Left ArrowRight ArrowUp ArrowDown ArrowEnterEscapePlaying, SolvedSave 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.
One row of the "Outline Colors" Data Table.
#46615a#2579bc#f3d49c2.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.
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.
Any Objectself.slotNumber- Value
data('Outline Colors', 'normal', 'color')
self.slotNumber.slot == $focusSlot || self.slotNumber.slot == $pressedSlot- Value
data('Outline Colors', 'focus', 'color')
self.slotNumber.slot == $selectedSlot- Value
data('Outline Colors', 'selected', 'color')
Attach it to the Piece Outline. The Changes card shows where.
Window / UIUIX 70, Y 70-1Outline Square#46615AX 70, Y 70Lay Out Slot, Show OutlineLay Out SlotSlot NumberNothing 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.
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.
Any Objectself.slotNumber- Variable
$chosenSlot- Value
self.slotNumber.slot
- Applies to
@self.puzzleRules- Custom Event
piecePressed
- Variable
$chosenSlot- Value
self.slotNumber.slot
- Applies to
@self.puzzleRules- Custom Event
pieceReleased
Attach it to the Piece.
Window / UIUIX 68, Y 68-1Village Pieces 64X 68, Y 68Show Piece, Lay Out Slot, Piece PointerShow Piece, Lay Out SlotSlot NumberPuzzle Rules2.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.
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.
Any Object- Variable
$pressedSlot- Value
$chosenSlot
- Custom Event
selectionChanged
$pressedSlot >= 0$pressedSlot == $chosenSlot- Custom Event
pieceChosen
- Custom Event
piecesDropped
- Variable
$pressedSlot- Value
-1
- Custom Event
selectionChanged
- Event
On End Step- Mode
Release Seen
- Variable
$pressedSlot- Value
-1
- Custom Event
selectionChanged
- Event
On End Step- Mode
No Release
- Variable
$pressedSlot- Value
-1
- 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.
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.
Any Object- Custom Event
selectionCanceled
- 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.
Reset.Choose another piece.Picture complete.The Game Goal is a new Object. It tells a new player what to do, in one gray line under the title.
Window / UIUIDrag or tap two pieces to exchange them.15Medium#526478VectorPlace 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.
The player's exchange: the pieces of two slots trade places, Moves counts it, and every Piece is told.
- firstSlot
firstSlot- secondSlot
secondSlot
- Variable
$moves- Operator
+=- Value
1
- 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.
Forgets the selected piece: the words "Choose another piece." leave the Message Line, and the Outlines are told.
- Variable
$selectedSlot- Value
-1
$message == data('Messages', 'selected', 'words')- Variable
$message- Value
""
- 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.
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.
Any Object- Variable
$selectedSlot- Value
$chosenSlot
- Variable
$message- Value
data('Messages', 'selected', 'words')
- Event
On Piece Chosen- Mode
One Selected
- Custom Event
selectionChanged
$chosenSlot != $selectedSlot- firstSlot
$selectedSlot- secondSlot
$chosenSlot
- Variable
$message- Value
""
- Event
On Piece Chosen- Mode
Nothing Selected
- firstSlot
$pressedSlot- secondSlot
$chosenSlot
- Variable
$message- Value
""
- Event
On Piece Chosen- Mode
Nothing Selected
- Event
On Piece Chosen- Mode
Nothing Selected
- Variable
$moves- Value
0
- Event
On Piece Chosen- Mode
Nothing Selected
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.
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).
Any Objectself.slotNumber- Frame
data('Board Slots', self.slotNumber.slot, 'piece')
- Frame
data('Board Slots', self.slotNumber.slot, 'piece')
- Frame
data('Board Slots', self.slotNumber.slot, 'piece')
Keeps $piecesHome, the count the Board Caption shows, equal to the number of pieces in their home slots.
Any ObjectThe keys ask for the same things as the Buttons: R for Reset, N for a new arrangement. Escape cancels a selection.
Any Object- puzzleRules
@self.puzzleRules
- puzzleRules
@self.puzzleRules
- Custom Event
selectionCanceled
Last, the Player Counter, a new Object, which shows $moves under the Preview.
Window / UIUIMoves {$moves}14Semibold#263D54VectorPlace 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.
Tells Puzzle Rules that the player chose a slot, as a tap on a piece does. Keys 1 to 9 and Enter use it.
- Variable
$chosenSlot- Value
slot
- 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.
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.
- Name
nextSlot- Value
0
$focusSlot == (-1)- Variable
$focusSlot- Value
0
- Variable
nextSlot- Value
$focusSlot + distance
nextSlot >= 0 && nextSlot < ($gridSize * $gridSize)- Variable
$focusSlot- Value
nextSlot
- 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.
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.
Any Object- puzzleRules
@self.puzzleRules- slot
0
- puzzleRules
@self.puzzleRules- slot
1
- puzzleRules
@self.puzzleRules- slot
2
- puzzleRules
@self.puzzleRules- slot
3
- puzzleRules
@self.puzzleRules- slot
4
- puzzleRules
@self.puzzleRules- slot
5
- puzzleRules
@self.puzzleRules- slot
6
- puzzleRules
@self.puzzleRules- slot
7
- puzzleRules
@self.puzzleRules- slot
8
- distance
-1
- distance
1
- distance
-$gridSize
- distance
$gridSize
$focusSlot >= 0- puzzleRules
@self.puzzleRules- slot
$focusSlot
- Variable
$focusSlot- Value
-1
- 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.
Sets the Game State: Solved once every piece is home, Playing while any piece is away from home.
Any Object$piecesHome == ($gridSize * $gridSize)- Game State
Solved
- Variable
$message- Value
data('Messages', 'solved', 'words')
- 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.
Make BoardMake Board DataPuzzle RulesPiece OutlinePieceNow you can finish the Village by hand. It takes a while, and it’s the whole puzzle, played for real.
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.
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.
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.
