In this project, we are going to use a Joystick device and connect it to the platform game we created in the previous tutorial on how to create a game with Phaser.js. Our goal is to move the player in the game using the Joystick.
To achieve this, we will use Johnny Five, a JavaScript Robotics and IoT platform. In our Node.js application, we will connect to the Joystick device and create a Websockets server. The browser client will then connect to this server and stream the movement events to control the player in the game.
Let’s get started!
The Joystick
We will be using a Joystick component in this project. It resembles the ones you can find on real-world devices like a Playstation controller. The Joystick has 5 pins: GND, +5V (VCC), X, Y, and SW. The X and Y pins correspond to the coordinates of the Joystick, indicating its movement on the X and Y axes. The SW pin is a digital output that is activated when the Joystick is pressed. For this project, we will not be using the SW pin.
Connecting the Joystick to the Arduino
To connect the Joystick to the Arduino, we will use 4 wires. Connect the GND and +5V pins of the Joystick to the GND and +5V pins of the Arduino respectively. Connect the X pin of the Joystick to analog pin A0 and the Y pin to analog pin A1 of the Arduino.
The Johnny Five Node.js App
In our Node.js app, we will use the Johnny Five library to control the Joystick. Create a new file called joystick.js
and add the following code:
const { Board, Joystick } = require("johnny-five");
const board = new Board();
board.on("ready", () => {
const joystick = new Joystick({
pins: ["A0", "A1"],
});
joystick.on("change", function () {
console.log("x: ", this.x);
console.log("y: ", this.y);
});
});
In this code, we initialize a new Board object and listen for the “ready” event. Inside the event callback, we create a new Joystick object and specify the input pins we are using for the X and Y coordinates. We then listen for the “change” event on the Joystick object, which is triggered whenever there is a change in the position of the Joystick. Inside the event callback, we log the x and y coordinates to the console.
To run this program, execute the command node joystick.js
in your terminal. You will see the x and y coordinates printed in the console when you move the Joystick.
Creating a Websockets Server
To communicate between the game running in the browser and our hardware project, we will use Websockets. We will set up a Websockets server in our Node.js app and the browser client will connect to it.
First, install the ws
npm package by running the command npm install ws
. Then, modify the code in joystick.js
as follows:
const { Board, Joystick } = require("johnny-five");
const board = new Board();
const WebSocket = require("ws");
board.on("ready", () => {
const joystick = new Joystick({
pins: ["A0", "A1"],
});
const wss = new WebSocket.Server({ port: 8085 });
wss.on("connection", (ws) => {
joystick.on("change", function () {
if (this.x > 0.5) {
ws.send("right");
} else if (this.x < -0.5) {
ws.send("left");
} else if (this.x > -0.5 && this.x < 0.5) {
ws.send("still");
} else if (this.y > 0.5) {
ws.send("down");
} else if (this.y < -0.5) {
ws.send("up");
}
});
});
});
In this code, we import the ws
module and create a new WebSocket Server on port 8085. Inside the connection event callback, we listen for the change event on the Joystick object. When a change occurs, we send a message to the connected client indicating the direction of movement based on the x and y coordinates of the Joystick.
Connecting to the Websockets Server from the Game
Next, we need to connect to the Websockets server from the game running in the browser. In the app.js
file of your game, add the following code:
const url = "ws://localhost:8085";
const connection = new WebSocket(url);
connection.onerror = (error) => {
console.error(error);
};
connection.onmessage = (event) => {
const message = event.data;
// Handle the message received from the server
};
In this code, we create a new WebSocket connection to the server using the URL of the Websockets server. If there is any error during the connection, it will be logged to the console. We also listen for the message event and handle the received message inside the event callback.
Now, inside the update()
function of your game, you can listen for events triggered by the Joystick and control the player movement accordingly:
function update() {
// Listen for Joystick events and control the player movement
connection.onmessage = (event) => {
const direction = event.data;
if (direction === "left") {
// Move the player to the left
} else if (direction === "right") {
// Move the player to the right
} else if (direction === "still") {
// Stop the player's movement
} else if (direction === "up") {
// Move the player up
} else if (direction === "down") {
// Move the player down
}
}
}
In this code, we handle the received message from the server and control the player’s movement based on the direction indicated in the message.
That’s it! Now you can control the player in your browser game using the Joystick connected to the Arduino via the Johnny Five library and Websockets.
Alternative using WebUSB:
If you want to connect the Arduino directly to the browser without using a Websockets server, you can use WebUSB, a technology available on Chromium-based browsers like Chrome and Edge. Here are the steps to follow:
-
Connect the Joystick to an Arduino board that supports WebUSB, such as the Arduino MKR WiFi 1010.
-
Upload the Arduino sketch provided in the tutorial to the Arduino.
-
In your game’s
index.html
file, add a “Connect” button with an id attribute:<button id="connect">Connect</button>
-
In your game’s
app.js
file, add the following code:import serial from "./serial.js";
-
Inside your game’s
DOMContentLoaded
event listener, add the following code:document.addEventListener("DOMContentLoaded", () => { const connectButton = document.querySelector("#connect"); let port; connectButton.addEventListener("click", () => { if (port) { port.disconnect(); connectButton.textContent = "Connect"; port = null; } else { serial.requestPort().then((selectedPort) => { port = selectedPort; port.connect().then(() => { connectButton.remove(); }); }); } }); });
-
Add the following code to the
update()
function in your game:function update() { if (port) { port.onReceive = (data) => { const key = new TextDecoder().decode(data); if (key === "L") { // Move the player to the left } else if (key === "R") { // Move the player to the right } else if (key === "S") { // Stop the player's movement } else if (key === "J") { // Move the player up (or perform a jump) } }; port.onReceiveError = (error) => { console.error(error); }; } }
With these changes, you can now control the player in your game using the Joystick connected directly to the Arduino via WebUSB.
Tags: Arduino, Johnny Five, Joystick, Websockets, WebUSB