Skip to content

sinclairHansen/Rubiks-Cube-Game-Controller

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 

Repository files navigation

Rubiks-Cube-Game-Controller

The goal of this project is to use a Bluetooth GAN smart Rubik's cube as a game controller.
The idea is:

  1. Track cube movements in the browser using Andy Fedotov's GAN Web Bluetooth demo.
  2. Forward each move over a WebSocket to a local Node script.
  3. Map each cube move to a keyboard key in index.js, so the cube "presses" keys.

Most of the heavy lifting is done by Andy Fedotov's package that connects GAN cubes to a web app and exposes move events:

https://github.com/afedotov/gan-web-bluetooth

GAN demo site used here:

https://afedotov.github.io/gan-cube-sample/

Video of cube being used to play tetris:

https://youtube.com/shorts/Aap78g6D09s?feature=share

Requirements

  • Node.js installed
  • A supported GAN smart cube (for example GAN356 i Carry)
  • A browser that supports Web Bluetooth (Chrome recommended)
  • macOS if you use the provided AppleScript based index.js (other platforms will need a different keypress implementation)

Instructions

Create a new directory and initialize it:

mkdir cube-controller
cd cube-controller
npm init -y
npm install ws

Download the provided index.js, which listens for cube moves from WebSocket and turns them into keypresses. You can edit the file to change which key each side maps to. The current index.js file is designed for Tetris.

node index.js

You should see:

WebSocket server listening on ws://localhost:8081

Open the GAN cube sample site in Chrome: https://afedotov.github.io/gan-cube-sample/

Connect your cube using the UI on that page. You may need to enter the cube Bluetooth MAC address in the site, depending on your model and browser.

Open Chrome DevTools and go to the Console tab.

With the cube connected and DevTools open on the demo site, paste this snippet into the console:

(() => {
  const ws = new WebSocket("ws://localhost:8081");
  ws.onopen = () => console.log("[WS] open");
  ws.onerror = (e) => console.log("[WS] error", e);
  ws.onclose = () => console.log("[WS] close");

  const origLog = console.log;

  console.log = function (...args) {
    // Look through every argument that gets logged
    for (const a of args) {
      if (
        a &&
        typeof a === "object" &&
        a.type === "MOVE" &&
        typeof a.move === "string"
      ) {
        // caught a cube MOVE object like {type:"MOVE", move:"R'"}
        if (ws.readyState === WebSocket.OPEN) {
          origLog("[HOOK] sending move to Node:", a.move);
          ws.send(a.move);
        } else {
          origLog("[HOOK] WS not open yet, move:", a.move);
        }
      }
    }


    origLog.apply(console, args);
  };
})();

When you twist the cube, you should see in the browser console:

[HOOK] sending move to Node: R'

And in the terminal where node.js is running:

[ws] Browser connected
[ws] got message: "R'"
[pressKey] Running: tell application "System Events" to key code 56

The move to key mapping is fully customizable in index.js.

This implementation uses AppleScript and System Events on macOS to generate keystrokes. It can type into any focused text field and some games, but not all games will treat these as real movement keys.

You will need to allow your terminal application to control the computer in macOS Privacy and Security settings so System Events can send keystrokes.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors