JavaScriptでRPGを作ろう!自作したマップをブラウザに表示しよう!

JavaScriptでRPGを作ろう!自作したマップをブラウザに表示しよう!

前回の記事では、Tiled Map EditorでRPG用マップの作り方について解説しましたが、自作したマップを実際にブラウザに表示するところまで、実際のJavaScriptの書き方について解説していきます。「ゲーム作りって大変そう。RPGのWebアプリを作ってみたいけどどうやるの?」という疑問にお答えします!

前回の記事を見逃した方は「JavaScriptでRPGを作ろう!Tiled Map Editorを使ったマップの作り方を解説」をご覧ください。

今回の記事の完成版はこちらで確認できます。[デモ]

HTML解説

外部スクリプトの読み込み

まずはライブラリやマップファイルを読み込んでいきましょう。

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js" integrity="sha512-NxocnqsXP3zm0Xb42zqVMvjQIktKEpTIbCXXyhBPxqGZHqhcOXHs4pXI/GoZ8lE+2NJONRifuBpi9DxC58L0Lw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="./p5.tiledmap.js"></script>
<script src="./data/village.js"></script>
<script src="./main.js"></script>

1~2行目はp5.js関連のライブラリの読み込みです。3行目はTiled Map Editorで作成したマップファイルを指定します。ここでは作業フォルダdataの中のvillage.jsを指定しています。4行目はJavaScript本体です。

mainタグの記述

続いてHTML本体ですが、空のmainタグを記述します。この中にp5.jsがcanvasタグを作ってくれます。

<body>
  <header>
    <h1>RPGサンプル</h1>
  </header>
  <main></main>
  <p style="text-align: center;">©2022 qoomei.com All rights reserved.</p>
</body>

JavaScript解説

変数定義

var tmap; // カレントマップ
var x, y; // キャラクタ位置

tmap、x、yのグローバル変数を定義します。

preload()関数

setup()の直前に呼び出されるpreload()関数は、外部ファイルの非同期ロードをブロックする方法で処理するために使用されます。preload関数が定義されている場合、setup()はpreload()呼び出しが終了するまで待機します。ロードコール(loadImage、loadJSON、loadFont、loadStringsなど)をpreload()関数内に入れます。ここではloadTiledMap()関数を呼び出しましょう。

xとyにはマップの座標を指定します。マップの座標の初期位置=主人公の位置=画面中央になります。

////////////////////////////////////////////////////////////////////////////////
// プリロード
function preload() {
  // 主人公の位置
  x = 11;
  y = 4;

  // デフォルトマップ
  loadTiledMap("village", "data", mapLoaded);
}

loadTiledMap()関数

TiledMapはTiled Map Editorで作成したマップファイルを指定します。これは次のようにscriptタグで事前にロードする必要があります。

 <script src="./data/village.js"></script>

loadTiledMap()関数のパラメータは次の通りです。第1引数にはマップ名、第2引数には作業フォルダ名、第3引数にはコールバック関数を指定しましょう。

第1引数 String mapNameマップ名を指定します。
第2引数 String imagePath画像ファイルへのパスを指定します。
第3引数 Function callbackマップがロードされたときに呼び出す関数を指定します。

setup()関数

setup()関数はプログラムの起動時に1回呼び出されます。これは、画面サイズや背景色などの初期環境プロパティを定義し、プログラムの起動時に画像やフォントなどのメディアをロードするために使用されます。プログラムごとに設定できるsetup()関数は1つだけであり、最初の実行後に再度呼び出すことはできません

////////////////////////////////////////////////////////////////////////////////
// セットアップ
function setup() {
  let cnv = createCanvas(640, 640);
}

createCanvas()関数

ドキュメントにcanvas要素を作成しそのサイズをピクセル単位で設定します。このメソッドはセットアップの開始時に1回だけ呼び出す必要があります。

第1引数 Number wキャンバスの幅をピクセルで指定します。
第2引数 Number hキャンバスの高さをピクセルで指定します。

draw()関数

