男の子・お化け・お菓子を用意し、画面に出して確かめる
リソースエディタで 8×8 ドットの絵を 3 つ描いて保存し、 それを画面に並べて表示するところまでを確認します。 このフェーズで書くコードは 20 行ほどで、動きはまだありません。
step1/ フォルダを作り、その中に次の 2 つを置きます。
フォルダとファイルはご自身で作ってください。
step1/
├── candy_hunt.py これから書くコード
└── candy_hunt.pyxres リソースエディタで作る絵
名前は好きなもので構いませんが、以降のページはこの名前で説明します。
step0 では「星を pset で描く」ところから始めて、あとから宇宙船の絵を足しました。
今回は最初に絵を作ります。動かす対象が 3 種類あり、
それぞれ「どんな見た目か」が決まっていないと、位置や大きさの数字を決められないからです。
絵のサイズは 8×8 ドットにします。画面が 160×120 なので、 横に 20 個・縦に 15 個ぶん並ぶ計算です。追いかけっこをするのにちょうどよい大きさで、 step0 の宇宙船(16×16)の 4 分の 1 の面積になります。
ここがこのフェーズの本題です。イメージバンクは 256×256 ドットの 1 枚の大きな紙で、 3 つの絵はその紙の上に並べて描きます。コードから絵を呼び出すときは、 名前ではなく「紙のどこから、何ドットぶん切り出すか」という座標で指定します。
つまり配置がそのままコードの中の数字になります。 あとから絵の位置を動かすと、コードの数字も全部直すことになります。 先に決めておきましょう。
| 絵 | 切り出し位置 | 大きさ |
|---|---|---|
| 男の子 | u = 0, v = 0 | 8 × 8 |
| お化け | u = 8, v = 0 | 8 × 8 |
| お菓子 | u = 16, v = 0 | 8 × 8 |
u = 5、u = 13 のような数字を
コードに書くことになり、あとで読み返したときに何のことか分からなくなります。
エディタの方眼も 8 ドット単位なので、目でも合わせやすくなります。
v = 8)に足せるようにしておきます。
step0 の魚が 2 枚の絵を切り替えて泳いでいたのと同じ仕組みです。
絵の背景(何も描かない部分)は黒=色番号 0 のままにしておきます。 画面に出すとき「この色は透明として扱う」と指定することで、 四角い枠が見えず、キャラクターの形だけが表示されます。step0 の宇宙船と同じやり方です。
| 機能 | 役割 |
|---|---|
pyxel edit ファイル名.pyxres | リソースエディタを開く。ファイルが無ければ新規作成される |
pyxel.load("ファイル名.pyxres") | 作った絵をプログラムから読み込む |
pyxel.blt(x, y, img, u, v, w, h, colkey) | イメージバンクから切り出して画面に貼る |
step1 フォルダを作ったら、その中で次を実行します。
ファイルがまだ無いので、新しく作られます。
cd step1
pyxel edit candy_hunt.pyxres
イメージバンク 0 のタブを開き、上の配置図のとおり左上から横一列に描いていきます。
1 つ描くごとに Ctrl + S で保存しておくと安心です。
Ctrl + S で保存し、Esc でエディタを閉じます。
step1 フォルダに candy_hunt.pyxres ができていれば完了です。
描いた絵がちゃんと出るかを確かめます。step1/candy_hunt.py に次を入力してください。
# candy_hunt.py
# step1 フェーズ1:描いた 3 つの絵を並べて表示する
import pyxel
SCREEN_WIDTH = 160
SCREEN_HEIGHT = 120
class App:
def __init__(self):
"""起動時の設定"""
pyxel.init(SCREEN_WIDTH, SCREEN_HEIGHT, title="Candy Hunt")
pyxel.load("candy_hunt.pyxres")
pyxel.run(self.update, self.draw)
def update(self):
"""フレーム毎の更新処理(まだ何もしない)"""
pass
def draw(self):
"""描画処理"""
pyxel.cls(pyxel.COLOR_BLACK)
pyxel.blt(40, 56, 0, 0, 0, 8, 8, pyxel.COLOR_BLACK) # 男の子
pyxel.blt(76, 56, 0, 8, 0, 8, 8, pyxel.COLOR_BLACK) # お化け
pyxel.blt(112, 56, 0, 16, 0, 8, 8, pyxel.COLOR_BLACK) # お菓子
App()
cd step1
python candy_hunt.py
黒い画面の真ん中あたりに、描いた 3 つの絵が横に並んで表示されれば成功です。 まだ何も動きません。
pass は「ここは何もしない」の印
Python では、def の中身を空っぽにするとエラーになります。
かといって今の update() には書くことがありません。
そこで 「何もしないことを、はっきり書いておく」ための命令が pass です。
次のフェーズで男の子を動かす処理を書くので、この pass はすぐに消えます。
「あとで中身が入る場所」の目印だと思ってください。
blt() の 8 個の数字step0 でも使いましたが、引数が多いので改めて整理します。
pyxel.blt(40, 56, 0, 0, 0, 8, 8, pyxel.COLOR_BLACK)
~~~~~~ ~ ~~~~ ~~~~ ~~~~~~~~~~~~~~~~~
(1) (2) (3) (4) (5)
| 値 | 意味 | |
|---|---|---|
| (1) | 40, 56 | 画面のどこに貼るか(左上の座標) |
| (2) | 0 | どのイメージバンクを使うか |
| (3) | 0, 0 | 絵のほうのどこから切り出すか(u, v) |
| (4) | 8, 8 | 切り出す幅と高さ |
| (5) | pyxel.COLOR_BLACK | 透明として扱う色 |
3 行の違いは (1) の貼る位置と (3) の切り出し位置だけです。
切り出し位置が 0 → 8 → 16 と変わっているのが、
さきほど決めた配置に対応しています。
40、56、8 といった数字がコードに散らばっていますが、
次のフェーズからは SPRITE_SIZE = 8 のように名前を付けた定数に置き換えていきます。
今は「どの数字が何を指しているか」を目で確かめるために、あえてそのまま書いています。
| 症状 | 原因と対処 |
|---|---|
| 黒い画面のまま、何も出ない | 絵を描いた場所がずれている可能性があります。エディタを開き直して、 左上の角ぴったりから描けているか確かめてください。 また、イメージバンクの 0 番のタブに描けているかも確認します |
FileNotFoundError と出る |
.pyxres が見つかっていません。pyxel.load() の相対パスは
実行するスクリプトの置き場所を基準に解決されるので、
candy_hunt.py と candy_hunt.pyxres が
同じフォルダにあるか確認してください |
| 絵のまわりに黒い四角が見える | 透過色の指定が抜けています。blt() の最後の
pyxel.COLOR_BLACK があるか確認してください |
| 絵が途中で切れている | 切り出す幅と高さが合っていません。8, 8 になっているか確認します |
| となりの絵が混ざって表示される | 8 ドットの区切りをまたいで描いてしまっています。 はみ出した部分をエディタで消してください |
絵が用意できました。次は男の子を矢印キーで動かします。
このフェーズで書いた candy_hunt.py がそのまま土台になり、
update() の pass が中身に置き換わります。