Unityでジャンクゲームを作っているっぽい

会社帰りにGPD PocketにUnity入れてゲーム作ってます

Pyxelで作る04 アイテムを複数だす

参考サイト

今回も↓のサイトにお世話になっています
dev.classmethod.jp
あまりPythonに詳しくないので、調べて勉強する部分が多数ありました

とりあえずのコード

from random import randint
import pyxel

class App:
    def __init__(self):
        # 画面サイズの設定 captionはwindow枠にtext出せる
        pyxel.init(160, 120, caption="Hello Pysel")
        # editorデータ読み込み(コードと同じフォルダにある)
        pyxel.load("my_resource.pyxres")
        # 初期配置
        self.player_x = 80
        self.player_y = 60
        # fruit初期配置 x座標 y座標 表示flag on を4個用意
        self.fruit = [(i * 60, randint(0, 104), True) for i in range(4)]

        # 実行開始 更新関数 描画関数
        pyxel.run(self.update, self.draw)

    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()
        self.update_player()

        # i番目とv要素(各fruitの要素) enumerate関数で各fruitの値を取得して実行しているっぽ
        for i, v in enumerate(self.fruit):
            # (*v)ってタプルという複数の要素を管理するデータ型の一つらしい
            # つまり、初期化で設定したデータをタプル型にしてupdate_fruit関数に渡しているっぽい
            self.fruit[i] = self.update_fruit(*v)

    def update_player(self):
        # key入力
        # max関数 min関数で画面外に行かないようにしているのか
        if pyxel.btn(pyxel.KEY_LEFT):
            self.player_x = max(self.player_x - 2, 0)
        if pyxel.btn(pyxel.KEY_RIGHT):
            self.player_x = min(self.player_x + 2, pyxel.width - 16)
        if pyxel.btn(pyxel.KEY_UP):
            self.player_y = max(self.player_y - 2, 0)
        if pyxel.btn(pyxel.KEY_DOWN):
            self.player_y = min(self.player_y + 2, pyxel.height - 16)

    def update_fruit(self, x, y, is_active):
        # 左に移動
        x -= 2

        # 画面外に出たら
        if x < -40:
            # 画面反対側に強制移動
            x += 240
            # y座標はランダム
            y = randint(0, 104)
            # 表示flag on
            is_active = True

        # 返り値を設定
        return (x, y, is_active)

    def draw(self):
        # 画面クリア 0は黒
        pyxel.cls(0)
        # editorデータ描画
        pyxel.blt(self.player_x, self.player_y, 0, 0, 0, 16, 16, 0)

        # draw fruits
        for x, y, is_active in self.fruit:
            if is_active:
                pyxel.blt(x, y, 0, 16, 0, 16, 16, 0)
App()

これでこんな感じになります
f:id:mekatamatama:20201004182652g:plain
さて、イロイロと謎があったので、細かく見ていきます

アイテムの初期配置の事

# fruit初期配置 x座標 y座標 表示flag on を4個用意
self.fruit = [(i * 60, randint(0, 104), True) for i in range(4)]

i * 60

これはx座標のアイテムの配置間隔みたい
順次アイテムを生成していくのではなく、初期化時に画面外に4つ並べてしまっているのか
間隔を変化させたい場合は、ちょっと処理を追加しなきゃならなさそう、今後の課題にしよう
ちなみに、この部分を60とかにすると↓の様にアイテムが出てくるので、なるほど~ってなります
f:id:mekatamatama:20201004182655g:plain

randint(0, 104)

これはy座標をランダムにしているだけなので、特に問題は無し

True

これは、表示flagみたい
今回のコードですと、表示flagがFalseになることはないのですが
アイテムの取得処理が入ると必要になってくるみたいです

これらの値は

def update_fruit(self, x, y, is_active):

で使用します

enumerate()関数の事

update内の

for i, v in enumerate(self.fruit):

にenumerate()関数があります
調べてみると…
note.nkmk.me
インデックス番号, 要素の順に取得できる
これをupdateで、for文で回すことで、初期化した各アイテムの情報をdef update_fruit(self, x, y, is_active):へ送って動かしているようだ

関数にある(*v)の事

self.fruit[i] = self.update_fruit(*v)

ここの(*v)が、よくわからなかったので調べてみると
タプル型ってのにしているっぽい

参考にしたサイト

blog.codecamp.jp
dev.classmethod.jp

ここでは、初期化時に4つのアイテムを用意していますが、データ的には固定したい物なのでタプル型を使っているっぽい
トゲとか出現個数を変化させたい時には…どうすんだろ…
今は基本をつかむことが大事なので後で悩もう

これ以外は、コメントでなんとかなったのでそのまま
さて、次はアイテムの取得かな