【Python】Pyxelでゲームを作るための最初の一歩

#はじめに
PyxelはPython向けのレトロゲームエンジンです。
手軽にゲームを作ることができるので、かつては色々と遊んでいたのですが、最近あまり触れていなかったため、すっかり記憶を失ってしまいました。
久しぶりに遊んでみて記憶の回復を図っていこうと思います。

なお、詳しく正しい知識、それからインストール方法等は以下のリンクをご覧ください。
https://github.com/kitao/pyxel/blob/master/README.ja.md
#1 最小限のコード
まず必要最小限のコードは大体以下のとおりになります。

```python
# まずはpyxelをインポート
import pyxel

# ゲーム全体を表すクラスを作り、その中でゲームの内容を定義する
class App:
    def __init__(self):
        # 画面サイズ(幅w, 高さh)を指定する
        pyxel.init(100, 100)

        # とりあえず変数を作っておく
        # 今は特に意味はない
        self.x = 0

        # フレーム更新時に実行する更新関数と描画関数を登録する
        # 2つの関数が時間ごとに連続で実行されるイメージ
        pyxel.run(self.update, self.draw)

    def update(self):
        # 1フレームごとにxが1増えていく
        # 今は特に意味はない
        self.x += 1

    def draw(self):
        # 画面をクリアする色を指定する(0〜15)
        # 1フレームごとに画面が色0(=黒)でクリアされる
        # 今は特に意味はない
        pyxel.cls(0)

# クラスのインスタンスを生成、ゲームを開始
App()
```
コードの説明は全てコメントで記載したとおりです。
実行結果はこのとおり、今は真っ黒な画面を表示するだけです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912003/f541051b-cc8f-e19a-46ff-33e14f783417.png" width=50%>
#2 絵を表示させる
さて、画面は出てきましたが、ここから絵が表示されて、動いて、操作できないとゲームになりません。
まずは絵を表示させるところから始めます。
絵の表示は描画関数`draw`の中に記述します。
シンプルな四角形を作ってみます。

```python
    def draw(self):
        pyxel.cls(0)

        # 四角形を描画、引数は(左上の点の座標x, y, 幅w, 高さh, 色)
        pyxel.rect(10, 10, 10, 10, 9)
```
(前に書いたコメントは省略)
四角形の左上の点の座標と、幅、高さ、色を指定して四角形を描画します。
座標は、画面の左上が(0, 0)で、右にいくとxが増え、下にいくとyが増えるという仕組みです。
この例だと、画面サイズが100×100なので、
左上が(0,0) 右上が(100,0)
左下が(0,100) 右下が(100,100)
ということになります。
実行結果。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912003/8c6359a2-59d0-6b87-421b-705adb80b4b3.png" width=50%>
右に10、下に10行ったところに、幅10、高さ10、色9(=オレンジ)の四角形を描画できました。
#3 絵を動かす
続いて、この四角形を動かしてみます。
フレームごとに変数を変化させ、その変数を描画関数の中のパラメータに当てはめる、というのが基本です。
今まで使ってませんでしたが、更新関数`update`の中に、フレームごとに1ずつ増えていく変数xがあります。これを四角形のパラメータに使ってみます。

```python
    def draw(self):
        pyxel.cls(0)

        # 四角形を描画、引数は(左上の点の座標x, y, 幅w, 高さh, 色)
        # 変数xを幅に設定
        pyxel.rect(10, 10, self.x, 10, 9)
```
おそらく、四角形の幅が少しずつ増えていくのでしょう。
実行結果。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912003/856331e8-1ad0-bdff-d44a-825526d0ebd1.png" width=50%>
四角形の幅を1ずつ伸ばすことができました。
#4 操作する
絵を動かすだけではただのアニメーションです。プレイヤーの操作が画面に反映するようにしましょう。
まずはキーボードの操作から。`btn`関数は、指定したキーが押し続けられているかどうか判定します。キーの種類は`KEY_○○`みたいな定数で指定します。
更新関数`update`の中では変数xが1ずつ増えていました。これを、キーの操作によって変化するようにしましょう。

```python
    def update(self):
        # 右キーを押している間はxが増える
        if(pyxel.btn(pyxel.KEY_RIGHT)):
            self.x += 1
        # 押していなければ1になる
        else:
            self.x = 1
```
これで、キーボードの右が押されていなければ四角形の幅が1になり、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912003/b4698030-af90-91ab-f568-6588d4f15a5c.png" width=50%>
右が押されている間は幅が1ずつ伸びていくようになりました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912003/4b4edc7b-b578-4288-4c5d-9566a6c3cd86.png" width=50%>
続いて、マウスの操作を反映させます。

```python
    def draw(self):
        pyxel.cls(0)

        pyxel.rect(10, 10, self.x, 10, 9)

        # マウスカーソルの座標を取得
        mx = pyxel.mouse_x
        my = pyxel.mouse_y

        # 新しく四角形を作成
        # 左上の座標をマウスカーソルの座標と一致させる
        pyxel.rect(mx, my, 5, 5, 6)
```
`mouse_x`、`mouse_y`でマウスカーソルの座標を取得します。
そして、その座標を、新しく作った四角形の左上の点の座標に当てはめます。
これで、マウスカーソルと同じ場所に四角形を描画できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912003/cc654de1-beac-1cc5-4016-0ed6b9e31665.png" width=50%>
マウスを動かすとついてくる水色の四角形ができました。
キーボードで操作するならインベーダーゲームやパックマン、マウスで操作するならブロック崩しみたいなのが作れそうですね。
#5 おわりに
コード全体。かんたんですね。

```python
import pyxel

class App:
    def __init__(self):
        pyxel.init(100, 100)

        self.x = 0
        
        pyxel.run(self.update, self.draw)

    def update(self):
        if(pyxel.btn(pyxel.KEY_RIGHT)):
            self.x += 1
        else:
            self.x = 1

    def draw(self):
        pyxel.cls(0)

        pyxel.rect(10, 10, self.x, 10, 9)

        mx = pyxel.mouse_x
        my = pyxel.mouse_y

        pyxel.rect(mx, my, 5, 5, 6)

App()
```
ひとまず記憶喪失になった自分のリハビリのため、基礎中の基礎を書き留めてみました。
今回は書いていませんが、Pyxelにはドット絵をかけるエディターが付属しているのが大きな特徴です。これを使いこなし、今回書いた簡単なコードに肉付けしていくと、それなりのゲームができていくんですね。
ゲームを作るのは楽しいだけでなく、当たり判定や重力、状態変数といった、プログラミングをする上で重要な概念が学べるのでとても有意義です。今後も少しずつ勉強してゲームらしいものを作れるようになりたいです。

(2020/12/19追記)コードについて指摘がありました。コメントをご覧ください。