Phones, tablets and gamepads
A phone has no arrow keys, and a living-room console has no keyboard at all. In Keys, the mouse and a finger you saw that a finger works the mouse. Now for the rest: buttons on the screen, the ways a finger can steer, and a gamepad in your hands.
A gamepad on the screen
GAMEPAD ON puts a gamepad over the game: a D-pad on the left, A, B, X and
Y on the right, and START in the middle. Each button presses a key, and
GAMEPAD MAP says which one. So a game that reads keys with keydown
works on a phone without changing a line of its loop.
SCREEN 320, 240
GAMEPAD ON
GAMEPAD MAP "UP", "Up"
GAMEPAD MAP "DOWN", "Down"
GAMEPAD MAP "LEFT", "Left"
GAMEPAD MAP "RIGHT", "Right"
GAMEPAD MAP "A", "Space"
x = 160
y = 80
DO
IF COOLDOWN(1)
IF keydown("Left") THEN x = x - 2
IF keydown("Right") THEN x = x + 2
IF keydown("Up") THEN y = y - 2
IF keydown("Down") THEN y = y + 2
shade = 14
IF keydown("Space") THEN shade = 12
MEMORYBUFFER "scene"
CIRCLE (x, y), 10, shade, shade
END MEMORYBUFFER
FRAME
CLS
PUTIMAGE (0, 0), "scene"
END FRAME
END IF
LOOP
The buttons are called "UP", "DOWN", "LEFT", "RIGHT", "A", "B",
"X", "Y" and "START". A button you haven’t mapped presses nothing.
Making it yours
Most games don’t need every button. A few more words tidy the gamepad up:
GAMEPAD BUTTON "B", FALSEhides a button, andTRUEbrings it back.GAMEPAD BUTTON "A" !! at((0.85, 0.8))moves one. The place is a share of the screen, from 0 to 1 each way, so it lands in the same spot on any size of phone.GAMEPAD ALPHA 0.5makes the whole gamepad half see-through.GAMEPAD SETIMAGE "A", "jump"draws a button with an image of yours.GAMEPAD DPADsays how the D-pad works:"buttons", four of them, the way it starts;"joystick", a stick you push any way, diagonals and all; or"drag", where you put your thumb down anywhere and slide it.GAMEPAD OFFhides it, for a cutscene or a menu you tap, andGAMEPAD RESETforgets everyGAMEPAD MAP.
Here’s a gamepad for a runner, where all you do is jump: one big button, faint, in the corner where a right thumb rests.
SCREEN 320, 240
MEMORYBUFFER "jump", 32, 32
CIRCLE (16, 16), 15, 12, 4
POLYGON [(16, 6), (26, 20), (6, 20)], 15, 15
END MEMORYBUFFER
FOR button = ["UP", "DOWN", "LEFT", "RIGHT", "B", "X", "Y", "START"]
GAMEPAD BUTTON button, FALSE
END FOR
GAMEPAD BUTTON "A" !! at((0.88, 0.82))
GAMEPAD SETIMAGE "A", "jump"
GAMEPAD ALPHA 0.6
GAMEPAD MAP "A", "Space"
GAMEPAD ON
y = 200
speed = 0
DO
IF COOLDOWN(1)
IF keydown("Space") AND y = 200 THEN speed = -6
speed = speed + 0.3
y = min(y + speed, 200)
MEMORYBUFFER "scene"
LINE (0, 211) -> (319, 239), 2 !! box fill
CIRCLE (60, y), 10, 14, 14
END MEMORYBUFFER
FRAME
CLS
PUTIMAGE (0, 0), "scene"
END FRAME
END IF
LOOP
Steering with a finger
Some games are better with no buttons at all. Here’s what I know about a finger on the screen:
touchx, touchy | Where a finger is touching, or -1 when none is. Only a finger: the mouse doesn’t count. |
mousex, mousey | Where the mouse is, or a finger. |
tap | 1 while a finger (or the mouse button) is held down and hasn’t moved. |
dragx, dragy | How far a finger (or the mouse) has been dragged since it went down, from -1 to 1, and 0 when it isn’t dragging. |
dragx and dragy make a joystick out of the whole screen: put a finger
down anywhere and slide it. Halfway across the screen is all the way, 1 or
-1. Try it with the mouse, too: hold the button and drag.
SCREEN 320, 240
x = 160
y = 120
DO
IF COOLDOWN(1)
x = clamp(x + dragx * 4, 0, 320)
y = clamp(y + dragy * 4, 0, 240)
shade = 11
IF tap THEN shade = 15
MEMORYBUFFER "scene"
POLYGON [(x, y - 8), (x + 6, y + 6), (x - 6, y + 6)], shade, shade
END MEMORYBUFFER
FRAME
CLS
PUTIMAGE (0, 0), "scene"
END FRAME
END IF
LOOP
Press and hold without moving and the ship lights up: that’s tap. As soon
as you drag, tap goes back to 0 and the ship starts to move.
Where am I running?
ismobile is 1 on a phone or a tablet, and isconsole is 1 on a console in
the living room. Use them to pick the controls and the words on the screen:
SCREEN 320, 240
IF ismobile
GAMEPAD ON
PRINT "Tap A to start"
ELSE IF isconsole
GAMEPAD PHYSICAL ON
PRINT "Press A to start"
ELSE
PRINT "Press Space to start"
END IF
Crash-tan’s Tip: On a console there’s no screen to touch, so I never show the on-screen gamepad there, even if you ask. Its players have a real gamepad, which is next.
A gamepad in your hands
GAMEPAD PHYSICAL ON, which you met in Keys, the mouse and a finger,
switches on real gamepads. Once it’s on, GAMEPAD MAP works for them as it
does for the one on the screen: the same mapping and the same keys, so one
loop serves the keyboard, the screen and the gamepad.
For more than keys, ask the gamepad itself. joybutton(n) is 1 while a
button’s held: 0 is A, 1 is B, 2 is X, 3 is Y, and 9 is START.
joyaxis(0) and joyaxis(1) are the left stick, from -1 to 1, and
joyaxis(2) and joyaxis(3) the right one. Each takes a second number to
read the second gamepad, the third, or the fourth.
RUMBLE shakes it. !! strength is how hard, from 0 to 1, and
!! duration is for how long, in milliseconds.
SCREEN 320, 240
GAMEPAD PHYSICAL ON
GAMEPAD MAP "A", "Space"
x = 160
was_down = FALSE
DO
IF COOLDOWN(1)
stick = joyaxis(0)
IF abs(stick) > 0.2 THEN x = clamp(x + stick * 4, 10, 310)
IF keydown("Left") THEN x = x - 3
IF keydown("Right") THEN x = x + 3
// A, or Space on the keyboard: a shake you can feel.
down = keydown("Space")
IF down AND NOT was_down THEN RUMBLE !! strength(0.8) duration(150)
was_down = down
MEMORYBUFFER "scene"
CIRCLE (x, 120), 12, 14, 14
END MEMORYBUFFER
FRAME
CLS
PUTIMAGE (0, 0), "scene"
LOCATE 1, 1
PRINT "gamepads:", joyconnected
END FRAME
END IF
LOOP
Crash-tan’s Tip: A stick never rests at exactly 0. Ignoring anything under 0.2, as that loop does, keeps a sprite from creeping about on its own.