LoginSignup
0
0

PICO-8 の公式サンプルで遊んでみよう (1) HELLO

Last updated at Posted at 2023-12-03

PICO-8 とは

PICO-8 は「ファンタシー・コンソール」で、楽しく遊べる小さな仮想マシン環境です。まずは PICO-8 公式ページ を開き、トップページにあるデモで遊んでみると、だいたい感覚がつかめるかとおもいます。

有料($14.99)ですが、作成されたゲームやソフトウェアを実行するのは無料です。とてもシンプルな環境で、開発環境も実行環境も統合されているため、プログラミング入門には最適かとおもいます。

以下は関連リソースです。良質な入門記事が多い印象。

ちなみに似た方向性をもつ環境は幾つかあります。以前にご紹介した記事は以下なのですが、だいたいの雰囲気はつかんでいただけるかとおもいます。

デモを試してみる

ネット上に数多くの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 デモを実行してみましょう。

image.png

実行すると以下のような表示になります。ESC キーで終了し、コンソールに戻ります。

hello_0.gif

衝突判定サンプルの COLLIDE なども楽しいですね。

collide_0.gif

HELLO サンプル

いちばん簡単そうな HELLO サンプルの中身を見て、理解していきましょう。今回利用するのは PICO-8 v0.2.5g です。

元のコード

まずは HELLO サンプルの Lua ソースコードを見てみましょう。

HELLO
-- 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

そしてスプライト定義はこちらです。

image.png

短縮版のコード

上記コードからコメントと改行を削除してみました。結果、ギリで1画面に収まっています。

image.png

基本的な表示を理解してみる

HELLO WORLD 文字列のアニメーションが面白いわけですが、まずはこの動きを止めて、基本的な表示部分を確認しましょう。以下の赤枠の部分をコメントアウトします。

image.png
※ -- 以降がコメント文となり処理されません

RUN で実行すると、以下のようにアニメーションが止まった画面が表示されます。

image.png

HELLO WORLD 以外の部分から見ていきましょう。左が短縮したコートで、右がその実行画面です。

image.png

① の _DRAW() 関数は PICO-8 での標準のお作法で、画面更新に関する表示ロジックはこの関数内で記述します。

【補足】同様に定期的に呼ばれる関数に _UPDATE() がありますが「_draw関数は通常30fpsで呼ばれますが、間に合わない場合、PICO-8は15fpsで画面更新を行い、代わりに1回の表示ごとに_update関数を2回呼びます。」と説明があり、こちらは内部処理に適しているとおもわれます。

②と③はテキストメッセージの表示ですね。最後の引数が色の指定で、以下 PICO-8 API 早見表 から転載します。

image.png

④ はスプライト表示ですね。最初の引数 1 がハートのスプライト定義を指定しています。

HELLO WORLD 表示部を理解してみる

さて、ちょっと複雑な HELLO WORLD 表示部をみていきましょう。ここですね。

image.png
※ 見やすくするためコメントアウトしたコードを削除しています

この表示部ですが、2段階の FOR ループで構成されていますね。最初(外側)のループは制御変数が COL で、値を「14から7まで」変化させています。これは表示色を制御しています。

image.png

試しに、このループにおける値の変化を「14から7まで」でなく、「14から9まで」に変更してみましょう。上の表示色の表から、結果が予想できますか?実行してみます。

image.png

予想通りでしたでしょうか?修正の結果、表示色7である白色と、表示色8である赤色の HELLO WORLD 表示が消えたことを確認できます。

【補足】このループでは -1 を指定して、「7から14まで」ではなく「14から7まで」の逆順でループを回しています。これは後で表示するほうが優先されるため、下から順に表示していき、白の HELLO WORLD 文字列が最後に表示される、つまり他の色に上書きされるようにしています。

さて、2番目(内側)のループは制御変数が I で、値を「1から11まで」変化させています。これは HELLO WORLD 各文字の表示を制御しています。間のスペースまで数えると、11文字ありますね。

