プログラムで絵を描こう – PICO–8ゲーム開発入門(2)
暑さが日ごと増してまいりましたが、皆様お変わりありませんか。きつい日差しの下、外を出歩くのは危険です。冷房の効いた部屋でプログラミングするのは、安全で健康的な夏の過ごし方としておすすめです。今回はPICO–8の使い方とプログラミングの基礎からはじめて、画面に絵を描くところまで説明します。第一回はこちら。
PICO–8の使い方
コマンドモード
さっそくPICO–8を起動しましょう。
かわいい音とともに起動した直後のPICO–8は、コマンドモードです。このモードでは、ファイル操作などのコマンドを実行できます。ご存じの方はご存じのとおり、WindowsのコマンドプロンプトやMacのターミナルにあたるものです。HELPと打ってEnterを押すと、使えるコマンドの一覧が表示されます。
その中にあるINSTALL_DEMOSコマンドを使ってみましょう。このコマンドで、PICO–8作者zepさん作のデモ・カートリッジがインストールできます。
これでDEMOSディレクトリー(フォルダー)にデモ・カートリッジがインストールされたので、CD(Change Directory)コマンドでDEMOSに移動します。DIR(DIRectory)コマンドを使うと、今自分がいるディレクトリーの中のファイル一覧が表示されます。
デモの一つ、JELPIを動かしてみましょう。LOAD JELPIでカートリッジを読み込めます。読み込んだら、RUNで実行すると、かわいいキャラクターの2Dプラットフォーマーが始まります。
ここで、このゲームの操作方法を説明する前に、PICO–8の入力装置について説明します。PICO–8は「空想上のゲーム機」であるわけですが、架空の入力装置も設定されています。下図のようなイメージです。プログラミングしたり絵を描いたりするには、キーボードやマウスが使えますが、作成したプログラムを実行する際には、十字キー+2ボタンのファミコンのようなコントローラーのみが使える、という仕様です。
架空のコントローラーのボタンは、PCのキーボードでは、以下のように割り当てられています。
十字キー: 上下左右矢印キー
ボタン◯: Z
ボタン✕: X
JELPIでは、◯でジャンプ、✕で特殊なアタックです。
エディターモード
ESCを押すとゲームが止まります。さらにもう一度ESCを押すと、下図の画面になります。これはエディターモードです。JELPIを読み込んだ状態なので、JELPIのコードが見えています。このモードでは、マウスが使えます。右上のアイコンをクリックすることで、エディターを切り替えることができます。
使えるエディターは以下のとおりです。
- コード・エディター
- スプライト・エディター
- マップ・エディター
- 効果音エディター
- 楽曲エディター
今回は、コード・エディターのみ使用します。
エディターモードでESCキーを押すと、コマンドモードに戻ります。ESCキーでコマンドモードとエディターモードを行き来できるわけです。
SPLORE
ここでもうひとつ、PICO–8の中で使える便利なツール、SPLOREを紹介します。コマンドモードでコマンドSPLOREを実行すると、下図のような画面になります。これはカートリッジの管理ツールで、PICO–8公式掲示板にアップロードされているカートリッジを、ダウンロードして遊ぶことができます。さらに、ダウンロードしたカートリッジは、中身を見ることができるのです!
ESCキーでSPLOREから終了できます。SPLOREを終了した状態では、最後に読み込んだカートリッジが読み込まれた状態になっています。あるカートリッジの中身を見るには、SPLOREでカートリッジを読み込む→SPLOREに戻る→SPLOREを終了するという流れです。
Luaプログラミング事始め
PICO–8ではLua言語を使います。Luaは、本年のオリンピック開催地であるブラジルはリオデジャネイロ・カリトカ大学で生まれたスクリプト言語で、ゲーム業界で利用されることが多いそうです。オープンソースなゲームエンジンLÖVEや、『キャンディークラッシュ』で有名なKingが公開したDefoldもLuaを採用しているようです。筆者の個人的感想ですが、初学者にとっては覚えることが少なく、とっつきやすい言語ではないかと思います。
なお、本連載では、プログラミングをまったく経験したことのない方向けに、プログラミングの基礎概念から説明していきます。経験者の方は、Web上のLua解説などで学習していただいて、PICO–8独自の内容以外は読み飛ばしていただくのが良いかと思います。
プログラムとは、コンピューターへの命令が順番に書かれた指示書です。Luaでは、ひとつずつの命令の区切れは改行です。つまり、一行がひとつの命令です。エディターモードのコード・エディターに下記のコードを打ち込んでみてください。(※PICO-8ではすべての文字が大文字です。この連載でもコードはすべて大文字で書きますが、入力する際はShiftキーやCaps Lockキーを使う必要なく、小文字を打てば大文字で表示されます。)
PRINT(“PICO”) PRINT(“8”)
そしてコマンド・モードに戻り、RUNしてみると、以下のように表示されるはず。
PRINT()は、()の間に入れた内容を表示して改行せよ、という命令です。上から順に実行されたことがわかると思います。
変数
PICO–8プログラミングで重要な3つの要素として、「変数」、「関数」、「制御文」の3つを挙げたいと思います。覚えるべきことは、ほかにもまだいくつかありますが、最低限この3つをおさえておけば、原理的にはなんでも作れるはず。さて要素その1、変数について学びましょう。
数学にも登場するので想像がつくかもしれませんが、変数とは数値を入れて保存しておける場所です。実際には数値だけでなく、文字列(文字の連なり。文言、文章などすべてを指した、プログラミング的な呼び方です。英語では”string”。)も入れることができます。
Pro Tips: Luaの変数には、実際には、ブール値、テーブル、関数なども格納できます。
たとえばRPGを作っているとして、プレイヤーのヒット・ポイントのデータを保存するには、こんなふうにします:
HIT_POINT = 100
この一文を数学として読むと、「HIT_POINTは100に等しい」ということになります。しかし、この”=“は「等しい」という意味ではなく、HIT_POINTという名前の変数に100を入れなさい、という命令です。”=“の左側が入れられる側(変数)で、右側が入れるデータ、というルールです。
変数はその名のとおり、中身のデータを変えることができます。プレイヤーがモンスターに攻撃されてダメージを受けたときはこんな感じ:
HIT_POINT = HIT_POINT - 30
この一文は数学として読むとおかしいですが、「”=“の左側が入れられる側、右側が入れるデータ」というルールで考えれば簡単です。まず右側から考えます。今、HIT_POINTは100ですが、30のダメージを受けて70に減ります。これを左側のHIT_POINTに入れなさい(上書きしなさい)、というのがこの一文です。
今の一連の流れを実行してみましょう。コード・エディタに下記を打ち込んでみてください。
HIT_POINT = 100 HIT_POINT = HIT_POINT - 30 PRINT(HIT_POINT)
コマンド・モードでRUNで実行してください。下記のように表示されたと思います。
なお、Luaの変数には「型」がありません。他の言語では、変数に格納できるデータの形式「型」が決まっていることがあります。整数型の変数には整数のみ、文字列型の変数には文字列のみ入れることができます。Luaでは、ひとつの変数に整数でも実数でも文字列でも、なんでも放り込むことができます。たとえば、
HIT_POINT = 100 HIT_POINT = HIT_POINT + 10.5 PRINT(HIT_POINT)
これを実行すると、
さらに、
HIT_POINT = 100 HIT_POINT = “HELLO” PRINT(HIT_POINT)
これを実行すると、
変数HIT_POINTは”HELLO”という文字列で上書きされた、というわけです。ただし、中身が文字列のときに、数値のように足し算などを行うことはできません。たとえば、
HIT_POINT = “HELLO” HIT_POINT = HIT_POINT + 100
これを実行するとエラーになります。
関数
さて、つぎに要素その2「関数」を説明します。関数も数学に由来する概念ですが、ここでは難しく考えず、「命令文のかたまり」だと思ってもらえば大丈夫です。ある一連の命令に名前をつけて、あとで何度も簡単に呼べるようにしたものです。たとえば、最初に説明した2行の命令を関数にしてみます:
FUNCTION PICO() PRINT("PICO") PRINT("8") END PICO()
FUNCTION PICO() から END までの行が関数の定義です。このコードを実行した時、FUNCTION〜ENDのまではすぐには実行されず、PICOという名前の関数として登録されます。関数の中身の行は、PICO()によって実行することができます。このコードを実行すると、
さきほどと同じ結果が得られます。
なお、上記のコードにおいて、関数の中身の行は、それが中身であることがわかるように字下げしています。行の先頭でTabキーを押すと字下げできます。
関数の引数
関数は、入力を受け取ることができます。関数への入力は「引数(ひきすう)」と呼ばれます(英語では”parameter”)。これまで使ってきたPRINT()も、実のところ「文字列を受け取って画面に表示する」という関数なのです。引数を受け取る関数を作ってみます:
FUNCTION SUM(A, B) PRINT(A + B) END SUM(3, 5)
これは、足し算を実行して画面に表示する関数です。SUM(A, B)のAとBが引数です。引数はひとつだけでなく、複数にすることができます。呼び出すときに入れたデータが、このA、Bの変数に入り、関数の中でだけ使用できます。これを実行すると、
となるわけです。
PICO–8に組み込まれた関数
さて、関数の概念と作り方がわかりました。これからは、PICO–8に組み込まれているグラフィックスにかんする関数を使って、画面に絵を描いてみましょう。
「PICO–8に組み込まれている」とは、PICO–8独自の要素だということです。PICO-8で使用する言語はLuaですが、PICO-8ではLua言語がもともと備えている文法に加えて、PICO-8独自の文法や関数が使用できます。いままで使ってきたPRINT()は、実はLua言語の命令ではなくて、PICO–8で独自に追加された関数です。PRINT()やこれから説明するグラフィックス関数などは、Lua言語が使えるほかのゲームエンジンなどでは使えないことに注意してください。
ドットを打つ
ここまではPRINT()を使って、画面に1行ずつ数値や文字列を表示するプログラムを作ってきました。この場合、プログラムを実行していくと、画面にさまざまな文字が残っていきます。グラフィックの作業を始める前に、まずはこれらをきれいにしましょう。CLS()を実行すると、画面全体が真っ黒になります。CLSはCLear Screenの略です。
CLS()
真っ黒といっても、画面に「>」が残っていて、完全な真っ黒とはいえません。これを取り去る方法は、次回に説明します。今回のところは、こういうものだと思って気にしないでおいてください。
この黒い画面にドットを打ってみましょう。ドットを打つにはPSET()を使います。この関数は引数を3つ受け取ります。
PSET(X, Y, C)
- X: X座標
- Y: Y座標
- C: 色の番号
です。まず座標について説明します。PICO–8の画面の2次元座標は、数学の座標とはY軸の方向が逆です。下図のように、左上の位置が(0,0)で、右下が(127,127)です。
また、3番目の引数の色の番号については、スプライト・エディターに現れるパレットの色の順番に対応して、以下のようになっています。
0: 黒色、1: 暗い青色、2: 暗い紫色、3: 暗い緑色
4: 茶色、5: 暗い灰色、6: 明るい灰色、7: 白色
8: 赤色、9: オレンジ、10: 黄色、11: 緑色
12: 水色、13: 藍色、14: ピンク、15: 桃色
ここでは星のように、いくつかドットを打ってみましょう。以下のコードを打ち込んで実行してみてください。
CLS() PSET(35,30,7) PSET(20,90,7) PSET(110,65,7)
色番号7番は白です。実行すると以下のようになるはず。
おめでとうございます!PICO–8の画面に星空を描けましたね。
線を引く
せっかく星空ができたので、線を結んで星座を表現してみましょう。線を引くにはその名の通りLINE()関数を使います。これは5つの引数を受け取ります。
LINE(X0, Y0, X1, Y1, C)
- X0: ひとつめの点のX座標
- Y0: ひとつめの点のY座標
- X1: ふたつめの点のX座標
- Y1: ふたつめの点のY座標
- C: 色番号
次のコードを打ち込んでください。CLS()とPSET()の部分は、前のコードと同じです。
CLS() LINE(35,30,20,90,1) LINE(20,90,110,65,1) LINE(110,65,35,30,1) LINE(35,30,7) LINE(20,90,7) LINE(110,65,7)
これを実行すると……これは、夏の大三角形だ!
LINE()で引く線の色は、星の点と区別するために濃紺にしてみました。また、PSET()でドットを打つ処理をLINE()のあとにしたことで、星が線の上に描かれるようにしてあります。
円を描く
夏っぽい雰囲気を演出できたところで、今回の講義を終わってもよいのですが、まだいくつかある、グラフィックス関数について学んでしまいましょう。1ピクセルの点だけの星は見づらいので、円で表現してみましょう。CIRCFILL()を使いましょう。CIRCle(円)とFILL(塗る)をくっつけた名前です。
CIRLFILL(X, Y, R, C)
- X: 円の中心のX座標
- Y: 円の中心のY座標
- R: 円の半径
- C: 色番号
次のコードを打ち込んでください。PSET()で星を描いていた箇所を、CIRCFILL()で置きかえてあります。
CLS() LINE(35,30,20,90,1) LINE(20,90,110,65,1) LINE(110,65,35,30,1) CIRCFILL(35,30,2,7) CIRCFILL(20,90,2,7) CIRCFILL(110,65,2,7)
これを実行すると……
うーん、あまり美しくはないですが、星がはっきりわかるようになりました。なお、CIRLFILL()からFILLを取った、CIRC()を使うと、輪郭だけの円を描くことができます。引数の構成は同じです。
矩形を描く
耳慣れない言葉かもしれませんが、矩形(くけい)とは長方形のことです。RECTFILL()で矩形に色を塗ることができるので、これをCLS()の代わりに使って、夜空を少し明るめにしてみましょう。
RECTFILL(X0, Y0, X1, Y1, C)
- X0: 矩形の左上の点のX座標
- Y0: 矩形の左上の点のY座標
- X1: 矩形の右下の点のX座標
- Y1: 矩形の右下の点のY座標
- C: 色番号
RECTangle(矩形)とFILL(塗る)をくっつけた名前です。FILLを取ったRECT()も存在し、そちらでは輪郭だけの矩形を描くことができます。
次のコードを打ち込んでみてください。CLS()をRECTFILL()に置きかえ、またLINE()の色を変えてあります。
RECTFILL(0,0,127,127,1) LINE(35,30,20,90,13) LINE(20,90,110,65,13) LINE(110,65,35,30,13) CIRCFILL(35,30,2,7) CIRCFILL(20,90,2,7) CIRCFILL(110,65,2,7)
これを実行すると、すこし明け始めた夜空になります。
Pro Tips: 今回説明した各グラフィックス関数の、色を指定する最後の引数は、実はオプションです。COLOR()関数を使って使用する色を事前に設定しておけば、省いても構いません。
次回
今回は、図形を描く関数について学びました。これらは、PICO–8ゲーム開発でとても使える道具ですので、ぜひ覚えておいてください。これからの基本的な図形の組み合わせだけでも、ゲームを作ることはできます。たとえば、こんな感じ:
次回は、自分で描いた絵を画面に出せるようにするために、「スプライト」について学びましょう。また、図形や絵を動かす方法についても説明します。
PICO–8最新情報
PICO-8マニュアル日本語版
PICO–8に付属しているマニュアル”pico8.txt”は、英語版のみですが、北尾さんという方が日本語訳を公開してくださいました。このマニュアル、PICO-8でできることすべてがコンパクトにまとまっていますので、ぜひご一読ください。
PICO-8ワークショップ
PICO-8作者zepさんのオフィスでもある東京・吉祥寺『Pico Pico Cafe』でのワークショップも、すでに次回で第三回となりました。今回は、いままでと同様にプログラミングを1から学ぶ講座を行いながら、腕に自身のある方は、お題にそって最初から制作をはじめていただく、という趣向です。
日時: 2016年8月27日 14:00開場、14:30開始 (19:00ごろ終了予定)
場所: Pico Pico Cafe (東京都武蔵野市吉祥寺南町1–11–2 もみじビル8階)
定員: 10名
料金: 4,000円 (PICO–8ダウンロードキー、軽食付。PICO–8をお持ちの方は500円割引き)
持ち物: ノートパソコンをご持参ください(電源、Wifiを利用できます)。
参加申し込みは、PeatixまたはPico Pico Cafeへ直接(メール・電話)お申込ください。