360行でイチから作るRPG

Processingで簡単RPG開発

これは何?

 Processing Advent Calendar 2014に今年も参加しまして、これはその12/11の記事です。夏にはUnity アセット真夏のアドベントカレンダー 2014 Summer!uProcessingでお手軽プロトタイピングなんて記事も書いたので、今年はアドベントカレンダーに2つ参加したことになります。めでたし、めでたし。

 いや、めでたしじゃなくて、なにか記事を書かねば……まぁ、直前にネタを考えるのはよくあることですが、今年は本当にノープランすぎて、仕事はマスターアップ直前で、プライベートでも多忙のためまったく余裕が無く、途方にくれるわけです。でも忙しいときにこそ何かしないと、いつも(遊ぶのにも)忙しいので、何もできなくなってしまいます。遊んで作るスマホゲームプログラミングを書いたのも忙しいときだったし。

 そんなわけでいくつか考えたのですが、今回はRPGを作ることにします。

 ProcessingでRPG。360行ぐらいです。Processing.jsを使ってブラウザ上で動かしたデモもあります。

解説

 実行するとこんな感じの画面が出て、マウスで好きなところへ行けます。右下に見える青いのが主人公です。これは勇者ですよね。そうとしか見えないです。心の中でロールプレイングしてください。

 レトロを超えたレトロっぷりですが、このカラフルな矩形を画像に置き換えれば見た目もがらりと変えられますので、改造してみてください。RPG フリー素材とかで検索するとよいかと思います。

 マップについてはデータを用意するのが面倒だったので、noise()を使って自動生成しています。

 具体的には、下記のような計算式で雲模様のような値を得ています。

float n = noise(x / (float)w, y / (float)h);

 n を * 255して塗りつぶした色でチップを作ったとしたらこんな感じ。

 その値を適当なしきい値で黒っぽいところは海、灰色は草原、白っぽいところは山……といった形で分けています。

int chipType(int x, int y) {
  float n = noise(x / (float)w, y / (float)h);
  if(isJavaScript) { n = n * 2.4f - 0.6f; }
  int type = CHIP_GLASS;
  if(n < 0.3f) type = CHIP_DEEP_SEA;
  else if(n < 0.33f) type = CHIP_SEA;
  else if(n > 0.8f) type = CHIP_MOUNTAIN_WALL;
  else if(n > 0.7f) type = CHIP_MOUNTAIN;
  else if(n > 0.6f) type = CHIP_FOREST;
  return type;
}

 そうするとこんな感じの地形として表示できます。毎回ランダムに変わりすぎると調整しづらいので、noiseSeed(1)と書いて乱数の種、乱数系列を固定化しています。

 どこまでも世界が広がっているので探索してみてください。作者にも先がどうなってるのか分かりません。これが乱数の醍醐味の一つですね。

 そのまま歩いていると、敵と遭遇して戦闘が始まります。

 Attackで攻撃するか、Escapeで逃げるかしましょう。Escapeは失敗することもあり、その場合は敵の攻撃を一方的に受けます。敵を倒すと経験値が得られて、一定値を越えるとレベルアップします。

 drawShape()で描いている矩形も、Enemyクラスでオーバーライドして画像ファイルと差し替えて改造するのも(以下略)。

 遠くに歩いた先の敵ほど強いので、油断は禁物です。ちなみに草原より、林や山の方に敵が多く潜んでいます。

 もし敵の攻撃を受けてHPが0になってしまうとレベルやパラメータが大きく減ってしまうので、ご注意を。

 なお、受けたダメージは歩くと回復します。

 最初は街の人との会話もランダムな謎言語文字列生成で作ろうかと思っていたのですが、そこまでは間に合わず断念――。

 あと戦闘をコマンド式のこのような別モードではなく、ぶつかってダメージを与えるようなアクションにするのも楽しそうです(コマンド式よりコード減りそう)。

デモとソースコード

 以下のリンク先で、HTML5版のサンプルデモとプログラムのソースコードを確認できます。

 プログラムはJavaScriptモードだけでなく、そのままJavaモードでも使えます。ただ、Java版とnoise関数で得られる値が微妙に異なったので、isJavaScriptで場合分けして値を調整しています。

画像を使えばこの通り

 矩形描画のかわりに画像ファイルを使うようにプログラムを書き換えて、マップチップやキャラクター、背景、フレームなどを描画するとこんな感じにできます。

 モンスターは10種類登録してあります。オフィスに住むというイルカも参戦?

 こちらのサンプルは360行ではなく、370行になってしまいました。

 使用させていただいた各素材の配布元様についてもソースコードの冒頭に記述してありますので、参考にどうぞ!