teaching machines

CS 491: Meeting 3 – Joystick

February 11, 2020 by . Filed under gamedev, lectures, spring-2020.

Dear students:

We have formed teams and are hashing out game ideas. Some of us are feeling the repressed artist inside of us wake up to the call of pixel art. We should keep that progress going. Right after a lab exercise!


Let’s make a game—one that uses a two-axis joystick. We’ll move an avatar around the screen with the joystick, and when it runs into something, that something will disappear.


Behold, the controller that we’ll make today:

The joystick is an analog component. An analog component yields readings across a broad spectrum of values, whereas a digital component, like a button, only yields 0 and 1. This means that the joystick supports degrees of intensity that we cannot achieve with a button.

Assemble the controller as follows:

The fifth pin on the joystick is for the button press that you can achieve by pressing the joystick toward the board. We’re not using it today.

Once assembled, follow these steps to get your firmware up and running:

What values do you see in the Serial Monitor?

Compare your answers against mine.
Hopefully you see numbers in [0, 1023].

It’d be nice if pushing left made the number go negative, idle was 0, and pushing right made the number go positive. Let’s make that happen. We want to turn a number in the top range into a number in the bottom range:

$$\begin{array}{lrcrl}[& 0, && 1023 &] \\ && \downarrow && \\ [&-512, && 511 &]\end{array}$$

What calculation do we perform?

What if we want to perform this mapping, which is a reverse of the previous?

$$\begin{array}{lrcrl}[& 0, && 1023 &] \\ && \downarrow && \\ [&511, && -512 &]\end{array}$$

What math would we use here?

Let’s keep going.

Once you have both numbers printing, we want to send them across the serial port to Unity. Last time we used Serial.write to send over a byte value in binary. We could try that here, but our numbers exceed what can be stored in a single byte. Perhaps we could do some bit twiddling to decompose the values into two separate bytes? All told, each message would be 4 bytes long.

However, we’re going to run into another issue with serial communication. The Arduino will be pushing out a steady stream of bytes. At some point our Unity game will start drawing from this stream of bytes and interpreting its contents. But it might not start at the first byte of a message. If it starts reading at the third byte, then x and y will be effectively flipped. If it starts reading at the second or fourth bytes, we’ll get some unintelligible results.

To help get our game and the Arduino in sync, let’s insert start and end markers around each message. And let’s eschew binary for the ASCII format.

As you develop your controller firmware, you’ll need to establish a protocol like this describing your message format.


Now that we have a working controller, let’s turn to our game. Complete the following to establish our scene:

Once you have confirmed that messages are getting through, it’s time to push the game object around the scene based on the intensity and direction of the joystick. Follow these steps to get your object moving:

You should now have a moving game object. For our final step, let’s add a second, stationary game object. When the player collides with it, the object disappears and the player wins. Follow these steps to achieve this endgame:

Does it work? If so, show your working game to your instructor to receive credit for this lab.


Here’s your TODO list for next time:

See you next time!