Luaで超簡単にゲームプログラミングができて、Web-APIで実機転送ができちゃうゲーム機を作ってみた。

8/11: タイトルを変更しました。
元タイトル: 1480円のマイコンでゲーム機を作ろう

どーも こんにちは。
夏休み、いかがお過ごしでしょうか？
私はゲーム**機**開発にいそしんでおります。
ゲームじゃないですよ。ゲーム機。マシンです。

# Panicがゲーム機出してたなー

遠い過去の話ですが、Codaで大変お世話になった[Panic](https://panic.com/jp/)。
その[Panic](https://panic.com/jp/)が何を血迷ったか[ゲーム機を作ってる](https://play.date/jp/)らしい。（2020年発売予定）
ゲーム機ってそんなに簡単に作れないと思ってたけど、
よく考えたら、**意外と簡単につくれるんじゃね？**

と思い立ったわけです。（子供は）夏休みだし、**自由研究にはもってこい**なわけです。


# スクリプト言語でさくっとゲームが作れて、実機に転送して遊べる
くらいできないとやっぱり**ゲーム機**とは呼べないわけです。


ということでだいたいこんな感じだといいなぁーというのがこれ。

- 入力は ファミコンライクに十字キーとABボタン
- 液晶はもちろんカラーで！
- ゲーム開発言語はLuaとかmrubyとかMicroPythonとかのスクリプト言語。（C言語はイヤ）
- 作ったゲームの転送は無線で！（WiFiとかBluetoothとか）


現実的なところをとって最終的に以下の仕様にしました。

- 入力は、**アナログジョイスティック**＋**ABボタン**
  - アナログジョイスティックの方が豪華？　いえ、**安い**んです。
- 液晶は**カラー**
  - これはゆずれない。
- ゲーム開発言語は**Lua**（tolua++の便利さといったら）
  - Luaは組み込み経験があったので。
- ゲーム転送は**Web API**で。
  - curlで良い。curlが良い。
  - Bluetoothだとアプリとか作らないといけないから辛い・・・

# で、できたのがこちら
![P1000465_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63235/c8ec80b6-83c4-b9f2-fce9-de026422e78a.gif)

ゲームを選択して、遊べます。
超荒いので、細かく見たい方はYouTubeでどうぞ。
https://youtu.be/rkK88xarytI

# 部品紹介
と、だいたい仕様が決まったところで秋月電子で適当に部品を漁ります。
安さ最優先です。

- ESP32-DevKitC
  - http://akizukidenshi.com/catalog/g/gM-11819/
- カラー液晶 ST7735
  - https://amzn.to/2McLzbK
- アナログジョイスティック
  - http://akizukidenshi.com/catalog/g/gK-10263/
- タクトスイッチ
  - http://akizukidenshi.com/catalog/g/gP-02561/
- ブレッドボード(2つ必要です。)
  - http://akizukidenshi.com/catalog/g/gP-05294/
- ジャンパーワイヤー
  - http://akizukidenshi.com/catalog/g/gC-05159/

はい。しめて**4,349円**。ほぼESP32と液晶の値段です。
カラー液晶だけamazonです。。秋月で取り扱っているカラー液晶は配線が面倒なのです。残念。
そして液晶がちょっとお高い。

# 部品同士を繋ぐだけ！簡単実装
今回の工作は超簡単です。基本、ブレッドボード上で配線するだけ。
抵抗やらコンデンサやらそういったもののお世話にはなりません。
ESP32のピンに直付けです。

![overview.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63235/c3572988-16d1-956a-70d8-29150574fcb9.jpeg)

![circuit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63235/39b22932-6678-93b7-1d8d-e816b5515a1e.png)

# APIはpyxelライク！
以前、[pyxel](https://github.com/kitao/pyxel/blob/master/README.ja.md)でゲーム作ったことがあったので。

[ゲームAPI ドキュメントはこちら](https://github.com/pluswing/espconsole/#%E3%82%B2%E3%83%BC%E3%83%A0api)

●がジョイスティック入力で動くサンプルはこんな感じ。

```lua
local api = GetApi()

function update()
end

function draw()
    api:cls(COLOR_BLACK)
    api:rectb(api:analogX() + 80, api:analogY() + 64, 20, 20, COLOR_RED)
end
```


ブロック崩し（のブロックが無いバージョンw）はこんな。

```lua
local api = GetApi()

api:setFPS(30)

local ball = {
    x = 0,
    y = 0,
    mx = 1,
    my = 1,
    size = 10,
}

local bar = {
    x = 0,
    y = api:height() - 10,
    w = 20,
}

local gameover = false

function update()
    if gameover then
        return
    end

    ball.x = ball.x + ball.mx
    ball.y = ball.y + ball.my

    if ball.x < 0 then
        ball.mx = 1
    end

    if ball.x > api:width() - ball.size then
        ball.mx = -1
    end

    if ball.y < 0 then
        ball.my = 1
    end

    if ball.y + ball.size > bar.y then
        if bar.x > ball.x + ball.size then
            gameover = true
            return
        end
        if bar.x + bar.w < ball.x then
            gameover = true
            return
        end
        ball.my = -1
    end

    if api:btn(BTN_LEFT) then
        bar.x = bar.x - 3
        if bar.x < 0 then
            bar.x = 0
        end
    end
    if api:btn(BTN_RIGHT) then
        bar.x = bar.x + 3
        if bar.x > api:width() - bar.w then
            bar.x = api:width() - bar.w
        end
    end
end

function draw()
    api:cls(COLOR_BLACK)

    api:rect(ball.x, ball.y, ball.size, ball.size, COLOR_GREEN)
    api:line(bar.x, bar.y, bar.x+bar.w, bar.y, COLOR_WHITE)

    if gameover then
        api:text(40, api:height()/2, "GAME OVER!", COLOR_RED)
    end
end
```


# ゲームの転送はWeb API
はい。これでいけます。

```bash
curl -X POST http://espconsole.local/upload -F "file=@game.lua"
```

[Web API一覧はこちら](https://github.com/pluswing/espconsole/#web-api)


# 肝心のファームウェア
Arduinoで開発しています。vscodeにArduino拡張機能を入れると、超絶便利です。
Arduino IDEには戻れません。

https://github.com/pluswing/espconsole

インストール方法とかは、[README](https://github.com/pluswing/espconsole/#%E3%83%95%E3%82%A1%E3%83%BC%E3%83%A0%E3%82%A6%E3%82%A7%E3%82%A2%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF)に書いてあるので見てね。


# まだまだ機能が足りない！

実は、ファームウェアはまだまだ開発中で機能が全然足りてません。
大きなところだと、サウンド。
他、やらなきゃなーってことはissueに上げてるので、お手伝い募集中ですｗ
https://github.com/pluswing/espconsole/issues