1. HOME
  2. »
  3. プログラミング・Web
  4. »
  5. JavaScript
  6. »
  7. JavaScriptでRPGを作ろう!スマホにも対応したゲームの作り方

JavaScriptでRPGを作ろう!スマホにも対応したゲームの作り方

みなさんこんにちは。今日も楽しくプログラミングを学んでいきましょう!

これまでの講座こうざで、JavaScriptジャバスクリプトによるゲーム開発かいはつの方法が、なんとなくでも分かっていただけたかな、と思います。
今回からは、これまでの復習ふくしゅうもかねて、本格的ほんかくてきにRPGをフルスクラッチで作っていこうと思います。

ちなみにフルスクラッチは、ライブラリなどを使わずに一から自分で作る、という意味です。

りこ

ねぇ、アル。私たち、今までにいっぱいプログラミングを学んできたでしょ?

アル

うん、いろんなことをおぼえたよね

りこ

そろそろ1つぐらいゲームを完成させられるんじゃないかなって思って

アル

あ、そうだよね。ぼくたち、もうゲームをつくれるような気がするよね!

りこ

今から山田先生にききに行ってみない?

アル

うん、行こう!

りこ

山田先生! そろそろちゃんとしたゲームを作りたいってアルが

アル

ちょっと、りこちゃんが言い出したんじゃないか

りこ

ふふふ、そうだった

山田

まぁまぁ。じゃあ、今回から本格的にRPGを作っていくべか?

アル

RPG? 作りたい!

りこ

私も!

目次
  1. 今回から作るゲームについて
  2. 使用する素材そざいについて
  3. フォルダ構成こうせいについて
  4. index.htmlファイルを作ろう!
  5. JavaScriptのファイルを、index.htmlから読み込もう!
  6. ゲームエンジンについて

今回から作るゲームについて

まずは、今回から作っていくゲームを見てみましょう。
このようなゲームを作ります。

パソコンで遊ぶときは、ゲーム画面をクリックしてから、なにかキーを押してね!)

※音が出ますので、ご注意ください。

パソコンの場合は、ゲーム画面をクリックしてから、なにかキーを押してください。
スマホの場合は、ゲーム画面をタップして、ゲームをはじめてください。

タイトル画面では、スペースキー、もしくはタップで、次に進めます。

ゲーム内では、方向キー、もしくはゲーム左下の方向パッドで、山田先生を操作そうさできます。(方向パッドはスマホのみで対応。パソコンのマウスでは操作できません)

ゲーム内容:
山田先生、りこちゃん、アルくんが、迷宮めいきゅうに閉じ込められてしまいました。
前後左右、どこを見ても壁ばかり。でもきっとどこかに出口があるはず……

みんなでゴールを目指そう!

このゲームについて:
このゲームは、JavaScriptで作ったものです。
今回は、タイルマップの作り方、キャラの移動と当たり判定、シーンの変更、音声の鳴らし方、など、RPGを作成するうえで、基本なのにむずかしい、という部分にしぼっています。
戦闘、レベルアップ、アイテム、といったものは、今回は省略しょうりゃくしていますが、そういったものも作ると、もっとRPGらしくなると思います。

使用する素材そざいについて

素材そざいはこちらを使います。
まとめてダウンロードするには、こちらをクリックしてください。

山田先生(yamada.png)
りこちゃん(rico.png)
アルくん(aru.png)
START(start.png)
GOAL(goal.png)
タイル(tile.png)
D-PAD(dpad.png)
スタート(start.mp3)
クリア(clear.mp3)
BGM(bgm.mp3)

素材そざい利用りようについて

ここで公開している素材は、ここに書かれた範囲内はんいないであれば、だれでも自由に使うことができます。

まず、そのままの素材や、ちょっとだけ加工かこうしたものを「ぼくが作った!」っていうふうに言ったり、再配布さいはいふするのはダメです。もちろん「私が作りましたよ」でもダメです。
ちょっとだけ加工……というのは、たとえば、曲にエコーをかけて、「これぼくが作曲した!」というのはダメです。
BGMに合わせてラップを歌って、「これオレの曲。かっこいいだろ」は、かまいません。

山田先生、りこちゃん、アルくんは、このサイトのオリジナルキャラクターとなります。ですが、画像素材はキャラの変更へんこうをしないかぎり、自由に使ったり、公開したりできます。
キャラの変更……というのは、名前を変えたり、べつの作品のキャラクターにしたりすることです。たとえば、山田先生の画像を白黒反転はんてんさせて、「白猫プロジェクトのキャトラです」はダメです。もちろん「黒猫のウィズです」もダメです。

白猫や黒猫とは関係なく、曖昧あいまいという意味でのグレーな部分は、とりあえずOKにします。たとえば、山田先生の耳を消して「耳をかじられてから、ネズミが怖くなってしまったべ……」は、かまいません。

この素材を使って作ったものを公開するとき、著作権表示ちょさくけんひょうじなどは、してもしなくてもOKです。報告ほうこくも、してもしなくてもOKです。

山田

ちなみに、ここでいう再配布は、ここの素材を別のサイトで素材みたいなかたちで配布することを言っているべ
もちろん素材を使ったゲームを公開してはいけない、と言っているわけではないべよ

※素材の利用については、今後変更される場合があります。

フォルダ構成こうせいについて

まず、フォルダ構成こうせいを見ていきましょう。
フォルダ構成とは、つくりたいものがあるフォルダのなかにどのようなフォルダやファイルがあるのか、という意味です。

今回はrpgというフォルダを作って、そのなかにいろんなフォルダやファイルを作っていきます。
ゲームが完成したとき、フォルダ構成はこのようになります。

rpg/
|-- img/
│   |-- aru.png
│   |-- dpad.png
│   |-- goal.png
│   |-- rico.png
│   |-- start.png
│   |-- tile.png
│   `-- yamada.png
|-- index.html
|-- js/ 
│   |-- engine/
│   │   |-- charactertile.js
│   │   |-- dpad.js
│   │   |-- game.js
│   │   |-- party.js
│   │   |-- scene.js
│   │   |-- sound.js
│   │   |-- sprite.js
│   │   |-- text.js
│   │   |-- tile.js
│   │   `-- tilemap.js
│   |-- main.js
│   `-- map.js
`-- sound/
    |-- bgm.mp3
    |-- clear.mp3
    `-- start.mp3

とてもたくさんのフォルダやファイルがあって、すごく分かりにくいですよね……
大丈夫です。これから順番に作っていくので、まずは以下のこれだけ用意しておいてください。

rpg/
|-- img/
│   |-- aru.png
│   |-- dpad.png
│   |-- goal.png
│   |-- rico.png
│   |-- start.png
│   |-- tile.png
│   `-- yamada.png
|-- index.html
`-- sound/
    |-- bgm.mp3
    |-- clear.mp3
    `-- start.mp3
山田

imgフォルダやsoundフォルダに入っているファイルは、さきほどの素材からダウンロードしたものを使ってほしいべ

ただ、index.htmlファイルは自分で作成するべよ

りこ

内容はどうするの?

山田

いまから説明していくべよ!

index.htmlファイルを作ろう!

では、index.htmlファイルを作成しましょう。

アル

えっと、まずなにからはじめるんだっけ?

りこ

ホームページをつくるのよ

アル

あ、そうか。ブラウザあそぶゲームだから、ホームページ必要ひつようなんだったよね

えっと、いんでっくす、えいちてぃーえむえるだっけ?

りこ

そうそう、index.html

山田

ふたりとも、よく覚えててくれたべな
では、index.htmlを作っていくべよ

ブラウザゲームを作るには、そのゲームをうごかすためのサイト必要ひつようになります。
index.htmlは、サイトを開いたとき、他のファイル指定していされていないときに開かれるファイルで、つまりトップページということになります。

では、index.htmlファイルを作っていきましょう。
これはrpgフォルダのなかに作ります。

index.htmlは、次のようにします。

index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>くろねこラビリンス</title>
	<style>
		* {
			padding: 0;
			margin: 0;
		}
		canvas {
			display: block;
		}
	</style>
</head>
<body>

</body>
</html>
山田

index.htmlファイルを作ったら、それをブラウザで開いてほしいんだべ

アル

開いたけど、まだ画面が真っ白だね……

りこ

ほんどだ

山田

まだなにも表示ひょうじしてないべからな……
じゃあ、作っていくべよ

JavaScriptのファイルを、index.htmlから読み込もう!

つづいて、index.htmlから、JavaScriptファイルを読み込んでいきましょう。

山田

まずは読みこむJavaScriptファイルを作るべ

rpgフォルダに、jsフォルダを作って、そこにmain.jsファイル追加ついかしてほしいんだべ

rpg/
|-- img (省略)/
|-- index.html
|-- js (追加)/
│   `-- main.js (追加)
`-- sound (省略)/
りこ

main.jsには、まだなにも書きこまなくていいんだよね?

山田

そうだべよ

アル

えっと、次はどうするんだ……

山田

index.htmlから、main.jsを読みこむべよ
bodyタグのなかに、main.jsを読みこむためのおねがいを書くべ

index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>くろねこラビリンス</title>
	<style>
		* {
			padding: 0;
			margin: 0;
		}
		canvas {
			display: block;
		}
	</style>
</head>
<body>
	<script src="js/main.js"></script>
</body>
</html>
アル

入力したよ!

りこ

でも、ちゃんと読みこめてるかな……

山田

ちゃんと読みこまれてるか、main.jsにちょっとコマンドを追加して、確かめてみるべ

main.jsファイルが、ちゃんとindex.htmlから読みこまれているか、確かめていきたいと思います。
今回はdocument.write();をつかって、パソコンにお願いをしてみます。

document.write();は、画面に文字やタグなどのデータを表示できるものです。

では、main.jsに、このように入力してください。

js/main.js

document.write( 'くろねこラビリンス' );

ブラウザを開き、「くろねこラビリンス」と表示されていれば、ぶじmain.jsが読みこまれている、ということになります。

山田

「くろねこラビリンス」って表示されたべか?
もし表示されなからった、main.jsまでのパスと、ファイルの場所が、ちゃんと合っているか確認してほしいんだべ

