higedarumaのアイコン画像
higedaruma 2024年10月28日作成 (2024年10月30日更新) © MIT
製作品 製作品 閲覧数 80
higedaruma 2024年10月28日作成 (2024年10月30日更新) © MIT 製作品 製作品 閲覧数 80

ワンボタンでマリオを遊ぶ(アヒル型コントローラー)

ワンボタンでマリオを遊ぶ(アヒル型コントローラー)

はじめに

スーパーマリオブラザーズを遊ぶための変わったコントローラを作って展示会等で遊んでもらっていました。
小さいお子さんの場合、普通のコントローラで遊ぶこと自体が初めて子が多い事に気づいきました。
既存のマリオを誰でも簡単に遊べるようにするため、1つのボタンを押すだけで遊べる専用コントローラーを作成しました。

展示会等で細かい説明をしなくても、「勝手に遊べる」簡単さも実装のコンセプトにしています。
※合計3日ほど展示しましたが、ほぼ説明不要で遊んでもらえてます。

完成品の紹介

こちらが展示会に設営した時の写真です。
可愛いアヒル型コントローラーと、大きいボタンが特徴となっています。

展示時

実際の動作

ここに動画が表示されます

各種ボタンの動作について

強制的に右ボタンを押す状態にする事で、勝手に移動するようにし、ジャンプだけで遊べるようにしました。
※ステージによってはこのボタンだけだと厳しいかもしれませんが、今回はそこまで辿り着く方はいませんでした

大人向けに頭のキーロックを回す事で、Bダッシュ の状態になるようにしています。

ボタンが押されている状態だと、スタートは無効となるため、スタートボタンが押された場合のみ、他のキーは無視するようにしています。
また、左移動のボタンがないため、全く動けなくなる場合もあることから、すべてのボタンを同時に押すとゲームをリセットする機能も入れています。

遊び方資料
展示会において、こちらの説明資料があれば問題は起こりませんでした。

構成

装置の構成は下図の通りです
構成図

なぜモノラルジャックを使うのか?
ボタンをモノラルジャックにすることで、どんな方でもご自身が利用できる専用のボタンに変えて使って遊んでもらえると考えたからです。
参考:意思伝達装置用スイッチ

アヒルの構成

頭に、キーロック、胴に3つのモノラルジャックをつけています。

アヒル正面
可哀想ですが、頭は、12mm、胴は8mmのドリルで穴を開けています。

アヒル基板
アヒルの下に60mm程度の穴を開けています。
3D専用の土台を3プリンタで出力し、空いた穴の蓋と基板の固定(はめる感じ)を兼ねるようにしています。

アヒル配線
頭と胴からの各種配線はこのような感じ。
少し小さい大きいアヒルを使っています。
ボタンを増やす、配線が窮屈な場合は、もう少し大型のアヒルを使うも良さどうです。

アヒル後方
お尻からは任天堂Switchと接続するためのUSBケーブルを出しています。
穴を開けず切れ込みを入れて、ケーブル通しています。

ボタンの構成

モノラルプラグ対応であればどのようなボタンでも利用可能ですが、叩き心地のある大きめなボタンを用意

ボタン
ボタン自体は発光対応ですが、今回は光らせてません。

キャプションを入力できます

ボタンは、モノラルケーブルと繋ぐだけのシンプルなモノです。
筐体は、3Dプリンタで出力し、上蓋、胴、下蓋と3つを組み合わせるだけのシンプルなものです。

部品表

アヒルコントローラー

名前 数量 備考
ゴムアヒル (10.2 mm x 115mm x 130mm) 1個 https://ja.aliexpress.com/item/1005005849020308.html
Raspberry Pi Pico 1個 (共立電子) https://eleshop.jp/shop/g/gL25313/
φ3.5mm モノラルジャック パネル型 3個 (共立電子) https://eleshop.jp/shop/g/gB84131/
キースイッチ 1個 (共立電子) https://eleshop.jp/shop/g/gO8MS3Z/
QIケーブル2S-2S ※半分に切って使用 2本 (共立電子) https://eleshop.jp/shop/g/gAAC411/
ヘッダーピン 8本 (共立電子) https://eleshop.jp/shop/g/gN1K311/
30mm x 70mm ユニバーサル基板 1枚 (共立電子)https://eleshop.jp/shop/g/gGBS125/
ファストン端子 単極用 #110/メス 2個 (共立電子)https://eleshop.jp/shop/g/gN1D114/
microUSBケーブル 1本 (共立電子)https://eleshop.jp/shop/g/gH9E31E/
アヒル筐体 1個 3Dプリンタ出力

