出力: LEDマトリクスのドット絵

### 背景
8x8のLEDマトリクスは切り替え表示できるようです。
spheroV2にも準備されているようなので、ドット絵の作成と切り替え動作を試しました。

### Scratch
マトリクスアニメーションはマトリクスにありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/fdf85de1-4dd8-1b83-0383-9129a0751957.png)

＋のボタンをクリックすると自作のデータを新規作成しました。
左から2番目のspheroが跳ねているボタンを押すと、フレームを追加できました。
上のxボタンを押すと前の画面に戻り、レボタンを押すとマトリクスアニメーションの窓が閉じました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/1ded3c38-4e6b-6ae3-1afa-470bb1853ebe.png)

ここで＋のボタンをクリックするとフレームを新規作成しました。
編集したいフレームを選んで鉛筆アイコンを押すとドット絵を編集しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/a1c87a2c-61da-a67b-4d9f-fa712e9f0bbc.png)

色を選んで、変更するドットをクリックして編集しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/c2009791-63e6-d6cb-7f82-d74bca968d42.png)

「アニメーションをループ再生する。」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/532991f3-10cc-7624-02db-a599b12b3898.png)

### spheroV2
sphero_edu.pyのメソッドを調べると、アニメーションはregister_matrix_animationでフレームデータを登録して、play_matrix_animationでアニメーションを再生するようです。

また、フレームデータは使用する色をカラーパレットのリストに登録してから、ドットの色をカラーパレットのインデックスで指定するようです。

ここでは、8x8のpngファイルで作成しておいたファイルを指定したフォルダ内から読み込み、再生するようにしました。

chatGPT先生と相談しながら作成しましたが、依頼した手順よりも良い方法を回答された（カラーパレットを作りながらフレームデータを作成）ので、その手法を採用して一部修正して作成しました。

```
import os
import time

import glob
from PIL import Image
from spherov2.sphero_edu import SpheroEduAPI
from spherov2.types import Color
from spherov2 import scanner

def extract_palette_and_frames(folder_path):
    """
    指定フォルダから8x8のPNGファイルを読み込み、カラーパレットとフレームデータを作成する。
    """
    frames = []
    palette = []
    color_map = {}

    # フォルダ内のすべてのPNGファイルをフレーム番号順にソート
    png_files = sorted(glob.glob(os.path.join(folder_path, "*.png")))
    print(f"Found {len(png_files)} PNG files in {folder_path}.")

    for file in png_files:
        # 画像を読み込む
        img = Image.open(file).convert("RGB")  # RGB形式で読み込む
        if img.size != (8, 8):
            raise ValueError(f"Image {file} is not 8x8 pixels.")

        # フレームデータを格納
        frame = []
        for y in range(8):
            row = []
            for x in range(8):
                color = img.getpixel((x, y))
                if color not in color_map:
                    color_map[color] = len(palette)  # カラーパレットに追加
                    palette.append(Color(r=color[0], g=color[1], b=color[2]))
                row.append(color_map[color])  # パレットのインデックスを格納
            frame.append(row)
        frames.append(frame)

    return palette, frames

def main():
    folder_path = "./frames"  # PNGファイルが格納されているフォルダ
    print("Extracting palette and frames...")
    palette, frames = extract_palette_and_frames(folder_path)

    print(f"Palette: {len(palette)} colors")
    print(f"Frames: {len(frames)} frames")

    # Sphero Boltに接続してアニメーションを登録
    print("Connecting to Sphero Bolt...")
    toy = scanner.find_BOLT()
    if toy is None:
        print("Failed to connect to Sphero Bolt.")
        return

    with SpheroEduAPI(toy) as droid:
        print("Connected to Bolt.")
        droid.reset_aim()
        droid.set_stabilization(True)
        droid.set_front_led(Color(r=20, g=20, b=20))  # LED を白に設定

        # アニメーションを登録
        droid.register_matrix_animation(
            frames=frames,
            palette=palette,
            fps=10,  # フレームレート
            transition=False  # トランジションなし
        )
        print("Animation registered. Playing now!")

        # アニメーションを再生
        droid.play_matrix_animation(0)
        time.sleep(10)
        droid.clear_matrix()

if __name__ == "__main__":
    main()

```

framesという名前のフォルダにフレーム画像を連番で作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/9fa93da8-3e7c-2d16-7968-f4ec476c8d71.png)

実行結果はこちらです。
```
git\spherov2.py\spherov2\test>python BoltTest_matrixAnimation2.py
Extracting palette and frames...
Found 4 PNG files in ./frames.
Palette: 2 colors
Frames: 4 frames
Connecting to Sphero Bolt...
Connected to Bolt.
Animation registered. Playing now!
```


### まとめ
spheroV2を用いて、sphero boltのマトリクスにアニメーションを表示しました。
8x8のドット絵のデータを引用すると、演出が捗りそうです。