試しに、このループにおける値の変化を「1から11まで」でなく、「1から8まで」に変更してみましょう。3文字ぶん減るわけですが、結果が予想できますか?実行してみます。

image.png

予想通りでしたでしょうか?修正の結果、HELLO WORLD の最後の RLD 部分が表示されなくなったことを確認できます。

もう少し見ていきましょう。各文字の横の表示位置 X を計算している部分に注目します。ここの I*8I*10 に変更したらどうなるでしょう?

image.png

結果として、HELLO WORLD の文字間隔が広がりましたね。右の実行画面のほうに注目して欲しいのですが、H 文字から次の E 文字までの距離を計算しているのが I*8 の部分です。この幅が8ピクセルありました。ここを I*10 と変更したので、この幅が10ピクセルに増え、結果として文字間隔が広くなったのです。

なお PICO-8 において、標準のスプライトの大きさは 8x8 ピクセルです。なので I*8 で8ピクセルごとに横にズラして、画面上でちょうど良い感じで並ぶわけです。最初のスプライト定義部分をみるとわかるのですが、今回のサンプルにおいて、文字データは右の1ピクセルを使わないでデザインされています。なので I*7 として7ピクセルごとに横に並べると、隙間ない感じで表示できたりします。

image.png

この章はやたら長くなってしまいましたが、最後に各文字の縦の表示位置 Y を計算している部分もみておきましょう。各色の縦位置が1ピクセルしかズレておらず、重なっていますので、3ピクセルごとの表示にしてみます。

image.png

結果は想像通りでしたでしょうか?縦の差がかなり広がって、各色がわかりやすくなりましたね。

以上で、基本的な表示部分の説明は終わりです。

HELLO WORLD を動かそう

さて、もう一度、完全な状態の HELLO デモを見てみましょう。HELLO WORLD の動きが面白いですよね。

hello_0.gif

さて、この動きは以下の計算部分で実現されています。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となり、プログラム実行直後の状態から時間が進まない感じになります。

image.png

さて、ここからは実際のロジックの説明になるのですが、三角関数(sin(), cos()) の説明からはじめると更に長くなってしまいます。ここでは三角関数を「-1 から 1 の範囲で移動する値を返す関数」としてとらえましょう。

具体的には、ある座標 X を求めるときに、以下のようなロジックが良い感じで働く、ぐらいの理解でいきましょう。

-- T: 時間変化
-- DT: 変化速度(大きいほど遅い)
-- C: 中心点となる座標
-- W: 移動できる範囲
X = C + COS(T / DT) * W

例えば今回のサンプルで DT に相当する部分を倍にしてみると、

image.png

動作が1/2にスローダウンするのがわかるとおもいます。

hello_0.gif

【補足】この例はちょっと手抜きで、本来はその前にある部分もあわせて T1 = T()*30 + I*8 - COL*4 と修正しないと動きの幅が減ります

さて、せっかく三角関数を使っているので、最後は、その特徴を生かした修正をして遊んでみましょう。X のほうを sin() 関数にして、変化量も Y とあわせてみます。

image.png

SIN()COS() の組み合わせ、三角関数といえば円運動ですよね!

hello_1.gif

皆さんも、この HELLO サンプルの X Y 座業の計算式など変更して、いろいろ遊んでみてください。

というわけで

PICO-8 楽しいですよね。

HELLO サンプルの説明だけで今回の投稿が終わってしまいました。プログラミング初心者の方を想定して書いてみたので、経験者の方には冗長、かつあまり情報量はなかったと思います…

PICO-8 ぐらいの限定された環境のほうが、プログラミング入門には適している気がしています。ですので興味があれば、ぜひ購入して、いろいろ試していただければとおもいます。

私も学習を兼ねて、引き続き PICO-8 公式サンプルを読み解いていく予定です。余裕があれば、今回のように簡単な解説を書くかもしれません。あまり期待せずお待ちいただければ幸いです。

それではまた!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0