アル

えっと、パスってなんだっけ?

りこ

目的のファイルまでの道順みちじゅんのことよ
今回だったら、main.jsがどこにあるのかってやつ
さっきindex.htmlに追加した「js/main.js」の部分よ

山田

そうそう。ちなみにパスについては「パスの書き方を覚えよう。絶対パス、相対パス、ルート相対パスの違い」でくわしく紹介しょうかいしているべよ

アル

ブラウザに「くろねこラビリンス」って表示されてれば、ちゃんと読みこまれてるんだよね……うん。ちゃんと表示されたよ!

山田

では進めるべよ
じつはもうひとつ、つくっておきたいファイルがあるんだべ

りこ

えっ、もうひとつつくるの?

山田

そうだべ
つくるのはゲームエンジンをつくるためのファイルだべ

さきほどmain.jsファイルを作りましたが、もうひとつ作っておきたいファイルがあります。
それはゲームエンジンをつくるためのものです。

では、jsフォルダengineエンジンというフォルダを作成し、そこにgame.jsファイルをつくりましょう。

rpg/
|-- img (省略)/
|-- index.html
|-- js/
|   |-- engine (追加)/
|   |   `-- game.js (追加)
|   `-- main.js
`-- sound (省略)/

このあと、必要ひつようなときにファイル追加ついかしていきますが、まずはこれだけで進めていきましょう。

では、index.htmlからgame.jsを読みこみます。

index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>くろねこラビリンス</title>
	<style>
		* {
			padding: 0;
			margin: 0;
		}
		canvas {
			display: block;
		}
	</style>
</head>
<body>
	<script src="js/engine/game.js"></script>
	<script src="js/main.js"></script>
</body>
</html>

さらに、game.jsファイルは、このようにします。

js/engine/game.js

document.write( 'ゲームエンジン' );

これでブラウザを再読みこみし、「ゲームエンジン くろねこラビリンス」と表示されれば、game.jsとmain.jsがぶじ読みこまれていることになります。

テキストが2つ表示されていれば、2つのファイルが読み込めているよ!
りこ

「ゲームエンジン」「くろねこラビリンス」の、両方のテキストが表示されてるってことは、2つのファイルが読み込まれてるってことね!

ゲームエンジンについて

さて、さきほどからゲームエンジンといっていますが、ゲームエンジンとはなんなのでしょうか。

アル

ねぇ、さっきから言ってるゲームエンジンってなんなのさ

山田

まぁ、簡単かんたんなものになってしまうべけど、ゲームづくりに使う機能きのうをまとめたものをあらかじめつくっておくんだべ

りこ

機能?

山田

たとえば、画像(スプライト)や文字を表示する機能、それを動かす機能、画像同士がぶつかったかどうかをチェックする機能など、いろいろつくっておくんだべ

アル

なんだかむずかしいよ! 画像を表示したければ表示するプログラム書いて、動かしたければ動かすプログラムを書けばいいじゃん!

りこ

うん……作りたいものから順番じゅんばんに、そのままつくっちゃだめなの?

山田

作りたいものをそのままつくってしまうと、また次の新作をつくりたいって思ったとき、もういちど1からつくらなくちゃいけなくなるんだべ
よく使う機能をまとめたものをあらかじめ作っておけば、今後こんごのゲームづくりでそれを使い回せるし、ソースも綺麗きれいになるべよ

アル

うーん。いまいちピンとこないな……

山田

そうだべか……じゃあ、こんな話をしてあげるべ

では、ここでクッキーの話をしましょう。
クッキー。おいしいですよね。

たとえば、AさんとBさんがいたとします。
そして2人は、クッキーをつくることにしました。

Aさんはとっても作業さぎょうがはやいです。スピードでは誰にも負けません。
スマホでささっとレシピを調べ、さっそくクッキーづくりにとりかかり、焼き上がるまで20分ほどでした。

Bさんは、料理が大好きです。
いろんなサイトでいろんなレシピを見て、どうやってつくるか考えます。もちろんあれこれ考えるのも、Bさんにとっての楽しみのひとつです。
Bさんは、材料ざいりょう分量ぶんりょうなど、作り方をかんたんにメモすると、小麦粉の量をはかり、カップに線を引きました。これでこのカップを使えば小麦粉の分量が分かるので、次にクッキーを作るときは楽ちんです。もちろん、メモした紙も、ちゃんとファイルにしまっておきました。
そんなこんなで、Bさんはクッキーを焼き上げるまでに、40分かかりました。

さて、数日後……2人は、もう一度クッキーを作ろう、という話になりました。

Aさんは、前回作ったサイトときに参考さんこうにしたサイトさがします。作ったのは数日前なので、履歴りれきも消してしまっていました。作ったときの記憶きおくも、もううすれてしまっています。分量なんて、まったく覚えていません。
まぁクッキーなんてどのレシピを見たって一緒いっしょだろ、と思い、前回とはべつのサイト参考さんこうに作りました。クッキーを焼き上げるまでにかかった時間は、前回と同じ20分でした。

Bさんは、ちゃんと前回見たサイトに書いてあった分量をメモしていました。今回はそのメモを見ながら作業をしています。
しかも、カップに線を引いておいたので、小麦粉の分量をはかるのは一瞬でできます。しかし前回、ちょっと小麦粉の量が多かった気がしたので、今回はその線よりすこし少なめにしました。
Bさんはクッキーを焼き上げるまでに、10分しかかかりませんでした。

アル

なんだよこの話。プログラミング関係かんけいないじゃん!

山田

まぁまぁ。じゃあアルくん、この話、どっちが効率こうりつがいいと思うべ?

アル

うーん、さいしょはAさんの方がいいと思ったけど、Bさんのほうが要領ようりょうをつかんでるよね
でも2回を合わせれば、Aさんは40分で、Bさんは50分。最終的にはAさんのほうがはやいよ

山田

クッキーづくりを2回しかおこなわなければ……だべよ

りこ

そっか。クッキーをつくる回数がおおいほど、Bさんの方が効率こうりつがいいってことが分かるね

あ、それにBさんは、小麦粉の量を調整ちょうせいしたりして、より美味おいしくつくろうとしてる!

山田

そうなんだべ。Aさんはクッキー作ることばかり考えてしまって、工夫くふうすることを忘れてしまっているべよ

りこ

でも、これとプログラミング、なんの関係があるの?

山田

ふっふっふ。Bさんは作り方をメモしたり、カップに線を引いたり……この作業のおかげで、Bさんはちょっと味に工夫をしてみたり、効率的こうりつてきにクッキーをつくったりできたんだべ
そしてゲームエンジンをつくる、というのは、その作業と同じなんだべ

りこ

分かった。クッキーをつくるための道具どうぐをつくるみたいに、ゲームを作るための道具をつくるのね!

そしてゲームに工夫を加えたいとき、ゲームエンジンのほうを工夫していけば……ゲームをつくればつくるほど、クオリティが上がっていく!

山田

そういうことだべ!

ゲームエンジンは、ゲームをつくりやすくするためのプログラムです。
よく使われるゲームエンジンには、

  • Unity
  • Unreal Engine

などがあります。

上のゲームエンジンはツールとなっていますが、ライブラリのものもあります。

  • melon.js
  • phina.js
  • enchant.js

などがあります。

これらを使えば、ゲーム開発がやりやすくなりますが、今回はゲームエンジンも自作していきます。

また、今回から作成するのは、ライブラリの方です。

では、次のページからは、実際にゲームエンジンを作っていきます。

このシリーズの一覧はこちら

  1. 小学生からのプログラミング入門。プログラミングってなぁに?
  2. Scratchの使い方と、ゲーム作りの基礎知識を学ぼう! 小学生からのプログラミング入門
  3. Scratchでじゃんけんゲームを作ろう! 小学生からのプログラミング入門
  4. Scratchでシューティングゲームを作ろう! 小学生からのプログラミング入門
  5. Scratchでピアノ鍵盤を作って音を鳴らそう! 小学生からのプログラミング入門
  6. テキストエディタ(Visual Studio Code)をインストールしてみよう! 小学生からのプログラミング入門
  7. Visual Studio Codeを日本語化してみよう! 小学生からのプログラミング入門
  8. JavaScriptでおみくじを作ろう! 小学生からのプログラミング入門
  9. JavaScriptで今月の残り日数を計算してみよう! 小学生からのプログラミング入門
  10. JavaScriptで画像を表示してみよう! 小学生からのプログラミング入門
  11. JavaScriptで画像を移動してみよう! 小学生からのプログラミング入門
  12. 【JavaScript】キー入力でキャラを動かしてみよう! 小学生からのプログラミング入門
  13. 【JavaScript】ファイルを分けて管理してみよう! 小学生からのプログラミング入門
  14. 【JavaScript】オブジェクトを使ってみよう! 小学生からのプログラミング入門
  15. 【JavaScript】ゲームのメインループを作ってみよう! 小学生からのプログラミング入門
  16. 【JavaScript】キャラを決まった間隔ずつ動かす! 小学生からのプログラミング入門
  17. HTML5とCanvasを使ってみよう! 小学生からのプログラミング入門
  18. 【JavaScript】迷路やRPGで使えるマップを作ってみよう! 小学生からのプログラミング入門
  19. 【JavaScript】マップでキャラを動かせるようにしよう! 小学生からのプログラミング入門
  20. 【JavaScript】クラスの概念をしっかりと理解しよう! 小学生からのプログラミング入門
  21. 【JavaScript】プログラム全体をクラスを使って作ってみよう! 小学生からのプログラミング入門
  22. 【JavaScript】文字を表示するクラスを作ってみよう! 小学生からのプログラミング入門
  23. 【JavaScript】改行と一文字ずつ画面に表示する方法! 小学生からのプログラミング入門
  24. 【JavaScript】ノベルゲーム風にキー入力で文字を切り替える方法! 小学生からのプログラミング入門
  25. JavaScriptでRPGを作ろう!スマホにも対応したゲームの作り方
  26. webpackを使ってゲームエンジンを作ろう!(JSライブラリの作り方)
  27. WindowsにPythonをインストールしてみよう!小学生からのPython入門
  28. MacにPythonをインストールしてみよう!小学生からのPython入門
  29. Pythonでじゃんけんゲームを作ってみよう!小学生からのPython入門
  30. Pythonのtkinterを使って、ウィンドウを表示してみよう!
  31. Pythonのtkinterで、画像つきのおみくじゲームを作ろう!

スポンサードリンク

関連コンテンツ

オススメ記事

gulp

gulp4完全攻略ガイド。インストールから使い方まで徹底解説!

幸せそうな人を見ると、転べって思います。@It_is_Rです。 Webページを制作するとき、sassをcssに変換して使用することが多いと思います。 今回はgulp4の使い方を、インストールか

WordPressのテーマを自作してみよう。テーマ開発の方法を徹底解説!

WordPressテーマの自作方法を紹介していきます。 今回はテーマ作成における知識や、ツール、ファイル構成、実際の作り方などを書いていきます。 WordPressのテーマを自作する上

【 Bootstrap 4 】全体的な機能の解説と、Alert の使い方。

頭がお花畑の@It_is_Rです。 今回からは Bootstrap 4 の使い方について、詳しく書いていこうと思います。 このシリーズの、前回の記事はこちらです。 Bootstrap 4 を読み込む

【初心者向けJavaScrip入門】変数を使いこなすための、かなり詳しい解説

変数は、数値や文字列などのデータを入れておける箱です。プログラミングをはじめて、最初のほうで覚えるものですが、変数は意外と奥が深いものです。 そこで今回は、JavaScriptにおける変数の使

Markdown記法一覧。最速で文章を書くには、これを覚えるべし!

Markdownは文章を記述するための言語です。サイト上で文章を作るとき、タグを使うことで、その文章に様々な意味を持たせます。 しかし、直接タグを打ち込むのは大変ですし、エディタの機能を使おう

ショートコード

BEMによるCSS設計の方法を解説。命名規則から使い方まで。

完璧を求めすぎて、平均以下な@It_is_Rです。 CSSは比較的簡単なものですが、CSS設計をしっかりしておかなければ、余分なコードが多くなったり、後から修正が大変になったりしてこまることにな

Pythonでじゃんけんゲームを作ってみよう!小学生からのPython入門

さて、今日《きょう》もプログラミングを学《まな》んでいきましょう! 今回《こんかい》はPython《パイソン》を使《つか》ったゲーム作りに挑戦《ちょうせん》してみたいと思います。作るゲームはじ

【Unity】開発したiOSゲームをiPhoneで実機テストする方法

こんにちは。現在、最新ゲーム熱意製作中の@It_is_Rです。個人での開発はとても大変で、時間がかかってしまっていますが、すこしずつ形にしていっています。 さて、今回はUnityで開発したiO

リセットCSS は何を使う? おすすめ8選(コピペも可能!)

Web開発でブラウザごとの表示の違いをリセットしてくれる リセットCSS というものがあります。 しかし、何を使っていいのかと感じている人もいると思います。 今回はこの リセットCSS につい

FC2でブログを始めよう!誰でも簡単にできるブログの作り方

FC2ブログは、FC2が運営する無料でブログを開設できるサービスです。(有料版もあります) また、FC2のサービスには、動画、ライブ配信、アフィリエイト、小説など、様々なものがあります。 今回

25件のコメント “JavaScriptでRPGを作ろう!スマホにも対応したゲームの作り方

  1. お世話になっております。いつもかなり勉強させて頂いております。プログラムの内容に関して質問させて頂きたく思います。party.jsの内容に関しまして、ソース文を写させていただき実行してみましたら、リコちゃんとアルくんが左右移動の時は行ったり来たりして、上下移動の際は斜めに荒ぶった動きをしてしまいました。ご経験お有りでしょうか?写し間違いがないか何度も確認してみたのですが無さそうで…もしアドバイスをいただければ幸いです!

    1. >Mura muraさん
      こんにちわ。コメントありがとうございます。

      その現象についてですが、私も作る途中で何度か経験しました。
      いろんな原因があると思うので確実な答えは出せないのですが、いまのところ思い浮かぶ原因として、それぞれのキャラクターが32で割り切れない座標にいるのかもしれません。
      タイルひとつが32pxなので、ずれてしまうと、うまくマップ上の位置(上から、または左から、何番目のタイルにいるのか)を出せなくなってしまいます。

      以下を、main.jsの、scene.onenterframe = () => { }のなかの、if ( ( tilemap.x - TILE_SIZE/2 ) % TILE_SIZE === 0 && ( tilemap.y - TILE_SIZE/2 ) % TILE_SIZE === 0 ) { }のなかにコピペして、それぞれのキャラクターが、その数のタイルの位置にいるのかを確かめてみてください。(タイルの枚数は、0から数える必要があります)

      console.log( `山田(X=${yamada.mapX}, Y=${yamada.mapY}) りこ(X=${rico.mapX}, Y=${rico.mapY}) アル(X=${aru.mapX}, Y=${aru.mapY})` );

      この値が小数になっていたりした場合は、それぞれのキャラクターの初期位置が32で割り切れる場所にいない、または移動したときに32pxずつ動いていない、という原因が考えられます。
      また、ここからほかの原因を探ることができるかもしれません。

      一度お試しください。

      1. 早速のご返信ありがとうございます。ご連絡頂きました内容を実行しましたところ、下方向に2歩移動しました結果は①(スタート地点)山田(X=1,Y=2)りこ(X=3,Y=2)アル(X=3,Y=3)②山田(X=1,Y=3)りこ(X=1,Y=1)アル(X=3,Y=0)③山田(X=1,Y=4)りこ(X=1,Y=4)アル(X=1,Y=1)  となりまして小数点にはなっておりませんでした。他に怪しい箇所が無いか再度確認してみたいと思います。他にアドバイスいただけましたら幸いです!

        1. >Mura muraさん
          こんにちわ。
          こちらでいろいろと試してみたのですが、全員、または、後ろをついてくるキャラクターの移動速度(後ろに.vx, .vyとついているもの)を2倍してみたところ、Mura muraさんの作ったものと同じ結果が得られました。

          party.jsには、後ろをついてくるキャラクターの移動速度を設定するメソッド(setMemberVelocity)がありますので、その辺りでミスをしてしまっている可能性が高いかな、と思います。
          party.jsのどこかで、this.member[i].vxやthis.member[i].vyを2倍してしまっているようなところはありませんか?

          もしかすると、原因は違うところにあるのかもしれませんが、私の方ではこのぐらいしか分かりませんでした。

          またなにかありましたら、お気軽にお訊ねください。

          1. 現象の再現までご確認いただき誠に有難うございます!party.jsのソース文を再度確認してみたのですが2倍をしてそうな箇所が見つからず色々悩んだ後にvx,vy
            の数式箇所全てを÷2しましたら正常に動作しました。ありがとうございます!(やはり他の箇所で2倍してしまっている箇所があるということですよね…探してみたいと思います!)今後は色々ページにて紹介して頂いております内容を応用させて頂いてRPGっぽく発展させていきたいと思います!

          2. >Mura muraさん
            まずは、ぶじ正常に動いたようで、よかったです。

            プログラミングは、エラーが出ていないのにうまく動かないときが、一番大変ですよね。
            移動速度2倍のことはいったん忘れて、ぜひゲームの発展を楽しんでください。
            そしてその過程で、ふと原因が分かるかもしれません。

            私も、よりよい記事を書けるように精進していきます。お互いに頑張りましょう。

            また遊びにきてください。

  2. はじめまして。
    質問です
    マップなどを使わさせていただいて、RPGを作っているのですが、家の中と外を移動するために
    マップを2つ作って、この2つのマップを移動するためにはどうしたらいいですか?
    よろしくを願いします

    1. >sgruさん
      コメントありがとうございます。

      2つのマップを移動する方法ですが、最もかんたんなのは、tilemap.dataの値を書き換えてしまう方法だと思います。
      記事の一番最後のページにある、ソースのまとめをご覧ください。

      「js/map.js」で、マップを作成していますが、ここに新たな変数を作って、家の中のマップを作成します。ここではmyHouseMapという変数にマップを作ったとします。

      「js/main.js」の67行目で、代入する変数を、さきほど作成した家の中のマップの変数(myHouseMap)に変更してみて、マップが変わるかどうかテストしてみてください。

      また、同じく「js/main.js」の164〜188行目では、キャラクターがゴールしたときのイベントを作成しています。
      このゴールのように、特定の場所に来たときになにかを起こす、といったふうに、出入り口に来たときにマップを切り替えるプログラムを作成します。つまりここでは、このゴールのタイルが出入り口の扉、ということにします。
      といっても、ゴールのタイルに重なったときにマップを切り替えるだけなので、以下のようになります。

      //山田先生のタイルがゴールのタイルと重なっているとき、イベントを発生させる
      if ( yamada.isOverlapped( goal ) ) {
      tilemap.data = myHouseMap;
      }

      これで、マップを切り替えることができます。
      あとは、双方から移動可能にしたり、エフェクトを入れてみたりなど、お好みにアレンジしてください。

      参考になれば幸いです。

      1. すみませんが、もう一つお願いします。
        マップを移動したときにX座標とY座標がそのままになってしまうので、
        X座標とY座標を変えてキャラクターを移動させる方法も教えて下さい。
        お願いします。

        1. キャラクターの移動はできました。
          すみませんが、また問題が起きてしまったのでお願いします。
          下のようにマップを変数で変更するときにはどうしたら良いでしょうか?
          var map = [
          [ 1, 1, 1, 1, m1 , 1],
          [ 1, 1, 1, 1, m1 , 1],
          [ 1, 1, 1, 1, m1 , 1],
          [ 1, 1, 1, 1, m1 , 1],
          [ 1, 1, 1, 1, m1 , 1]
          ];
          var m1 = 1;
          m1 = 3;
          マップの中に「m1」という変数を入れて初めは「1」だが、「3」にするということをしたいです。
          しかし、普通にやってしまうと、マップがそのままで、変更後が読み込めません。
          よろしくおねがいします。

          1. >sgruさん
            返信が遅くなってしまい、申し訳ありません。
            キャラクターの移動がうまくいったようで、私も嬉しいです。

            今回のマップの一部分だけを変更したい場合ですが、いちばん手軽に試せるのは、変更前と変更後のマップふたつ作りそれを切り替える、という方法だと思います。

            const map = [
            	[ 1, 1, 1, 1, 1, 1],
            	[ 1, 1, 1, 1, 1, 1],
            	[ 1, 1, 1, 1, 1, 1],
            	[ 1, 1, 1, 1, 1, 1],
            	[ 1, 1, 1, 1, 1, 1]
            ];
            
            const map2 = [
            	[ 1, 1, 1, 1, 3, 1],
            	[ 1, 1, 1, 1, 3, 1],
            	[ 1, 1, 1, 1, 3, 1],
            	[ 1, 1, 1, 1, 3, 1],
            	[ 1, 1, 1, 1, 3, 1]
            ];
            

            また、マップを生成する関数をつくる方法もあります。

            //マップを生成する関数
            const createMap = ( tile = 1 ) => {
            	//マップの作成
            	const _map = [
            		[ 1, 1, 1, 1, tile, 1],
            		[ 1, 1, 1, 1, tile, 1],
            		[ 1, 1, 1, 1, tile, 1],
            		[ 1, 1, 1, 1, tile, 1],
            		[ 1, 1, 1, 1, tile, 1]
            	];
            	
            	return _map;
            }
            
            //マップの作成
            tilemap.data = createMap();
            
            //マップを切り替えたいとき
            if ( 条件 ) {
            	tilemap.data = createMap( 3 );
            }
            

            上の関数は、サンプルとして作ったかんたんなものですので、実際にゲームに組み込むならば、さまざまなマップに対応できるように工夫する必要があります。
            お好みの方法をお試しください。

            参考になれば幸いです。

          2. 何度も教えてくださりありがとうございました。
            とっても役に立ちました。

  3. いつも参考にさせてもらっております。ありがとうございます。
    タイトル画面でスペースキーを押すと、Access to internal resource at ‘略’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.なるエラーが発生し画面が切り替わりません。対処法を教えていただけると幸いです。

    1. >てかりんさん
      コメントありがとうございます。

      まず、私ももう一度、記事にある最終的なソースをWindowsとMacで試してみたのですが、私の環境ではエラーはなく、正常に動かすことができました。

      今回のエラーでは、CORS policyによってブロックされた、となっていますので、Chromeがセキュリティ対策として機能を制限してしまっているのだと思います。
      正直なところあまり自信はないのですが、ローカルサーバを立てて実行すると、うまくいくかもしれません。

      ただ、私の環境では、ローカルサーバを使わなくても、WindowsとMacで正常に動作しており、どうしてそのようなエラーが表示されてしまっているのか、大変申し訳ないのですが、分からないです。

      原因は、環境の違いか、ソースの違いのどちらかだと思います。

      もし、記事の内容の通りに進めていただけているのであれば、index.htmlファイルを確認してみてください。必要のないタグを間違えて入れてしまっている可能性があります。
      私の環境では、<link rel="manifest" … >といったタグを入れてみたところ、同じエラーが発生しました。

      もし、オンライン上の開発環境を使っているのであれば、一度ローカルでお試しください。
      ローカルで開発しているのであれば、この記事の最後のページに、すべてのソースをまとめてありますので、参考にしてください。このとき、画像や音声、ソースファイルの、ディレクトリにご注意ください。

      お役に立てたか分かりませんが、またよろしくお願いいたします。

      1. htmlファイルのというタグを消したところ想定通り動くようになりました。ありがとうございます。

        1. >てかりんさん
          無事解決したようで、私も嬉しいです。
          またなにかあれば、お気軽にコメントください。

  4. こんばんは。はじめまして。
    参考にさせてもらっているのですが、
    const yamada = new Sprite( ‘img/yamada.png’ );

    を打ち込むと黒かった画面が真っ白になってしまい、画像どころかなにもでません。
    エラーはバリデーターの方でチェックしましたが、エラーなしでした。
    色々考えたり試したりしたのですが解決しませんでしたのでこちらに失礼します。ぜひよろしくお願いします。

    1. >はなさん

      はじめまして。
      私の記事を読んでいただき、ありがとうございます。

      黒かった画面が真っ白になった、とのことですが、これはなにかミスがあったときによく起こります。
      しかしミスがあれば、おそらくエラーが表示されるはずだと思うのです。

      Chromeの画面を右クリックして「検証」で表示された画面から、「Console」を選択したときも、なにも表示されていませんか?

      また、「const yamada = new Sprite( 'img/yamada.png' );」と打ち込むとエラーになるということは、sprite.jsがindex.htmlからうまく読み込めていないか、sprite.jsのどこかに入力ミスがあるかの、どちらかかな、と思います。

      参考になれば幸いです。
      またなにかあれば、お気軽にご連絡ください。

      1. お返事ありがとうございます。
        とても丁寧で初心者の私でも助かります。
        IO Error: HTTP resource not retrievable. The HTTP status from the remote server was: 401.
        とバリデーターで出てしまったのですが、gitpodの環境ではこちらのプログラミングはできないものなのでしょうか?
        よろしくお願いします。

        1. >はなさん

          コメントありがとうございます。
          私もgitpodで試してみました。本当に画像の表示の部分で真っ白になり、エラーも表示されませんね。
          私はgitpodを使ったことがなかったので、その環境でできるのかどうか、方法があるのかは分からないですが、今回のゲーム開発においては、gitpodの環境はちょっと使いにくいかな、と思います。

          私ははなさんがローカルで開発しているものだとばかり思っていたので、さきほどは間違った回答をしてしまいました。すみません。

          JavaScriptは、環境やブラウザによって、うまく動いたり、動かなかったりするんですよ。よくオンラインゲームで推奨ブラウザや推奨OSなどいったことが書いてあるのはそのためです。
          できれば、多くの方が使っている環境やブラウザで作ったほうがいいかな、と思います。

          もしgitpodの環境で、どうしてもうまくいかないようでしたら、一度ローカルで試してみるのがいいと思います。
          開発用にフォルダを作って、index.htmlやjsファイルを作成し、Chromeで確認する、一番シンプルな方法です。
          今回のような、ライブラリ等を使わないJavaScriptでの開発であれば、特別なものを用意する必要もないですし、もしそれでうまくいけば、環境がエラーの原因だったと分かります。

          あと、その方法でしたら、私もお答えできると思います。

  5. 初めまして!
    いつもとてもわかりやすい記事ありがとうございます。
    JavaScriptの勉強になり、とても助かっています。

    下記をもしよろしければ教えていただくことは可能でしょうか?

    【質問内容】
    こちらのgame.jsの48行目のfor文の箇所(「ゲームに登場する全てのもの(オブジェクト)の数だけ繰り返す」)のところでエラーが出てしまい、山田先生の画像が表示されません。

    【調べた内容】
    this.objs[i].update(this.canvas);のコードでUncaught TypeError: this.objs[i].update is not a functionとコンソールに表示されています。
    調べてみたところ、this.objs[i]が関数として呼び出されていないのではないかと考えました。

    for文の中のthis.objs[i].update(this.canvas);の上でconsole.log(this.objs[i])を試したところ、下記が取得できました。
    Sprite {img: img, y: 0, x: 0}this.objs[i].update(this.canvas);

    試しにこちらのサイトのコードを全てコピーして貼り付けてみましたが、エラーは変わっておりません。
    Gameクラス内のthis.objs = [];の場所なども関係しているのかと思い、場所を変えるなどしましたが、解決できませんでした。

    JavaScriptについてしっかり理解しておらず恐縮ですが、こちらのエラー原因のヒントなどいただけますと幸いです。
    よろしくお願いいたします。

    1. >るるさん

      はじめまして。
      コメントありがとうございます。
      私の記事を参考にしていただけているようで、とても嬉しいです。

      うまくプログラムが動かない、ということで、慌てて私もその部分のソースをコピーして、もう一度試してみました。
      私の環境ではちゃんと動作しているようです。

      まず、「Uncaught TypeError: this.objs[i].update is not a function」というエラーですが、これは「this.objs[i].updateは関数じゃないよ」というものです。
      ですので、「this.objs[i]が関数として呼び出されていない」というよりも、「this.objs[i].updateを関数として呼び出せない」という意味になります。

      this.objs[i].update」というのは、sprite.jsにある「update( canvas ) { 〜省略〜 }」の部分です。
      つまり「this.objs[i].update( this.canvas );」というのは、今の時点ではSpriteクラスのupdateメソッドを呼び出していることになります。これは、this.objsの中にSpriteが入っているからです。
      るるさんが「console.log(this.objs[i]);」を試したときSpriteを取得できた、ということは、ちゃんとthis.objsSpriteが入っているということです。

      さて、そうなると、エラーの原因は「Spriteクラスのupdateを関数として呼び出せないよ」ということになります。
      Spriteクラスはsprite.jsファイルに書かれているので、そのなかのupdateメソッドの辺りでなにかミスをしてしまっているのではないか、と思います。

      お役に立てれば幸いです。

      1. お忙しい中ご返信ありがとうございます!
        エラーの意味や処理の流れまで解説していただいて本当にありがたいです。
        おかげさまで理解が深まりました。

        大変お恥ずかしいのですが、sprite.jsのupdateがudpateになっていました…
        ちゃんとエラーも出ていたのに、完全に確認不足でした。
        お手数をお掛けしてすみません。今後はちゃんと確認するようにします!
        難しくてなかなか理解が進んでいないのですが、少しずつでも完成に近づけるように頑張ります!
        ありがとうございました!

        1. >るるさん

          無事解決できたとのこと、私も嬉しいです。
          プログラミングのエラーを直すのはとても大変ですが、うまく動いたときの喜びはこの上ないですよね。

          私も、もっと良い記事が書けるよう、努力していきたいと思います。
          ぜひ、また遊びにきてください。

コメントを残す(コメントは承認後に反映されます)

メールアドレスが公開されることはありません。