PICO-8 とは
PICO-8 は「ファンタシー・コンソール」で、楽しく遊べる小さな仮想マシン環境です。まずは PICO-8 公式ページ を開き、トップページにあるデモで遊んでみると、だいたい感覚がつかめるかとおもいます。
有料($14.99)ですが、作成されたゲームやソフトウェアを実行するのは無料です。とてもシンプルな環境で、開発環境も実行環境も統合されているため、プログラミング入門には最適かとおもいます。
以下は関連リソースです。良質な入門記事が多い印象。
- PICO-8 - Wikipedia (英語)
- PICO-8 日本語版マニュアル
- PICO-8初心者ガイド
- PICO-8で遊ぼう!【PICO-8入門】
- PICO–8って何? – PICO–8ゲーム開発入門(1)
ちなみに似た方向性をもつ環境は幾つかあります。以前にご紹介した記事は以下なのですが、だいたいの雰囲気はつかんでいただけるかとおもいます。
デモを試してみる
ネット上に数多くのPICO-8ソフト(カートリッジ)があるため忘れられがちですが、PICO-8 自体に幾つかのデモ(サンプルカートリッジ)が用意されています。
マニュアルから抜粋しますが、PICO-8 を起動し、コンソールから以下のコマンドを入力すると利用できます。
INSTALL_DEMOS
CD DEMOS
DIR
すると一覧が表示されます。バージョンによって異なるかもしれませんが、以下のようなデモがあるはず。
プログラム名 | 説明 |
---|---|
HELLO | PICO-8からの挨拶 |
API | PICO-8の主要機能のデモ |
JELPI | 2プレイヤー対応のプラットフォーム型ゲームデモ |
CAST | 2.5Dレイキャスト描画デモ |
MANDEL | マンデルブロー描画 |
COLLIDE | 壁とキャラクターの衝突判定サンプル |
BUTTERFLY | シェルピンスキーのフラクタル三角形描画 |
DRIPPY | 液体のように滴る曲線の描画 |
STOMPY | 音楽カートリッジ |
最初の HELLO
デモを実行してみましょう。
実行すると以下のような表示になります。ESC キーで終了し、コンソールに戻ります。
衝突判定サンプルの COLLIDE
なども楽しいですね。
HELLO サンプル
いちばん簡単そうな HELLO
サンプルの中身を見て、理解していきましょう。今回利用するのは PICO-8 v0.2.5g です。
元のコード
まずは HELLO サンプルの Lua ソースコードを見てみましょう。
-- hello world
-- by zep
music(0)
function _draw()
cls()
-- for each color
-- (from pink -> white)
for col = 14,7,-1 do
-- for each letter
for i=1,11 do
-- t() is the same as time()
t1 = t()*30 + i*4 - col*2
-- position
x = 8+i*8 +cos(t1/90)*3
y = 38+(col-7)+cos(t1/50)*5
pal(7,col)
spr(16+i, x, y)
end
end
print("this is pico-8",
37, 70, 14)
print("nice to meet you",
34, 80, 12)
spr(1, 64-4, 90) -- ♥
end
そしてスプライト定義はこちらです。
短縮版のコード
上記コードからコメントと改行を削除してみました。結果、ギリで1画面に収まっています。
基本的な表示を理解してみる
HELLO WORLD
文字列のアニメーションが面白いわけですが、まずはこの動きを止めて、基本的な表示部分を確認しましょう。以下の赤枠の部分をコメントアウトします。
RUN
で実行すると、以下のようにアニメーションが止まった画面が表示されます。
HELLO WORLD
以外の部分から見ていきましょう。左が短縮したコートで、右がその実行画面です。
① の _DRAW()
関数は PICO-8 での標準のお作法で、画面更新に関する表示ロジックはこの関数内で記述します。
【補足】同様に定期的に呼ばれる関数に
_UPDATE()
がありますが「_draw関数は通常30fpsで呼ばれますが、間に合わない場合、PICO-8は15fpsで画面更新を行い、代わりに1回の表示ごとに_update関数を2回呼びます。」と説明があり、こちらは内部処理に適しているとおもわれます。
②と③はテキストメッセージの表示ですね。最後の引数が色の指定で、以下 PICO-8 API 早見表 から転載します。
④ はスプライト表示ですね。最初の引数 1
がハートのスプライト定義を指定しています。
HELLO WORLD 表示部を理解してみる
さて、ちょっと複雑な HELLO WORLD
表示部をみていきましょう。ここですね。
※ 見やすくするためコメントアウトしたコードを削除しています
この表示部ですが、2段階の FOR
ループで構成されていますね。最初(外側)のループは制御変数が COL
で、値を「14から7まで」変化させています。これは表示色を制御しています。
試しに、このループにおける値の変化を「14から7まで」でなく、「14から9まで」に変更してみましょう。上の表示色の表から、結果が予想できますか?実行してみます。
予想通りでしたでしょうか?修正の結果、表示色7である白色と、表示色8である赤色の HELLO WORLD
表示が消えたことを確認できます。
【補足】このループでは -1 を指定して、「7から14まで」ではなく「14から7まで」の逆順でループを回しています。これは後で表示するほうが優先されるため、下から順に表示していき、白の
HELLO WORLD
文字列が最後に表示される、つまり他の色に上書きされるようにしています。
さて、2番目(内側)のループは制御変数が I
で、値を「1から11まで」変化させています。これは HELLO WORLD
各文字の表示を制御しています。間のスペースまで数えると、11文字ありますね。
試しに、このループにおける値の変化を「1から11まで」でなく、「1から8まで」に変更してみましょう。3文字ぶん減るわけですが、結果が予想できますか?実行してみます。
予想通りでしたでしょうか?修正の結果、HELLO WORLD
の最後の RLD
部分が表示されなくなったことを確認できます。
もう少し見ていきましょう。各文字の横の表示位置 X
を計算している部分に注目します。ここの I*8
を I*10
に変更したらどうなるでしょう?
結果として、HELLO WORLD
の文字間隔が広がりましたね。右の実行画面のほうに注目して欲しいのですが、H
文字から次の E
文字までの距離を計算しているのが I*8
の部分です。この幅が8ピクセルありました。ここを I*10
と変更したので、この幅が10ピクセルに増え、結果として文字間隔が広くなったのです。
なお PICO-8 において、標準のスプライトの大きさは 8x8 ピクセルです。なので I*8
で8ピクセルごとに横にズラして、画面上でちょうど良い感じで並ぶわけです。最初のスプライト定義部分をみるとわかるのですが、今回のサンプルにおいて、文字データは右の1ピクセルを使わないでデザインされています。なので I*7
として7ピクセルごとに横に並べると、隙間ない感じで表示できたりします。
この章はやたら長くなってしまいましたが、最後に各文字の縦の表示位置 Y
を計算している部分もみておきましょう。各色の縦位置が1ピクセルしかズレておらず、重なっていますので、3ピクセルごとの表示にしてみます。
結果は想像通りでしたでしょうか?縦の差がかなり広がって、各色がわかりやすくなりましたね。
以上で、基本的な表示部分の説明は終わりです。
HELLO WORLD を動かそう
さて、もう一度、完全な状態の HELLO
デモを見てみましょう。HELLO WORLD
の動きが面白いですよね。
さて、この動きは以下の計算部分で実現されています。t()
もしくは time()
は「最後に起動してからの経過秒を返す」関数です。
t1 = t()*30 + i*4 - col*2
x = 8+i*8 +cos(t1/90)*3
y = 38+(col-7)+cos(t1/50)*5
まず、この 't()' 関数の影響を無くしてみましょう。T()*30
とある部分を T()*0
と書き換えます。0を掛けることで値は常に0となり、プログラム実行直後の状態から時間が進まない感じになります。
さて、ここからは実際のロジックの説明になるのですが、三角関数(sin()
, cos()
) の説明からはじめると更に長くなってしまいます。ここでは三角関数を「-1 から 1 の範囲で移動する値を返す関数」としてとらえましょう。
具体的には、ある座標 X
を求めるときに、以下のようなロジックが良い感じで働く、ぐらいの理解でいきましょう。
-- T: 時間変化
-- DT: 変化速度(大きいほど遅い)
-- C: 中心点となる座標
-- W: 移動できる範囲
X = C + COS(T / DT) * W
例えば今回のサンプルで DT
に相当する部分を倍にしてみると、
動作が1/2にスローダウンするのがわかるとおもいます。
【補足】この例はちょっと手抜きで、本来はその前にある部分もあわせて
T1 = T()*30 + I*8 - COL*4
と修正しないと動きの幅が減ります
さて、せっかく三角関数を使っているので、最後は、その特徴を生かした修正をして遊んでみましょう。X
のほうを sin()
関数にして、変化量も Y
とあわせてみます。
SIN()
と COS()
の組み合わせ、三角関数といえば円運動ですよね!
皆さんも、この HELLO
サンプルの X
Y
座業の計算式など変更して、いろいろ遊んでみてください。
というわけで
PICO-8 楽しいですよね。
HELLO
サンプルの説明だけで今回の投稿が終わってしまいました。プログラミング初心者の方を想定して書いてみたので、経験者の方には冗長、かつあまり情報量はなかったと思います…
PICO-8 ぐらいの限定された環境のほうが、プログラミング入門には適している気がしています。ですので興味があれば、ぜひ購入して、いろいろ試していただければとおもいます。
私も学習を兼ねて、引き続き PICO-8 公式サンプルを読み解いていく予定です。余裕があれば、今回のように簡単な解説を書くかもしれません。あまり期待せずお待ちいただければ幸いです。
それではまた!