setup()の直後に呼び出されるdraw()関数は、プログラムが停止するかnoLoop()が呼び出されるまでブロック内に含まれるコード行を継続的に実行します。 setup()でnoLoop()が呼び出された場合でも、draw()は停止する前に1回実行されます。 draw()は自動的に呼び出されるため明示的に呼び出すことはできません。
draw()が1秒間に実行される回数はframeRate()関数で制御できます。デフォルト値は60(FPS)です。

////////////////////////////////////////////////////////////////////////////////
// ドロー
function draw() {
  background(tmap.getBackgroundColor());
  tmap.draw(x, y);
}

background()関数

background()関数はp5.jsキャンバスの背景の色を設定します。デフォルトの背景は透明です。この関数は通常draw()内で使用され、各フレームの開始時に表示ウィンドウをクリアしますが、setup()内で使用してアニメーションの最初のフレームに背景を設定するか、背景を1回だけ設定する必要がある場合に使用できます。

tmap.draw()関数

draw()はTiledMapを描画します。引数にはxとyを指定しましょう。

コールバック関数

////////////////////////////////////////////////////////////////////////////////
// マップロード
function mapLoaded(newMap) {
  tmap = newMap;
  tmap.setPositionMode("MAP");
  tmap.setDrawMode(CENTER);
}

コールバック関数はロードされたマップを受け取ります。tmap.setPositionMode()には”MAP”を指定し、tmap.setDrawMode()にはCENTERを指定することで主人公が画面の真ん中にいるように描画することが出来ます。

完成ソースコード

以上で今回の解説はおわりです。完成したソースをブラウザで確認してみましょう。ブラウザで動作確認するにはWebサーバー環境である必要があります。あるいはローカルWebサーバーを立ち上げて確認してみてください。

フォルダ構成

/(root)
 ┣━ /data
 ┃   ┣━ village.js  <- JavaScriptマップファイル
 ┃   ┣━ CastleTown-C-1.png  <- マップチップ 1つ目
 ┃   ┣━ pipo-map001_at-sabaku.png  <- マップチップ 2つ目
 ┃   ┗━   :
 ┣━ index.html
 ┣━ main.js
 ┗━ p5.tiledmap.js

HTML

<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex">
<title>RPGサンプル</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js" integrity="sha512-NxocnqsXP3zm0Xb42zqVMvjQIktKEpTIbCXXyhBPxqGZHqhcOXHs4pXI/GoZ8lE+2NJONRifuBpi9DxC58L0Lw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="./p5.tiledmap.js"></script>
<script src="./data/village.js"></script>
<script src="./main.js"></script>

<style type="text/css">
body {
  background-color: #666666;
}
h1 {
  color: #ffffff;
}
main {
  width: 640px;
  height: 640px;
  margin: 0 auto;
  background-color: #333333;
}
</style>

</head>

<body>
  <header>
    <h1>RPGサンプル</h1>
  </header>
  <main></main>
  <p style="text-align: center;">©2022 qoomei.com All rights reserved.</p>
</body>
</html>

main.js

var tmap;	// カレントマップ
var x, y;	// キャラクタ位置

////////////////////////////////////////////////////////////////////////////////
// プリロード
function preload() {
  // 主人公の位置
  x = 11;
  y = 4;

  // デフォルトマップ
  loadTiledMap("village", "data", mapLoaded);
}

////////////////////////////////////////////////////////////////////////////////
// セットアップ
function setup() {
  let cnv = createCanvas(640, 640);
}

////////////////////////////////////////////////////////////////////////////////
// ドロー
function draw() {
  background(tmap.getBackgroundColor());
  tmap.draw(x, y);
}

////////////////////////////////////////////////////////////////////////////////
// マップロード
function mapLoaded(newMap) {
  tmap = newMap;
  tmap.setPositionMode("MAP");
  tmap.setDrawMode(CENTER);
}

おわりに

いかがでしたか。少ないコードを記述するだけでマップを表示させることができたと思います。次回は主人公を登場させてマップをスクロールさせる方法について解説していきたいと思います!