Skip to content

Modus-Logo-Long-BlackCreated with Sketch.

  • Services
  • Work
  • Blog
  • Resources

    OUR RESOURCES

    Innovation Podcast

    Explore transformative innovation with industry leaders.

    Guides & Playbooks

    Implement leading digital innovation with our strategic guides.

    Practical guide to building an effective AI strategy
  • Who we are

    Our story

    Learn about our values, vision, and commitment to client success.

    Open Source

    Discover how we contribute to and benefit from the global open source ecosystem.

    Careers

    Join our dynamic team and shape the future of digital transformation.

    How we built our unique culture
  • Let's talk
  • EN
  • FR

Handling User Input in an Arduboy Game

Published on May 22, 2017
Last Updated on April 8, 2021
Application Development

EVADE!

Welcome to our latest in-depth post on the programming of our Arduboy game, EVADE. This is a continuation of a series of posts. So, if you missed our introductory one: Creating EVADE, a Side Scrolling Shooter Game for Arduboy give it a quick read. There are a lot of great tips for getting your Arduboy development environment up and running. We also published details on how we managed text in our game.

Today, we’re going to show you how to handle the input buttons in your game by using:

Standard Arduboy button functions
Debouncing
Button functions provided with the Arduboy2 library

User Input

The Arduboy has six input buttons:

  • Four directional buttons
    • LEFT_BUTTON
    • RIGHT_BUTTON
    • UP_BUTTON
    • DOWN_BUTTON
  • Two action buttons
    • A_BUTTON
    • B_BUTTON

The standard Arduboy API library comes with a couple of built in button functions:

  • pressed()
  • notPressed()

You can use these to detect a single button press:

> if (pressed(DOWN_BUTTON))

or simultaneous button presses:

if (pressed(DOWN_BUTTON + A_BUTTON))

Keep in mind that pressed() will return true if the button is pressed down and will continue to return true as long as that button is held. Don’t confuse this behavior with the button being pressed and then released.

There’s a potential problem here. Let’s say, for example, you are going to fire your ship’s guns when the A button is pressed. Easy enough you think. So you quickly code up the following:

if (pressed(A_BUTTON) {
    fireGuns();
}

The problem with simply calling the pressed function this way is that your fireGuns function may be called 30-60 times in a single frame. You thought you were going to fire a single bullet. Instead, you end up with a fire hose of bullets that looks like a straight line!

So, while these basic functions work well, you may find that you’ll need to introduce a delay (debounce) to make them feel right and also to decrease any auto repeat. We could use the excellent Arduboy2 API fork to do that but first, let’s see if we can do it manually.

To wire up a simple debounce, we will keep track of the current vs. previous button state from frame to frame and also introduce our own debounce delay. Here is a code snippet from EVADE. I’ve edited it down to the important bits but if you want to see the entire thing, head over to the EVADE repo here.

#define DEBOUNCE_DELAY 100

void settingsScreen() {
  long lastDebounceTime = millis();  // the last time the button was pressed
  bool exit_settings_menu = false;
  arduboy.clear();
  ...

  while (!exit_settings_menu) {
    unsigned long currentMilliseconds = millis();

    if ((currentMilliseconds - lastDebounceTime) > DEBOUNCE_DELAY) {
      ...
      if (arduboy.pressed(DOWN_BUTTON)) {
      // handle user input here
    }
    ...
    }
  }
}

Simple stuff but… there is an excellent Arduboy library we can use as an alternative to the base one. It’s called Arduboy2 and it that provides us with all of the debouncing and button polling functions we need:

  • pollButtons() : will check to see which buttons have been pressed or released and then track their current state in relation to their last state.
  • justPressed() : will return true if the button was pressed between the previous call to pollButtons() and the current call to pollButtons().
  • justReleased() : will return true if the button was pressed but has now been released between the previous call to pollButtons() and the current call to pollButtons().

In addition to better button functions, the Arduboy2 library also gives us:

  • Team A.R.G.’s Arglib sprite and compressed image drawing
  • Collision detection
  • Frees up more code space by allowing you to remove optional library functions
  • Alternative sound generation
  • Minimal boot sequence

Game Over

Dealing with user input in your game is another one of the fundamental things you need to tackle. Once again, the Arduboy does come with some of the basic functions but you will most likely need something more.

We discussed rolling your own button handling functions and debouncing to make your user input a bit smoother. You may also want to check out the Arduboy2 API fork which will give you all of the above plus a lot more.

Play EVADE!

If you’d like to play our game yourself, you’ll need:

  • An Arduboy device ($49) from arduboy.com, Adafruit, or Pimoroni (United Kingdom)
  • The Arduino IDE (free), works on Mac, Windows and Linux, required to install our code
  • Our code, which is open source and downloadable from GitHub where you will also find instructions on compiling and installing it using the Arduino IDE

Let Us Know What You Think

We hope you enjoy playing our game as much as we enjoyed writing it. We’d love to see pictures of your high scores, tag us on Instagram or tweet us a photo of your high scores using the hashtag #evadehighscore.

Posted in Application Development
Share this

Simon Prickett

Simon Prickett is a pragmatic technology enthusiast with broad experience of technical consultancy, product and software development, technical training, software architecture, development and system analysis. Simon has developed and led solutions for clients including MTV Networks, Coca-Cola and USA Today. Simon graduated top of his class from Aston University. During his time with Modus Create, Simon filled the role of Architect.
Follow

Related Posts

  • Evade Annoucement, our first Arduboy Game
    Announcing EVADE, our first Arduboy Game

    EVADE is Modus's very first game for the Arduboy platform. Learn how a highly performing…

  • EVADE featured in Arduboy Magazine Volume 1
    EVADE featured in Arduboy Magazine

    On Friday February 24, 2017, we were excited to learn that our game, EVADE, was…

Want more insights to fuel your innovation efforts?

Sign up to receive our monthly newsletter and exclusive content about digital transformation and product development.

What we do

Our services
AI and data
Product development
Design and UX
IT modernization
Platform and MLOps
Developer experience
Security

Our partners
Atlassian
AWS
GitHub
Other partners

Who we are

Our story
Careers
Open source

Our work

Our case studies

Our resources

Blog
Innovation podcast
Guides & playbooks

Connect with us

Get monthly insights on AI adoption

© 2025 Modus Create, LLC

Privacy PolicySitemap
Scroll To Top
  • Services
  • Work
  • Blog
  • Resources
    • Innovation Podcast
    • Guides & Playbooks
  • Who we are
    • Our story
    • Careers
  • Let’s talk
  • EN
  • FR