【プチコン講座】プログラミングでRPGを作りたい!ゲームの土台つくり編
こんにちは。継続の錬金術士なおキーヌです。
ブログ毎日更新は129日目になります。
先日、以下のようなツイートをしました。
GW最終日、皆様何か成長したり成果をあげましたでしょうか?
私はブログを毎日更新しつつ、
TypeScript+Electron+pixi.jsを使用して計8.5日で
1つゲームを完成させました。何日か進捗が悪かった日もありますが、何とか完成しました。
継続力のたまものです。 pic.twitter.com/h4HTNNOGi6— なおキーヌ@ゲームクリエイターLv1 (@naokeyzmt) 2019年5月5日
自作RPGを作ったのはいいのですが配布に困ったので、他の言語に移ろうかなと思いました。
結局ゲームって作ってもプレイされなきゃ意味がないんですよね。
といっても今回は自分がどこまで作られるかという実力試しというのもあったので、
配布しやすい形に作り直してから配布でもいいのですが。
とりあえず色々勉強不足な点も見えてきたのでゲーム作りに使う言語を選定しつつ、
今回作った自作RPGのコードをキレイにしながらSwitchで発売予定のプチコン4でRPGを作ろうと考えています。
そのプチコン4がSwitchに出るので予習も兼ねてプチコンBIGで作っておけば移植も楽なんじゃないかなと、
押し入れからWiiUを引っ張り出してきて久々にBASICを打とうとしたのですが、何から手を付けていいのやら……
BASICはすべて大文字なので、正直見通しのいい言語とは言えません。
一応Shiftを押せば小文字に出来るのですが大文字と小文字の区別はしないのであまり意味はありませんね。
BASICの書き方にならって全て大文字で行こうと思います。
それではプチコン講座 第1回目はRPGのマップをつくってみようのコーナーです。
私自身がプチコン超絶初心者なので至らないところもありますが、よろしくおねがいします。
プチコンを買ったけど、どうやって作ったらいいかわからない!
という方は私のやっていることをそのままやってみるといいかもしれません。
エディットモードやダイレクトモードの切り替えなどの基本的な操作説明は省いています。
それではプチコンでRPG作り第一回目を始めましょう。
ゲームループをつくる
まず、どんなゲームを作るにも絶対に必要になるゲームループを作る必要があります。
ゲームループを作らなかった場合、書いたコードを実行し終わったらプログラムが終わってしまいます。
普段プレイするゲームは放置してても、動き続けていますよね。
あれはゲームループという処理が動き続けているおかげです。
早速ゲームループを作ってみましょう。
'hoge
@GAME_LOOP
PRINT "こんにちは プチコン"
WAIT 1
VSYNC 1
GOTO @GAME_LOOP
実行してみると、こんにちは プチコン という文字がダーッ!と流れると思います。
1行ずつ見ていきましょう。
@GAME_LOOP と GOTO
@マークを戦闘に付けるとラベルにすることが出来ます。
ラベルとは簡単に言うと目印です。
ドラクエで言うと、ルーラ出来るリストの1つ。
ポケモンで言うと、そらをとぶで行ける場所の1つ。
一番最後の行にある GOTO(ゴトーさんではなくゴートゥ)
で指定したところにプログラムの実行を飛ばすことが出来ます。
PRINT "こんにちは プチコン"
コンソール画面(黒い画面)に文字を表示する命令ですね。
この文字がずらーっと並んでいるのはこの命令が1秒ごとに繰り返されているからです。
WAIT 1
WAITはプログラムをストップさせる命令です。
WAITの後にある1は秒数ですね。
1秒待ってから次の行を実行します。
VSYNC
プログラムは1回のループが1フレームです。
このVSYNCを入れると1秒間に最大60ループするように固定できます。
VSYNCを入れないとものすごい速さでループしてしまうので、ゲームループの最後にいれることで制御します。
VSYNCについては興味を持ったら自分で調べてみてください。
今はプチコンでゲームを作るときはVSYNCはゲームループの最後にいれるんだな!って覚えておけば大丈夫です。
プチコンで画像(マップチップ)を1つ表示してみる
ゲームループの準備が整ったので、次はマップ画面を作るためにグラフィックの表示をしてみましょう。
pixi.jsではスプライトと言っていましたがプチコンではレイヤーごとに名称が違うようで
バックグラウンドという概念があります。(厳密に言えばバックグラウンドもスプライト)
一応プチコンに準拠していくつもりなので、今後マップチップはBGと略します。
キャラクターなどのスプライトはSPで略します。
プチコンを始めた時、チュートリアルで線を表示したりしたと思いますが
今の若い世代には正直何もおもしろくなかったと思うので、いきなりグラフィック表示から始めます。
線の表示は時がきたらやりましょうかね。
それではバックグラウンド、つまりマップチップを表示するには
下記のコードを打ち込んで実行してください。
ACLS
BGPUT 0, 0, 0, 105
@GAME_LOOP
WAIT 1
VSYNC 1
GOTO @GAME_LOOP
実行してみると左上に緑の四角が現れたと思います。
これは草原のマップチップになります。
新しい命令が2つ増えているので見てみましょう。
ACLS
画面全体をクリア(真っ黒に塗りつぶす)するための命令です。
これをやらないと画面に前回表示したものが残ったままです。
今はプログラムの一番最初に置いておくものだと思っていてOKです。
BGPUT
今回マップチップを表示している部分です。
後ろに数字が4つカンマ区切りで並んでいるので説明しましょう。
1つめはBGレイヤーの番号、つまりBG画像を表示できるレイヤーです。
プチコンでは4つのBGレイヤーを用意しているらしくそれぞれに別々にマップチップが表示できます。
手前が早く、奥が遅く動くようなシーン(多重スクロールという)を作るときに使えますが今は0で大丈夫です。
2つめはx座標、よこ軸の座標です。
3つめはy座標、たて軸の座標です。
4つめは画像番号で、プチコンが用意してくれている画像の番号になります。
プチコン公式が画像番号リストを用意してくれてないのか、探すのに一苦労します。
(どこかにあったら申し訳ないですが教えてほしいです。)
とりあえず草原のマップチップを置きたかったので105にしています。
BGの画像はスマイルツールでみることができるので0~1024の数値で
数字を入れ替えてみて、色んな画像を表示してみるのも良いですね。
マップチップを画面全体にならべてみよう
マップチップ1つだけだとマップになりませんよね。
このマップチップを画面全てにならべてみましょう!
以下のコードを入力してください。
ちょっとむずかしいかもしれませんが、仕組みはカンタンです。
ACLS
VAR STOP_FLAG = FALSE
@GAME_LOOP
IF NOT STOP_FLAG THEN
FOR Y = 0 TO 14
FOR X = 0 TO 25
BGPUT 0, X, Y, 105
NEXT
NEXT
ENDIF
STOP_FLAG = TRUE
VSYNC 1
GOTO @GAME_LOOP
ACLSは説明したので省きます。
その下にある「STOP_FLAG = FALSE」
これは何をしているのかというと、フラグを用意しています。
何に使うのかは次に書きますね。
IF NOT STOP_FLAG THEN
IFはもし~という条件で処理を切り替える文でしたね。
先ほど作ったフラグのSTOP_FLAGはここで使います。
最初にFALSEを入れたので本来なら次の行が実行されずにELSEの方が実行されます。
しかしよく見てください。 IFと STOP_FLAG の間に何かありませんか?
そう、NOT という文字があります。
NOTとは否定の意味ですね。
IF STOP_FLAG THEN
だと もしSTOP_FLAGが真であれば~ という意味になりますが、NOTを付けることにより
もしSTOP_FLAGが真じゃなければ~という意味になります。
なぜこう書くのかというと、最初にSTOP_FLAGにFALSEを代入しているからですね。
別にSTOP_FLAGにTRUEを入れて IF STOP_FLAG THEN と書いても間違いではありません。
自分の好きなやりかたでも動くのがプログラミングの楽しいところなんです!
今回はこういう書き方も出来るんだ~って覚えてくれたらうれしいです。
FORの入れ子
なにやら見なれないコードがありますね。
FORは見たことがあるけど、NEXTの前にさらにFORが入っている!なんじゃこりゃ!
ってなると思います。
じつはこれ、とてもたいせつなコードなんです!
これが無いとRPGのマップを画面に表示できないからです!
それじゃあ解説しましょう。
FOR文は指定回数処理をくりかえす命令でしたね。
FORの中にFORを使うということは、中にある方のFORを繰り返すということです。
カンタンに言うと、以下のような処理をします。
わかりやすいように外側にあるFORを「FOR1」、内側にあるFORを「FOR2」と呼びましょう。
- FOR1でループ開始!カウントYは0で14までループするよ。
- FOR2でループ開始!カウントXは0で24までループするよ。
- BGPUTでマップチップを1つ表示するよ!X座標はFOR2のX=0、Y座標はFOR1のY=0
- FOR2のループ0回目が終わったので1回目のループ開始!X=1
- BGPUTでマップチップを1つ表示するよ!X座標はFOR2のX=1、Y座標はFOR1のY=0
- FOR2のループ1回目が終わったので2回目のループ開始!X=2
- BGPUTでマップチップを1つ表示するよ!X座標はFOR2のX=2、Y座標はFOR1のY=0
- ……省略
- FOR2のループ24回目が終わったのでFOR2のループを抜けるよ!
- FOR2のループを抜けたら次はすぐにFOR1の1回目のループが始まるよ!Y=1
- FOR2でループ開始!またまたカウントXは0で24までループするよ。
- BGPUTでマップチップを1つ表示するよ!X座標はFOR2のX=0、Y座標はFOR1のY=1
という感じでXが24まで行ったらYが1増えるのを繰り返します。
詳しく書くと、FOR2がループする度にマップチップが描写されて25回(0~24)描写したらY座標を1つ増やして、
また一番左から25回マップチップを表示する。
Yの数値が15になるまでずっとFOR2を繰り返します。
こうすれば画面全体にマップチップを敷きつめられますね!
STOP_FLAGをONにする
ループがすべて終わった後、最後にSTOP_FLAGをONにしています。
このフラグを切り替えないとゲームループが1ループする度にマップチップの描写を行ってしまいます。
そうするとものすごく処理が重たくなってしまいまともにゲームが出来なくなってしまいます。
フラグをONにすればIFの条件式を突破できなくなるので1回全部描写したら次は何もしません。
マップを表示しただけではゲームとは呼べませんね。
しかし!きみは いま! RPGつくり への だいいっぽを ふみだした!
補足:同じマップチップを並べるならBGFILLを使えばいい
今回のように同じマップチップを敷きつめるだけならプチコンでは「BGFILL」という命令を使えばコード1行で済みます。
しかし、森も山も洞窟も川もなにもないマップを歩いていて楽しいですか?
マップチップを表示するのはループの入れ子(今回使ったFORを重ねて使う)やり方が一般的です。
じゃあBGFILLってなにに使うんだよ!って思いますが私にも正直必要性を感じられません。
ただ、プチコンはバックグラウンドを表示できる画面が4つ用意されています。
一番下の画面に草原のマップチップを敷きつめて、その上に森や洞窟等を表示すれば活用できます。
そのやり方も今後学んでいきましょう!
実はこの記事を書いている私もプチコン歴1週間も経っていないのでわからないことだらけです。
それでは次回でお会いしましょう!