LoginSignup
3
1

More than 3 years have passed since last update.

Live Coding Street Fighter 2 実施方法

Last updated at Posted at 2019-10-05

これはなに?

Live codingでスト2キャラクターを操作し戦うものです.

俺より強い奴(プログラマー)に会いに行く!
IT系勉強会後の宴会に良さそうです.

本記事はその実施方法解説記事です.

ハックについて

明治大学で開催されたABPro 2019(「普通じゃないプログラム作品」の発表会)にて,津田塾大・栗原一貴先生より発表のあったゲームハックです.

プログラマブルゲームコントローラー GameControllerizer を使うことで,自身のプログラム(javascript)からのキャラクター操作を可能にしています.

必要な機材

  • PC(コーディング用)
  • GameControllerizer(プログラマブル ゲームコントローラー)
  • Raspberry Pi Zero W(↑と組み合わせて使います)
  • ゲームコンソール(今回はRetroFreak)

接続方法

image.png

Raspberry Pi Zero W とPC間のネットワーク導通は確認しておきます.
あまりにも遅延が大きい環境だと実施が難しいです.

設定手順

1. GameControllerizer + RasPiZW のセットアップ

公式サイトのセットアップ方法にそって進めます.RasPi上のNode-REDが立ち上がったら,こちらのページにあるCheatSheet をimportしておきます.Dpad/Button/Stick/Misc の4タブが生成されていることを確認しておきます.

うちMiscは以下のようになっています.これの意味するところは,GameControllerizerにより外部からWebSocket経由でws://xxxx:1880/gamepad へと送られてくる制御コマンド(JSON形式)が,機械語に翻訳されゲーム機に流しこまれる,ということになります.

image.png

2. Live Coding環境のOpen

を開くとコーディング画面が表示されます.ここで指定のコマンドを記述すると,ゲーム機の制御として反映される仕組みです.実際にはページを開く際に

  • wshost RasPiのIPアドレス
  • wsport Node-REDサーバーのポート番号(default = 1880)

をクエリパラメータで指定する必要があるため,具体的なアドレスは

のようになります.

ブラウザのセキュリティ警告

Javascript内に Secured WebSocket ではなくWebSocket で通信をするコード(PC→RasPi)が書かれているため,ブラウザによってはセキュリティ警告が出ます.以下の方法で回避できますが,本件の利用が済んだら戻しておくのが良いでしょう.

Chrome

URLバーの右にある盾マークから「安全ではないスクリプトを読み込む」

Firefox

URLにabout:configを入力しEnter.設定画面が表示されたらnetwork.websocket.allowInsecureFromHTTPStrueに変更する.

※関連記事:FirefoxでhttpsからWebSocket接続(ws)するには..

導通確認

PC→RasPi間でWebSocketによる導通が確保されると,Node-REDフロー上で緑色のマークが点灯します.
image.png

3. いざコーディング!

2までできればあとはコーディングするだけです.基本的にはGameControllerizer専用の制御コマンド仕様(DSL4GC)に基づいた記述を$x()で発行する,になります.例えば波動拳なら以下になります.

hado = [
    {"dpad": 2,  "dur":3},
    {"dpad": 3,  "dur":3},
    {"dpad": 6,  "dur":3},
    {"btn": [3], "dur":3}
]
$x(hado)

なおコマンドは,多重にネストしても動作します.
あわせて,いくつかヘルプ関数を設けています(暫定調整中です).

Command Memo
$x(c) コマンドcを発行する.cはネスト配列でもOK
btnf(n,m) {"btn":[n],"dur":m}に相当.ボタンを押す
btn(n) {"btn":[n]}に相当.ボタンを押す(chain)
dpadf(n,m) {"dpad":n,"dur":m}に相当.十字キーを押す
dpad(n) {"dpad":n}に相当.十字キーを押す(chain)
i=loop(c,m) mframe間隔でコマンドcを発行する.iは識別子
unloop(i) 識別子iに相当するloopを停止する
repeat(c,m) cm回繰り返すコマンドを発行する
f(m) mframe待つ

やってみた

ガイルで一生ソニック撃っていれば,意外と簡単にクリア出来るんじゃないの?と思ったのですが...
WIN_20191006_03_07_44_Pro.jpg
あ,あれれ...ケン(3面)強いぞ.

行動部のコード

回り込まれると即死なので,ソニック x 2 → バックジャンプ x 2.
記述はこんな感じです.

hp = btnf(2,3)  // punch(high)
lp = btnf(11,3) // punch(low)
tame = dpadf(1, -1)
back_jump = dpadf(7,60)
$x(hp)

sonic = [
  dpadf(6, 2),
  hp,
  tame
]
s1 = [sonic,f(100),sonic, f(100),back_jump]
id1 = loop(s1, 360)
unloop(id1)

おわりに

コントローラーではなくプログラムで操作するとなると

  • いちいち打たないといけない煩わしさ
  • loop, repeatに代表される便利さ

が混在し,慣れ親しんだゲームも別物のようです.ただ,左右が入れ替わるといろいろと不都合がおおいです.画像認識などの手法でフィードバックが取れるとよいのですが...

次は人vs人でやってみたいですね.

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1