いいね、生き生きしたね!
成果物
コード
#!/usr/bin/env python3 # coding: utf8 import pyxel, os class App: def __init__(self): self.window = Window() Resource() self.pc = PlayerCharacter() print('DEFAULT_FPS:', pyxel.DEFAULT_FPS) pyxel.run(self.update, self.draw) def update(self): self.pc.update() def draw(self): self.window.draw() self.pc.draw() class Resource: def __init__(self): pyxel.load(self.ResourcePath) def __this_dir(self): return os.path.dirname(__file__) def __parent_dir(self, path): return os.path.dirname(path) @property def RootDir(self): return self.__parent_dir(self.__this_dir()) @property def ResourcePath(self): return os.path.join(self.RootDir, 'res/python.pyxres') class Window: def __init__(self, width=128, height=96, border_width=0): pyxel.init(width, height, border_width=border_width) def draw(self): pyxel.cls(0) class PlayerCharacter: def __init__(self, x=0, y=0, width=8, height=8, img=0, u=0, v=0, colkey=0): self.w = width self.h = height self.x = (pyxel.width / 2) - (self.w / 2) self.y = (pyxel.height/ 2) - (self.h / 2) self.img = img self.u = u self.v = v self.colkey = colkey self.frame = 0 self.direction = 1 # 1=left, -1=right def update(self): if pyxel.btn(pyxel.KEY_LEFT) and self.x > 0: self.x -= 1 if pyxel.btn(pyxel.KEY_RIGHT) and self.x < pyxel.width - self.w: self.x += 1 if pyxel.btn(pyxel.KEY_UP) and self.y > 0: self.y -= 1 if pyxel.btn(pyxel.KEY_DOWN) and self.y < pyxel.height - self.h: self.y += 1 self.__frame() def draw(self): pyxel.blt(self.x, self.y, self.img, self.u + (self.frame * 8), self.v, self.w, self.h, self.colkey) def __frame(self): if 0 == pyxel.frame_count % (pyxel.DEFAULT_FPS / 2): self.frame += 1 if self.frame > 1: self.frame = 0 App()
要点
フレーム画像の切替
pyxel.blt(self.x, self.y, self.img, self.u + (self.frame * 8), self.v, self.w, self.h, self.colkey)
(self.frame * 8)
の部分が大事。ここでImage
バンク0
番の(u
, v
)座標にある領域を取得する。X座標を8ピクセル分だけ加算したときは2フレーム目の画像位置を指し示すことになる。
フレーム数は以下で制御する。0
〜1
。
def __frame(self): self.frame += 1 if self.frame > 1: self.frame = 0
つまり(u, v)
は(0, 8)
, (8, 8)
のいずれかの座標位置を指すことになる。
アニメ速度の制御
if 0 != pyxel.frame_count % (pyxel.DEFAULT_FPS / 2): return
この行でアニメーションする速度を遅くしている。さもなくば以下のように爆速になってしまう。
FPS
とは?
FPS
とは、Frame Per Second の略。1秒あたり何回描画するかを示す値。数値が大きいほどなめらかに動く。フレームとは1回あたりの描画画面のこと。
FPS
のデフォルト=30
FPS
のデフォルト値は30
。今回は変更していないため、デフォルト値の30
である。
FPS
の現在値を取得する変数が不明
pyxel.init()
でFPS
の値を任意に設定できるのだが、その値をどうやって取得するのかわからなかった。
pyxel.DEFAULT_FPS
ならあった。なのでデフォルト値のまま使う。FPS
はアニメ速度の調整で必要。
pyxel.frame_count
とは?
pyxel.frame_count
は起動時からのフレーム数。延々とカウントアップしていく。
計算
以下の式は、FPS=30のとき、30回に1回を意味する。つまり1秒に1回である。
if 0 == pyxel.frame_count % pyxel.DEFAULT_FPS:
演算子%
は剰余。割った余りを返す。30
で割ったなら0
〜29
を返す。30種類ある。このうち0
、つまり1種類の値のみヒットさせると1/30、30回中1回のみヒットとなる。
上記のコードは、1秒に1回、画像を切替している。でもこれでは遅すぎる。そこで0.5秒に1回、切替することにした。以下のように。
if 0 == pyxel.frame_count % (pyxel.DEFAULT_FPS / 2):
30/2
=15
。15
の剰余は0
〜14
の15種類。このうち0
という1種のみヒットさせる。
15フレームごとに1回ヒットする。実際は1秒間に30回描画するので、15回に1回ヒットなら、30回のときは2回ヒットする。1秒間に1回ヒットだから、1秒間に2回ヒットするなら0.5秒ごとにヒットすることになる。
0.5秒ごとに取得する画像の座標をずらしている。これでパラパラ漫画みたいに画像を切替している。
所感
反対側を向かせたい。左なら反転すればいいだけだし、簡単なのでは? 次回やってみる。
前回まで
- ラズパイ4Bにpyenvをインストールする(python 3.8.2)
- pyxelをインストールする(pyenv python3.8.2)
- pyxeleditorにおけるImageエディタの使い方
- pyxeleditorにおけるTileMapエディタの使い方
- pyxeleditorにおけるSoundエディタの使い方
- pyxeleditorにおけるMusicエディタの使い方
- pyxelのリソースにおける概念・制限まとめ
- pyxeleditorにおけるpyxresファイル形式まとめ
- pyxelのAPI調査
- pyxelで最小コード 窓を出す
- Pyxelで窓の境界線を消す
- 携帯ゲーム機の解像度
- pyxelで矩形を描画する
- pyxelで荒ぶる矩形
- pyxelでキーに応じて動く矩形
- pyxelで画像を描画する
対象環境
- Raspbierry pi 4 Model B
- Raspbian buster 10.0 2019-09-26 ※
- bash 5.0.3(1)-release
- pyxel 1.3.1
$ uname -a Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux