Panda3Dでのキーボードとマウス入力

# Panda3Dでのキーボード・マウス入力について
Panda3Dの始め方は[前回](https://qiita.com/ywand/items/2c0eed33c55b381c98e7 "Panda3Dでの３Dゲーム開発の始め方")の記事を参照。
3Dモデルを表示まで出来たので、今回はキーボード入力とマウス入力によって移動・拡大・回転などを行ってみます。

# 入力待ち受け方法（イベントハンドラ）
```python
self.accept(<event name>, <function>)
```
キーが押された時・離された時にイベントが送信され、そのイベントが```<event name>```に該当する場合に、```<function>```で指定した処理が行われます。
```<event name>```の例は以下の通り。
* 英数字や記号を押した時：  "a", "z", "1" , "0" , "[",
* 英数字や記号を離した時："a-up", "2-up", "[-up"
* 文字を入力しないキーの場合：
"escape", "f"+"1-12" (e.g. "f1","f2",..."f12"), "print_screen",
"scroll_lock", "backspace", "insert", "home", "page_up", "num_lock",
"tab",  "delete", "end", "page_down", "caps_lock", "enter", "arrow_left",
"arrow_up", "arrow_down", "arrow_right", "shift", "lshift", "rshift",
"control", "alt", "lcontrol", "lalt", "space", "ralt", "rcontrol"
* マウスの場合："mouse1". "mouse2", "mouse1-up", "wheel_up", "wheel_down"

マウスによるカメラ操作を実装する際に、```self.disableMouse()```でデフォルトのカメラ操作機能を無効化しないと、カメラの移動が上手く出来ませんでした。

# サンプルコード
前回のsample.pyを元に改修していきます。
```python:sample2.py
# Panda3Dライブラリのインポート
from direct.showbase.ShowBase import ShowBase
from panda3d.core import *

class App(ShowBase):
    # 3D描画ウィンドウの内容
    def __init__(self):
        # 3D描画ウィンドウの初期化
        ShowBase.__init__(self)

        # デフォルトで準備されてるキューブモデルを読み込み
        self.cube = self.loader.loadModel('models/misc/rgbCube')
        # キューブのサイズ設定
        self.cube.setScale(1, 1, 1)
        # キューブの回転
        self.cube.setQuat(Quat(0, 1, 1, 1))
        # キューブの位置調整
        # (y軸に+値を設定しないと、カメラ位置がモデルの中心かモデルより前になってしまって何も表示されないので注意)
        self.cube.setPos(0, 20, 0)
        # キューブの描画
        self.cube.reparentTo(self.render)

        # キーボードイベント待ち受け
        self.accept("escape", self.key_esc)
        self.accept("arrow_up", self.key_up)
        self.accept("arrow_down", self.key_down)
        self.accept("arrow_right", self.key_right)
        self.accept("arrow_left", self.key_left)
        self.accept("space", self.key_space)

        # デフォルトで設定されているマウス機能を無効化
        self.disableMouse()
        # マウスイベント待ち受け
        self.accept("mouse1", self.mouse1)
        self.accept("mouse2", self.mouse2)
        self.accept("mouse3", self.mouse3)
        self.accept("wheel_up", self.mouse_wheel_up)
        self.accept("wheel_down", self.mouse_wheel_down)

    # キー入力毎の処理内容
    # ESCキーで終了
    def key_esc(self):
        exit()

    # スペースキーでキューブの回転
    def key_space(self):
        self.cube.setR(self.cube.getR() + 10)

    # 十字キーでキューブの移動
    def key_up(self):
        self.cube.setZ(self.cube.getZ() + 1)

    def key_down(self):
        self.cube.setZ(self.cube.getZ() - 1)

    def key_right(self):
        self.cube.setX(self.cube.getX() + 1)

    def key_left(self):
        self.cube.setX(self.cube.getX() - 1)

    # マウス入力毎の処理内容
    def mouse1(self):
        # マウスのボタンに対応してキューブを拡大
        self.cube.setScale(
            self.cube.getScale()[0] + 1,
            self.cube.getScale()[1],
            self.cube.getScale()[2]
        )

    def mouse2(self):
        self.cube.setScale(
            self.cube.getScale()[0],
            self.cube.getScale()[1] + 1,
            self.cube.getScale()[2]
        )

    def mouse3(self):
        self.cube.setScale(
            self.cube.getScale()[0],
            self.cube.getScale()[1],
            self.cube.getScale()[2] + 1
        )

    # マウスホイールの上下によるカメラ操作
    def mouse_wheel_up(self):
        self.camera.setPos(
            self.camera.getPos()[0],
            self.camera.getPos()[1]+2,
            self.camera.getPos()[2]
        )

    def mouse_wheel_down(self):
        self.camera.setPos(
            self.camera.getPos()[0],
            self.camera.getPos()[1]-2,
            self.camera.getPos()[2]
        )

# Appクラスのインスタンス化と実行
app = App()
app.run()
```

# 実行結果
VSCodeとPythonの拡張機能を入れていると、F5キーを叩けば実行してくれるので楽です。
![02_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703546/d637d5d5-aa67-599a-e9a6-47c3a7d3eee3.gif)
3Dモデルやカメラをキーボードやマウスで操作出来るようになりました。

# 参考
[Keyboard Support — Panda3D Manual](https://docs.panda3d.org/1.10/python/programming/hardware-support/keyboard-support)
[Mouse Support — Panda3D Manual](https://docs.panda3d.org/1.10/python/programming/hardware-support/mouse-support)
[3次元のゲームエンジン Panda3D を使ってみる](https://www.kkaneko.jp/db/python3d/trypanda3d.html#S8)