※筐体は、Githubにてモデルを公開しています。

ボタン (3個分)

名前 数量 備考
60mmラウンドプッシュボタンスイッチ 3個 https://ja.aliexpress.com/item/1005001456931168.html
ファストン端子 単極用 #205/メス 6個 (共立電子)https://eleshop.jp/shop/g/gN1D116
3.5φ片端モノラルプラグ付きケーブル 3本 (共立電子)https://eleshop.jp/shop/g/g66131S/
ボタン(上蓋) 3個 3Dプリンタ出力
ボタン(胴) 3個 3Dプリンタ出力
ボタン(下蓋) 3個 3Dプリンタ出力

※筐体は、Githubにてモデルを公開しています。

接続図

接続図

ソースコード

環境

ボード定義

ビルドを行うには、USB Stackは、Adafruit TinyUSBを選択してください。
USB Stack

使用ライブラリ

Github

onebuttonmario.ino

#include "switch_tinyusb_custom.h" #define SW_SATRT_GPIO 19 #define SW_LEFT_GPIO 18 #define SW_B_GPIO 17 #define SW_A_GPIO 16 Adafruit_USBD_HID G_usb_hid; NSGamepad Gamepad(&G_usb_hid); HID_NSGamepadReport_Data_t beforeData; bool resetFlg = false; void setup() { Serial.begin(115200); Gamepad.begin(); // wait until device mounted while( !USBDevice.mounted() ) delay(1); pinMode(SW_SATRT_GPIO, INPUT_PULLUP); pinMode(SW_LEFT_GPIO, INPUT_PULLUP); pinMode(SW_B_GPIO, INPUT_PULLUP); pinMode(SW_A_GPIO, INPUT_PULLUP); pinMode(25, OUTPUT); digitalWrite(25, HIGH); } void loop() { Gamepad.reset(); // 他のキーが押下されている場合、スタートが無効となるため // スタートが押されている場合は、他のボタンを無視する if(digitalRead(SW_SATRT_GPIO) == LOW){ // スタート押下状態で、他のボタンが押されている場合は // ゲームをリセットする if(digitalRead(SW_A_GPIO) == LOW && digitalRead(SW_STOP_GPIO) == LOW ){ if(resetFlg){ return; } //リセットフラグを有効し、複数回の実行を防ぐ resetFlg = true; resetControll(); } else{ resetFlg = false; Gamepad.press(NSButton_Plus); } } else{ resetFlg = false; //キーロックが有効の場合は、Bダッシュ状態とする if(digitalRead(SW_B_GPIO) == LOW){ Gamepad.press(NSButton_B); } if(digitalRead(SW_A_GPIO) == LOW){ Gamepad.press(NSButton_A); } bool up = false; bool down = false; // 強制的に移動させる bool right = true; // 右と左が同時に押されている場合は、無効の判断になる(なので止まる) bool left = stopButton.read() == LOW; Gamepad.dPad(up, down, left, right); } // 前回と入力が同じ場合は、ボタン操作を送信しない if(!Gamepad.compareTo(beforeData)){ Gamepad.SendReport(); beforeData = Gamepad.getReportData(); } } /** * @brief ファミコンのリセット操作 * ZL+ZR押してメニューのリセットを選ぶ操作 */ void resetControll(){ Gamepad.reset(); Gamepad.press(NSButton_LeftThrottle); Gamepad.press(NSButton_RightThrottle); Gamepad.SendReport(); delay(100); for(int i=0; i<3; i++){ Gamepad.reset(); Gamepad.dPad(true, false, false, false); Gamepad.SendReport(); delay(150); Gamepad.reset(); Gamepad.SendReport(); delay(150); } Gamepad.reset(); Gamepad.press(NSButton_A); Gamepad.SendReport(); }

最後に

展示会に置いておくだけで、みんなが勝手に遊んでくれる事を目標に、2回ほど展示しましたが、
説明の手間もなく、子供から大人まで、好き勝手に楽しんでくれていたように思います。

簡単だけど制約があるコントローラーは、同じゲームの新しい楽しみ方を教えてくれました。
そして、30年近く前の「スーパーマリオブラザーズ」のゲームデザインがいかに優れているかも気づかせてくれます。

一部ではありますが、遊んでくださった方々に感謝を
Let's Play

2
ログインしてコメントを投稿する