Demotron / Beginner basics / 04
Input and First Moves
1 Steer Demi
btn(0) gives us a number while the left arrow is down and false while it isn't, and btn(1) does the same for the right arrow. Put each one in an if and we can steer:
1if (btn(0)) x -= speed
2if (btn(1)) x += speedif runs the rest of the line whenever what's in its brackets isn't false, and any number counts. A key gives 255, and so does a stick pushed all the way, but a stick pushed part way gives less. speed is a variable holding 2 here, the number of pixels we move each frame.
These lines go in _update, so we check 60 times a second. btn only knows what's down this frame, and the frame after you let go it's false and Demi stops. 2 pixels a frame is 120 a second, a quarter of the screen.
2 Four Ways
Up and down are buttons 2 and 3, and they move y:
1if (btn(2)) y -= speed
2if (btn(3)) y += speedUp takes speed off, because Picotron counts y from the top of the screen. The top row is 0 and the bottom one is 269. If you've drawn graphs at school this is upside down. Screens count rows from the top, like lines of text.
We get diagonals for free, since holding up and right runs both lines in the same frame. The boxes on the slide say 181 then, where one arrow gives 255.
3 Speed
1speed = 2 -- pixels a frameAll four btn lines use speed, so we set every direction with this one line. If we'd typed 2 four times, then the day we missed one, Demi would walk faster left than right and we'd spend a while wondering why.
Because it's a variable we can change it while the game runs, which is all the speed slider on the slide does. On 6, Demi crosses the room in about a second and a quarter.
4 Diagonals
Hold right and down and we add 2 to x and 2 to y in the same frame. Those are the two short sides of a triangle, and Demi goes along the long one, the hypotenuse. Pythagoras says the long side is the square root of the two short sides squared and added together, so here it's the square root of 2 × 2 + 2 × 2, which is 2.83 pixels, 1.41 times as far as one arrow.
1.41 is the square root of 2, and it comes out the same at any speed. 6 across and 6 down make 8.49.
5 Fixing Diagonals
Picotron already knows a diagonal is too fast. Hold two arrows and btn gives 181 for each instead of 255, because it treats the arrows like a round stick pushed into a corner, and 181 is 255 shrunk by about 1.41. Our ifs only check yes or no, so they throw that away. We use the numbers instead:
1dx = (btn(1) or 0) - (btn(0) or 0)
2dy = (btn(3) or 0) - (btn(2) or 0)
3x += speed * dx / 255
4y += speed * dy / 255For a button that's up we get false, and or 0 turns that false into a 0 we can do sums with. dx is right's number take away left's, so holding right makes it 255 and holding left makes it -255. With both held, or neither, the two cancel out to 0. Dividing by 255 turns a full press into 1, so one arrow still moves speed pixels.
On a diagonal we get 181 for each, and 181 / 255 of 2 is 1.42 across and 1.42 down. Pythagoras makes that 2.0 along the slant, the same as a straight line. Turn fix off to see the 2.83 come back. The dx line is the manual's own example from its btn entry.
6 Hop and Beep
Z (Picotron's O button) is button 4 and X is button 5, and we read them with btn(4) and btn(5) like the arrows.
For hopping that works, and holding Z keeps Demi hopping. For a beep it doesn't, because btn is yes on every frame the button is down. Hold X for a second and we get 60 beeps, and Demi has turned into a smoke alarm.
7 Once per Press
btnp is yes only on the frame a button goes down, so it's the one for anything that should happen once per press, like a beep or a hop:
1if (btn(5)) notes += 1 -- a note every frame X is held
2if (btnp(5)) notes += 1 -- a note each time X goes downWith btnp we get one note per tap, even though your finger stays on the key for several frames. Demi's hop uses it now too, so a tap of Z is one hop.
Hold X down, though, and the notes keep coming. A held button repeats by itself. After 30 frames we get a yes again, then another every 8 frames. Those are the orange ticks on the tape, and they're why the notes counter pulls ahead of the presses.
The two delays live in Picotron's memory, and we can change them with poke, which writes a number to an address:
1poke(0x5f5c, 30) -- frames before the first repeat
2poke(0x5f5d, 8) -- frames between repeatsThe first and every sliders on the slide do exactly this. Put 255 in the first address and a held button never repeats, and 0 in either puts back the default.
8 Ask in _update
Demi reads X with btnp in _update, and Fuzz, the grumpy old CRT, reads it in _draw. Switch on busy, press X a few times, and Fuzz starts missing presses.
Busy makes every _draw stall until the frame has used 1.2 frames' worth of time. Picotron does what Basics 2 said it would. It keeps _update at 60 a second and skips draws to catch up.
Picotron works out btnp's answers fresh at the start of every _update. When two updates run back to back, a press the first one saw is gone by the second, and the draw that finally runs never hears about it. Poor Fuzz, who was grumpy to begin with.
So we read every button in _update, the mouse too. The mouse would cope in _draw, since mouse() only says what's down right now, but keeping all our input in one place is tidier.
9 The Mouse
1mx, my, mb = mouse()It hands back several numbers at once, and the names on the left of the equals sign catch them in order, the pointer's x, then its y, then the buttons. The scroll wheel comes after those three.
In mb we get the buttons that are down, added up. Left is 1 and right is 2, so holding both makes 3. With nothing down it's 0.
There's no btnp for the mouse, and a click lasts a few frames, so if we placed a data gem every frame the button was down we'd get a little pile of them. Instead the slide keeps last frame's buttons in a variable, and a click is a frame where a button is down now and wasn't down then. Only that frame places a gem.
10 Gem Dash
You get 30 seconds to beat Fuzz to the gems. Hop over Glitch with Z or beep it away with X, and click the floor to beam in more gems.
Fuzz hops for whichever gem is nearest, including the ones you place, so putting them right under Demi's feet is technically allowed. On 6 speed Fuzz pretty much doesn't stand a chance.
11 Try It
This lesson's try-it demo is a small etch-a-sketch program.
- The four
btnlines steer the pen, speed pixels a frame. btnp(5)picks the next colour andbtnp(4)wipes the page, once per press each.col % 15 + 1takes colour 15 back round to 1, because Picotron does the % before the +.- All the buttons are read in the update, where no press gets lost.
mouse()gives the pointer and its buttons. The left button paints a dot of colour col every frame it's down, and the right one paints colour 1, the page's dark blue, which rubs out.
The slides have been cheating. Some hidden code keeps Demi inside the room, so you can hold left all day and Demi just stands at the edge. The etch-a-sketch has nothing like that. Steer the pen off the side and it keeps drawing where nobody can see, and you have to steer back blind.
Start up Picotron, copy the code below and paste it into the code editor's main.lua, then press Ctrl + R. The comment at the top says which button does what.
Try This
- Make X skip colour 1. It's the page's own dark blue, so for one press in every fifteen the pen draws in invisible ink.
- Make the pen come back on the left when it goes off the right, and the same for the other three edges.
- Make the pen's diagonals no faster than its straight lines, using
btn's numbers the way Demi does. - Make holding both mouse buttons paint a blob bigger than either button does on its own.
- Show the pen's x and y in the top right corner. The page never gets cleared, so the numbers pile up into a smudge.
Built with Picotron 0.3.0d.