【pyxel 1.5】pyxelでpython勉強帳(5)
さて、前回まではpythonのデータ型をいろいろとみていましたが、今回からは制御文やpyxel特有の機能について書いていこうと思います。
ということで、制御文といえば「IF」。ifというと「もしも」という意味ですが、プログラムでも「もしも○○したら××する」というように処理を分ける際に使います。
今回は、条件分岐で使われるif文を使って、簡単なゲームを作ってみました。
pyxelの命令を使ってキー入力を検知して、コマンドの完成を判定します。
コード全体は以下の通りです。
import pyxel
class APP:
def __init__(self):
pyxel.init(128, 128, title="pyxel")
self.frame = 0
self.f_limit = 10
self.cmd = 0
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btn(pyxel.KEY_R):
self.frame = 0
self.cmd = 0
if self.cmd == 0 and pyxel.btn(pyxel.KEY_RIGHT):
self.cmd += 1
if self.cmd == 1 and pyxel.btn(pyxel.KEY_DOWN):
self.cmd += 1
self.frame = 0
if self.cmd == 2 and pyxel.btn(pyxel.KEY_RIGHT):
self.cmd += 1
self.frame = 0
if self.cmd == 3 and pyxel.btn(pyxel.KEY_P):
self.cmd += 1
self.frame = 0
if self.cmd != 0:
if self.cmd == 4:
pass
else:
self.frame += 1
if self.frame > self.f_limit:
self.frame = 0
self.cmd = 0
def draw(self):
pyxel.cls(0)
pyxel.text(10, 10, str(self.frame), 7)
if self.cmd == 1:
pyxel.text(10, 20, "RIGHT!", 7)
if self.cmd == 2:
pyxel.text(10, 30, "DOWN!!", 7)
if self.cmd == 3:
pyxel.text(10, 40, "RIGHT!!!", 7)
if self.cmd == 4:
pyxel.text(10, 50, "SYO-RYU-KEN!!!!", pyxel.frame_count % 16)
APP()
順々に見ていきますが、今回は僕の趣味全開で作ってしまったので、格闘ゲームをやらない方には分かりにくい内容になってしまいました…。できるだけ丁寧に書こうと思いますが、申し訳ない。
def __init__(self):
pyxel.init(128, 128, title="pyxel")
self.frame = 0
self.f_limit = 10
self.cmd = 0
pyxel.run(self.update, self.draw)
▲まずはinit部分。3つの変数を用意します。
「self.frame」は経過フレーム数を格納。格ゲーのコマンドは一定時間内に連続でキー入力を行うので、前の入力からどれくらい経ったかを判別するのに使います。
「self.f_limit」は猶予フレームの設定用。制限時間みたいなものですね。この値内で次のキー入力を行います。
「self.cmd 」はコマンドがどこまで進んだかを示す値。今回は昇竜拳なので右・下・右・パンチというコマンドになります(パンチはPキーに割り当て)。これがどこまで進んでいるかを示します。
次に、実際にif文を使うupdate関数に進んでいきます。
def update(self):
if pyxel.btn(pyxel.KEY_R):
self.frame = 0
self.cmd = 0
if self.cmd == 0 and pyxel.btn(pyxel.KEY_RIGHT):
self.cmd += 1
if self.cmd == 1 and pyxel.btn(pyxel.KEY_DOWN):
self.cmd += 1
self.frame = 0
if self.cmd == 2 and pyxel.btn(pyxel.KEY_RIGHT):
self.cmd += 1
self.frame = 0
if self.cmd == 3 and pyxel.btn(pyxel.KEY_P):
self.cmd += 1
self.frame = 0
if self.cmd != 0:
if self.cmd == 4:
pass
else:
self.frame += 1
if self.frame > self.f_limit:
self.frame = 0
self.cmd = 0
▲update関数です。if文とpyxel.btnを使ってキー入力を判定しています。
if pyxel.btn(pyxel.KEY_R):
self.frame = 0
self.cmd = 0
▲基本の形はこんな感じ。「if」の後に条件を書いて「:」でふさぎます。
条件に合致した際には下の行の処理を行います。この時インデント(段落)をきちんと下げていないとエラーになってしまうので注意。
pyxel.btnは引数で与えられたキーが押されたかを判定するpyxelの命令文です。この部分はRキーを押すと各変数をリセットするコードですね。
if self.cmd == 0 and pyxel.btn(pyxel.KEY_RIGHT):
self.cmd += 1
if self.cmd == 1 and pyxel.btn(pyxel.KEY_DOWN):
self.cmd += 1
self.frame = 0
if self.cmd == 2 and pyxel.btn(pyxel.KEY_RIGHT):
self.cmd += 1
self.frame = 0
if self.cmd == 3 and pyxel.btn(pyxel.KEY_P):
self.cmd += 1
self.frame = 0
▲コマンド入力を検知する部分。self.cmdの値とキー入力で分岐します。各if文で正しいキー入力が行われた場合は「self.cmd += 1」でコマンドを進めて、「self.frame = 0」で猶予フレームをリセットします。
if self.cmd != 0:
if self.cmd == 4:
pass
else:
self.frame += 1
if self.frame > self.f_limit:
self.frame = 0
self.cmd = 0
▲ここのif文はちょっと複雑になっています。
まず「if self.cmd != 0:」の条件が来てますね。これはself.cmdが0でなかったらという意味です。==や!=のような比較に使う記号はいろいろあるので、ここではすべては取り上げません。
下のインデントに行くと、そこにもifがあります。if文はこのように何重にもすることができます(が、あまりにも階層が深くなるのは推奨されません)。
「if self.cmd == 4:」はself.cmdが4の状態を判定。これはコマンドが完成した状態で、昇竜拳が出ている場合です。この時は何もしたくないので「pass」を書いています。
「else」は「以外の場合」の意味です。これは上のifと対になります。今回でいうと「self.cmdが4でない場合」ということになります。コマンドが完成していない間は猶予フレームを消費したいので「self.frame += 1」で進めます。
ここまで来てまたifが出てきます。「if self.frame > self.f_limit:」で経過フレームが猶予フレームを超えてしまったらという条件になります。ここに合致するとself.frameとself.cmdが0になって最初からになってしまいます。
def draw(self):
pyxel.cls(0)
pyxel.text(10, 10, str(self.frame), 7)
if self.cmd == 1:
pyxel.text(10, 20, "RIGHT!", 7)
if self.cmd == 2:
pyxel.text(10, 30, "DOWN!!", 7)
if self.cmd == 3:
pyxel.text(10, 40, "RIGHT!!!", 7)
if self.cmd == 4:
pyxel.text(10, 50, "SYO-RYU-KEN!!!!", pyxel.frame_count % 16)
▲draw関数はself.cmdの値によって文字表示を変えているだけなので割愛します。
ちなみにself.f_limitをいじると猶予フレームを操作できます。「1」にすると猶予1フレの超難易度の出来上がり。
と思いきや、このゲームには攻略法があります。pyxel.btnはキー押しっぱなしでの入力も「入力あり」として検知するので、右キーを押し続けながら下とPをパチパチって感じで簡単に出ます。
これはpyxel.btnの仕様による攻略法ですが、これへの対処策もあります。pyxel.btnではなくpyxel.btnpを使うときちんとキーを「押下」しないと入力となりません。押しっぱなしを許容するかで使い分けると良い感じ。例えばシューティングゲームで押し続けて連射するかどうかとかですかね。
今回はここまで。
うまく使えば簡易版太鼓の達人みたいなゲームも作れそう。
次回はもう1つの制御文の巨頭、「for」を使ってみます。
読んでいただきありがとうございました。
ここまで読んでいただきありがとうございます!