Framer for Games: Arcade Joystick
3 min readAug 4, 2016
Core mechanic: Mapping layer positions with Utils.Modulate
Upcoming games and/or game mechanics in this series
Tune in Thursday mornings for a new entry in this series. I’d love to read your suggestions in the comments.
- Raid HQ Character Selection [Thursday, June 23]
- Endless Runner [Thursday, June 30]
- Guitar Hero [Thursday, July 7]
- Card Match [Thursday, July 14]
- Snake [Thursday, July 21]
- Dropping Ball Catcher [Thursday, July 28]
- Arcade Joystick [Thursday, August 4]
- Sliding Blocks [Thursday, August 11]
- Vertical Platformer [Thursday, August 18]
- Pong [Thursday, August 25]
- Tempest [Thursday, September 1]
Link to Framer Prototype
This prototype is not so much of a game, but rather a simulation of a physical game controller: the arcade joystick. Grabbing it by its handle and dragging in any direction controls an element on the screen.
Game elements
- Joystick component
- Object controlled by the player object
- [Optional] button to toggle right- and left-handedness
Joystick component
# Joystick Components# Area at large to encompass both positions for joystick
joystickArea = new Layer
x: Screen.width / 2
y: 901
width: 300, height: 300
backgroundColor: "transparent"
borderColor: "maroon"
borderWidth: 10
borderRadius: "50%"
joystickArea.states.animationOptions = time: 0.2
joystickArea.states.add
right:
x: Screen.width / 2
left:
maxX: Screen.width / 2# Layer acting as visual joint for joystick handle [Grey shape under joystick]
joystickHandle = new Layer
parent: joystickArea
x: Align.center
y: Align.center
width: 150, height: 150
borderRadius: "50%"# Draggable joystick object
joystick = new Layer
parent: joystickArea
width: 200, height: 200
x: Align.center
y: Align.center
borderRadius: 100
backgroundColor: "red"
joystick.draggable.enabled = yes
joystick.draggable.overdrag = no
joystick.draggable.constraints =
x: 0, y: 0
width: joystickArea.width
height: joystickArea.height
Switch Hands button
# Switch Hands Button
handToggle = new Layer
y: Align.bottom
width: 750
height: 100
Utils.labelLayer(handToggle, "Switch Hands")
handToggle.style = fontSize: "48px"# When button is clicked, it toggles state on joystickArea
handToggle.on Events.Click, ->
joystickArea.states.next "left", "right"
Object controlled by joystick
# Joystick-controlled Object
player = new Layer
x: Align.center
y: Align.center(-200)
rotation: 45
borderRadius: "25%"
# Using color to denote whether object is activated by joystick
player.states.add
moving:
backgroundColor: "white"
notMoving:
backgroundColor: "gray"
Where the magic happens
# Joystick Mapping Logic# Whenever the joystick is being dragged [i.e. it's position changes]
joystick.on "change:point", ->
player.states.switch "moving"
# Update x and y position of game object by amount between 0 and 4 units
# depending on how far from the center the joystick is dragged
player.x = player.x + Utils.modulate(joystick.x, [0,100], [-4,4])
player.y = player.y + Utils.modulate(joystick.y, [0,100], [-4,4])
# Restrict boundary for player object so it never goes beyond screen
if player.x < 0
player.x = 0
if player.maxX > Screen.width
player.maxX = Screen.width
if player.y < rules.height
player.y = rules.height
if player.maxY > Screen.height - handToggle.height
player.maxY = Screen.height - handToggle.height# When joystick is no longer activated, return it to its original position
joystick.on Events.DragEnd, ->
joystick.center()
player.states.switch "notMoving"
Framer/CoffeeScript mechanics highlighted here
- Event listeners
- Layer states
- Utility methods
- Control flow