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

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

山田

最後さいごに、これまでつくったプログラムをすべて、ここにのせているべ。確認かくにんなどに使って欲しいべ!

目次
  1. 今回のプログラムのまとめ

今回のプログラムのまとめ

最後に、今回作ったプログラムのすべてです。
index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
	<title>くろねこラビリンス</title>
	<style>
		* {
			padding: 0;
			margin: 0;
		}
		canvas {
			display: block;
		}
	</style>
</head>
<body>
	<script src="js/engine/scene.js"></script>
	<script src="js/engine/sound.js"></script>
	<script src="js/engine/sprite.js"></script>
	<script src="js/engine/dpad.js"></script>
	<script src="js/engine/party.js"></script>
	<script src="js/engine/text.js"></script>
	<script src="js/engine/tile.js"></script>
	<script src="js/engine/charactertile.js"></script>
	<script src="js/engine/tilemap.js"></script>
	<script src="js/engine/game.js"></script>
	<script src="js/map.js"></script>
	<script src="js/main.js"></script>
</body>
</html>

js/map.js

'use strict'

//マップの作成
const map = [
	[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
	[11,10,10,10,11,11,10,10,10,10,10,10,10,10,10,11,10,10,10,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8],
	[11, 5, 5, 5,11,11, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 5, 5,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8],
	[11, 5, 4, 4, 9,10, 5, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4, 4,11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8],
	[11, 5, 4, 4, 5, 5, 5, 4,11,11,11,11,11, 4, 4,11, 5,11,11,11, 5, 4,11,11,11,11,11,11,11,11,11,11, 4, 4,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 1, 8, 1, 8, 1, 8, 6, 6, 6, 6, 6, 6, 8, 8, 1, 8, 8, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8],
	[11, 5, 4, 4, 4, 4, 4, 4,11,10,10,10,10, 5, 4,11, 5, 9,10,11, 5, 4,11,10,10,10,10,10,10,10,10,10, 5, 4,11, 5, 4,11,10,10,10,10,10,11,10,10,10,10,10,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 1, 1, 8, 8, 8, 6, 6, 6, 8, 8, 1, 8],
	[11, 5, 4, 4,11,11,11,11,11, 5, 5, 5, 5, 5, 4,11, 5, 5, 5,11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4,11, 5, 5, 5, 5, 5,11, 5, 5, 5, 5, 5,11, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 8, 8, 8, 1, 7, 7, 7, 7, 7, 1, 1, 8, 8, 8, 1, 1, 1, 8, 8, 1, 8],
	[11, 5, 4,11,11,11,11,11,11, 5, 4, 4, 4, 4, 4,11, 5, 4, 4,11, 5, 4,11, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5, 4, 4, 4, 4,11, 5, 4, 4, 4, 4,11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 1, 8, 1, 8, 1, 8, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11,10,10,10,10,11, 5, 4,11,11,11,11,11, 5, 4, 4,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 4, 4,11, 5, 4,11, 4, 4,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11, 5, 5, 5, 5,11, 5, 4,11,11,11,10,10, 5, 4, 4,11, 5, 4,11,10,10,10,10,10,11,10,10,10,10,10,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 1, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11, 5, 4, 4, 4,11, 5, 4, 9,10,11, 5, 5, 5, 4, 4, 9, 5, 4,11, 5, 5, 5, 5, 5,11, 5, 5, 5, 5, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 1, 8, 1, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11, 5,11, 4, 4,11, 5, 4, 5, 5,11, 5, 4, 4, 4, 4, 5, 5, 4,11, 5, 4,11, 4, 4,11, 5, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11, 5,11, 5, 4,11, 5, 4, 4, 4,11, 5,11, 5,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11, 5,11, 5, 4,11,11,11,11, 5,11, 5,11, 5, 9,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11, 5,11, 5, 4, 9,10,10,11, 5,11, 5,11, 5, 5,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 1, 6, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11, 5,11, 5, 4, 5, 5, 5,11, 5,11, 5,11, 5, 4,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 8, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8],
	[11, 5, 4, 9, 5,11, 5, 4,11,11, 5,11, 5,11, 5,11, 5, 4,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 6, 6, 8, 1, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 1, 8, 8, 8, 1, 6, 6, 1, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 1, 6, 6, 1, 8],
	[11, 5, 4, 4, 5,11, 5, 4, 9,11, 5,11, 5,11, 5,11, 5, 4,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 1, 7, 8, 8, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 1, 1, 1, 1, 8],
	[11,11,11,11,11,11,11, 4, 4,11, 5,11, 5,11, 5,11, 5, 4,11,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 8, 1, 8],
	[11,10,10,10,10,10,10, 5, 4,11, 5,11, 5,11, 5,11, 5, 4,11, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 6, 6, 6, 6, 6, 6, 6, 8, 1, 6, 6, 6, 6, 6, 8, 1, 8],
	[11, 5, 5, 5, 5, 5, 5, 5, 4,11, 5,11, 5,11, 5,11, 5, 4,11, 5, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 8, 1, 8],
	[11,11,11,11,11,11,11,11,11,11, 5,11, 5,11, 5,11, 5, 4,11, 5, 4,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 6, 6, 6, 6, 6, 6, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8],
	[11,10,10,10,10,10,10,10,10,10, 5,11, 5, 9, 5,11, 5, 4,11, 5, 4,11,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 1, 8],
	[11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 5, 5,11, 5, 4,11, 5, 4,11, 5, 4,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 6, 6, 6, 6, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 1, 8],
	[11, 5,11,11,11,11,11,11,11,11, 5,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 9, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 6, 6, 6, 6, 6, 1, 6, 6, 8, 1, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 1, 8],
	[11, 5,11,10,10,10,10,10,10,11, 5, 9,10,11,10,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4, 9, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 5, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 6, 6, 6, 8, 8, 1, 8, 8, 8, 8, 1, 8],
	[11, 5,11, 5, 5, 5, 5, 5, 5,11, 5, 5, 5,11, 5, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4, 5, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4, 4, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 1, 8, 1, 1, 1, 1, 8, 8, 1, 8, 8, 8, 8, 1, 8],
	[11, 5,11, 5,11,11,11,11,11,11, 5, 4, 4,11, 5, 4, 4, 4,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 4, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 6, 6, 6, 6, 6, 1, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 1, 8],
	[11, 5, 9, 5,11,10,10,10,10,10, 5, 4,11,11, 5, 4,11,11,11, 5, 4, 9,10,10,10,10,10,10,10,10,10,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 6, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 1, 8, 8, 1, 6, 6, 6, 8, 1, 8],
	[11, 5, 5, 5,11, 5, 5, 5, 5, 5, 5, 4,11,10, 5, 4, 9,10,11,11, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 1, 1, 1, 8, 1, 8],
	[11,11,11,11,11, 5, 4, 4, 4, 4, 4, 4,11, 5, 5, 4, 5, 5, 9,11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8],
	[11,10,10,10,10, 5, 4,11,11,11,11,11,11,11,11,11, 5, 4, 5,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 6, 6, 6, 6, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 1, 8, 1, 8],
	[11, 5, 5, 5, 5, 5, 4,10,10,10,10,10,10,10,10,11,11, 5, 4,11, 5, 4,11,10,10,10,10,10,10,10,10,10,10,10,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8],
	[11, 5, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,10,11, 5, 4,11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 8],
	[11, 5, 4,11,11, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,11, 5,11,11, 5, 4,11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 6, 6, 6, 1, 8, 1, 8, 1, 8],
	[11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11, 5,11, 5,11,11, 5, 4,11, 5, 4,11,11,11,11,11,11,11,11, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 8, 1, 1, 1, 1, 8, 1, 8, 1, 8],
	[11, 5, 4, 9,10,10,10,10,10,10,10,10,10,10,11, 5,11, 5, 9,11, 5, 4,11, 5, 4,11,10,10,10,10,10,10,10, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8],
	[11, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5,11, 5, 5,11, 5, 4,11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 1, 8, 1, 8],
	[11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 6, 1, 6, 1, 6, 6, 6, 6, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8],
	[11,11,11,11,11,11,11,11,11,11,11,11,11, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11,10,10,10,10,10,10,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 8, 8, 8, 1, 8, 1, 8],
	[11,10,10,10,10,10,10,10,10,10,10,10,10, 5,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 1, 8, 1, 8],
	[11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11, 5, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 8, 1, 8, 1, 8, 1, 6, 6, 6, 6, 8, 1, 8, 1, 8],
	[11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11, 5, 4,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8],
	[11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11,10, 5, 4,11, 5, 4,11, 5, 4,11, 5,11, 5, 4,11,10,10,10,10,10,10,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 8, 8],
	[11, 5, 4,11,10,10,10,10,10,10,10,10,10,10,10,10, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5,11, 5, 4,11, 5, 5, 5, 5, 5, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 6, 8, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 6, 6, 8],
	[11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4,11, 5, 4,11, 5, 4,11, 5,11, 5, 4,11, 5, 4,11,11, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8, 1, 6, 6, 6, 6, 6, 8, 8, 1, 8, 1, 8, 1, 8, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 1, 1, 8],
	[11, 5, 4,11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5,11, 5, 4,11, 5, 4,11,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 2, 2, 1, 1, 1, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 1, 8, 1, 6, 6, 6, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 8, 8, 1, 8],
	[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 2, 2, 1, 1, 1, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 6, 8, 1, 8],
	[11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,11, 5, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 2, 2, 2, 1, 1, 8, 8, 6, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 6, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 6, 1, 8, 1, 8],
	[11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 9, 2, 2, 2, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 6, 6, 6, 6, 6, 6, 6, 1, 8, 1, 8, 1, 8, 1, 8, 1, 1, 1, 8, 1, 8],
	[11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 5, 4,11, 5, 4,11,11,11,11, 5, 4, 5, 2, 2, 2, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 1, 8],
	[11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4,11, 5, 4, 9,10,10,11, 5, 4, 4, 2, 2, 2, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 6, 6, 6, 6, 8, 1, 8],
	[11, 5, 4, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4,11, 5, 4, 5, 5, 5,11,11,11,11, 2, 2, 2, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 6, 6, 1, 8, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 1, 8, 1, 8, 1, 1, 1, 1, 1, 8, 1, 8],
	[11, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4,11,11, 5, 4, 4, 4,11,10,10,11, 2, 2, 2, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 1, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 1, 8, 1, 8],
	[11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4, 9,11,11,11, 4, 4,11, 5, 5,11, 2, 2, 2, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 1, 1, 1, 8, 1, 8, 1, 6, 6, 8, 8, 8, 1, 8, 1, 8],
	[11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4, 5, 9,10,11, 5, 4,11, 5, 4,11, 2, 2, 2, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 1, 1, 8, 8, 8, 1, 8, 1, 8],
	[11, 5, 4,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5,11, 5, 4, 9, 5, 4,11, 5, 4,11,11,11,11, 5, 5, 5,11, 5, 4,11, 5, 4,11, 2, 2, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 1, 8, 8, 6, 6, 6, 6, 8, 1, 8, 8, 1, 8, 8, 8, 8, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 4, 5, 5, 4,11, 5, 4,11,10,10,11, 5, 4, 4,11, 5, 4,11, 5, 4,11, 2, 2, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 1, 1, 1, 8, 1, 8, 8, 1, 8, 6, 6, 6, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 5, 4, 4, 4,11, 5, 4,11, 5, 5,11, 5, 4, 4,11, 5, 4,11, 5, 4,11, 2, 2, 1, 1, 8, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 6, 1, 8, 1, 1, 1, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4, 4, 4,11, 5, 4,11, 5, 4,11,11,11, 5,11, 5, 4,11, 5, 4,11, 2, 1, 1, 1, 8, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11, 5, 4, 4, 4,11, 5, 4,11, 5, 4, 9,11,10, 5,11, 5, 4,11, 5, 4,11, 2, 1, 1, 8, 8, 6, 6, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 4,11,11,11, 5, 4,11,11, 5, 5,11, 5, 5,11, 5, 4,11, 5, 4,11, 1, 1, 1, 8, 8, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11,11,11, 5, 4, 9,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 6, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11, 5, 4,11, 5, 4,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 4,11, 5, 4,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 6, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 6, 6, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11,10,10,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 8, 8, 8, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 1, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 6, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11,10,10,10,10,10,10,10,10,10,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 6, 6, 6, 6, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 6, 6, 6, 6, 6, 6, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 1, 1, 8, 1, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11,11,11,11,11,11,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 6, 6, 1, 8, 8, 1, 8, 1, 8, 1, 8, 8, 1, 6, 6, 6, 6, 6, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11,10,10,10,10,10,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 8, 1, 8, 1, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 1, 1, 1, 1, 8, 8, 1, 8, 1, 8, 1, 6, 8, 1, 1, 1, 1, 1, 2, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11, 5, 5, 5, 5, 5,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 1, 1, 8, 8, 8, 8, 8, 8, 2, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5,11,11, 4,11,11, 5,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 6, 6, 2, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 9,10, 4, 9,11, 5,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 1, 6, 6, 6, 6, 6, 6, 8, 1, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 1, 6, 6, 6, 6, 6, 6, 6, 1, 1, 2, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 5, 5, 4, 5,11, 5,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11,11,11,11,11,11,11, 5,11, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 2, 2, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 9,10,10,10,10,10,10, 5,11, 5,11, 5, 4,11, 5, 4, 9, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 9, 5, 4,11, 1, 1, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 1, 8, 8, 8, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 2, 2, 2, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5,11, 5, 4,11, 5, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 5, 5, 4,11, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 8, 8, 8, 1, 8, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 6, 6, 2, 2, 2, 0, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11, 5,11, 5, 4,11, 5, 4,11, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4, 9, 5, 4,11,11,11,11, 4, 4,11, 1, 1, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 8, 1, 6, 6, 6, 8, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 6, 1, 1, 2, 2, 2, 0, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4, 9,10,10,10,10,10,10,10,10,10,10,10, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 5, 5, 4, 9,10,10,11, 4, 4,11, 1, 1, 8, 1, 8, 1, 8, 6, 6, 8, 6, 6, 6, 1, 8, 8, 8, 8, 1, 1, 1, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 6, 1, 1, 2, 2, 2, 2, 2, 8],
	[11, 5, 4,11, 5, 4,11, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4, 4, 4, 5, 5, 5,11,11,11,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 8, 8, 8, 6, 1, 1, 2, 2, 2, 0, 0, 2, 8],
	[11, 5, 4,11, 5, 4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4, 4, 4, 4, 4, 4,11,10,10,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 1, 1, 1, 8, 8, 6, 6, 8, 6, 6, 6, 6, 6, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 6, 1, 1, 2, 2, 2, 2, 0, 0, 2, 8],
	[11, 5, 4,11, 5, 4, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 4, 4,11, 4, 4,11, 5, 5,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 8, 8, 8, 1, 1, 8, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 1, 1, 1, 2, 2, 2, 0, 0, 0, 2, 8],
	[11, 5, 4,11, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 8, 8, 8, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 1, 6, 6, 6, 6, 6, 8, 1, 8, 8, 8, 8, 6, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 8],
	[11, 5, 4,11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 6, 6, 6, 1, 1, 6, 6, 6, 6, 6, 6, 6, 8, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 8, 8, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 2, 8],
	[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 6, 2, 2, 2, 2, 0, 2, 0, 2, 0, 0, 2, 8],
	[11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 8, 6, 6, 6, 6, 1, 8, 8, 8, 1, 1, 1, 2, 2, 0, 2, 0, 2, 0, 0, 2, 8],
	[11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 8, 8, 1, 1, 1, 1, 1, 8, 8, 6, 1, 1, 2, 2, 0, 0, 2, 0, 2, 0, 0, 2, 8],
	[11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 1, 1, 2, 2, 0, 0, 0, 2, 0, 2, 0, 0, 2, 8],
	[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 6, 6, 6, 6, 6, 1, 8, 8, 8, 8, 6, 1, 2, 2, 2, 0, 0, 0, 2, 0, 2, 0, 0, 2, 8],
	[11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 6, 1, 1, 2, 2, 2, 0, 0, 0, 2, 0, 2, 0, 0, 2, 8],
	[11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4, 9, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 2, 2, 2, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 8],
	[11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 2, 2, 2, 2, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 8],
	[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4,11, 1, 1, 8, 1, 8, 1, 8, 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, 2, 2, 0, 2, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 8],
	[11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 9, 5, 4,11, 1, 1, 8, 8, 8, 1, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 8],
	[11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4,11, 5, 4,11, 5, 4, 5, 5, 4,11, 1, 1, 8, 6, 6, 1, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 0, 8],
	[11, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,11, 5, 4,11, 5, 4,11, 5, 4, 4, 4, 4,11, 1, 1, 8, 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, 1, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, 8],
	[11, 5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5, 4,11, 5, 4,11,11,11,11,11,11,11, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8],
	[11, 5, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,11, 5, 4, 9,10,10,10,10,10,11, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 8],
	[11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,11, 5, 4, 5, 5, 5, 5, 5, 5,11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 8],
	[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
];

js/main.js

'use strict'

//ブラウザがページを完全に読みこむまで待つ
addEventListener( 'load', () => {

	//変数gameに、あなたはゲームですよ、と教える
	const game = new Game();
	//ゲームに使う画像などの素材を先に読み込んでおく(プリロード)
	game.preload( 'img/yamada.png', 'img/rico.png', 'img/aru.png', 'img/start.png', 'img/goal.png', 'img/tile.png', 'img/dpad.png', 'sound/bgm.mp3', 'sound/start.mp3', 'sound/clear.mp3' );
	//使いたいキーとして、スペースキーを登録する
	game.keybind( 'space', ' ' );
	//ゲームを開始する準備ができたあとに実行する
	game.main( () => {

		//タイトルシーン
		const titleScene = () => {

			//変数sceneに、あなたはシーンですよ、と教える
			const scene = new Scene();

			//変数titleTextに、あなたは「くろねこラビリンス」というテキストだよ、と教える
			const titleText = new Text( 'くろねこラビリンス' );
			//テキストを上下左右中央の位置にする
			titleText.center().middle();
			//シーンにテキストを追加
			scene.add( titleText );

			//シーンが切り替わったときに、一度だけ呼ばれる
			scene.onchangescene = () => {
				//clear.mp3をストップ
				game.sounds[ 'sound/clear.mp3' ].stop();
				//start.mp3を再生
				game.sounds[ 'sound/start.mp3' ].start();
			}

			//シーンがタッチされたとき
			scene.ontouchstart = () => {
				//メインシーンに切り替える
				game.currentScene = mainScene();
			} //scene.ontouchstart() 終了

			//ループから常に呼び出される
			scene.onenterframe = () => {
				//スペースキーが押されたとき、メインシーンに切り替える
				if ( game.input.space ) game.currentScene = mainScene();
			} //scene.onenterframe() 終了

			//作ったシーンを返す
			return scene;

		} //titleScene() 終了

		//メインシーン
		const mainScene = () => {

			//タイルのサイズ
			const TILE_SIZE = 32;
			//歩く速さ
			const WALKING_SPEED = 4;

			//変数sceneに、あなたはシーンですよ、と教える
			const scene = new Scene();

			//変数tilemapに、あなたはタイルマップですよ、と教える
			const tilemap = new Tilemap( 'img/tile.png' );
			//tilemap.dataに、どんなマップなのか教える
			tilemap.data = map;
			//マップ全体の位置をずらす
			tilemap.x = TILE_SIZE*4 - TILE_SIZE/2;
			tilemap.y = TILE_SIZE*3 - TILE_SIZE/2;
			//移動できないタイルを指定する
			tilemap.obstacles = [0, 3, 6, 7, 8, 9, 10, 11];
			//マップを登録する
			scene.add( tilemap );

			//変数startに、あなたはスタートのタイルですよ、と教える
			const start = new Tile( 'img/start.png' );
			//マップ左上からの座標を指定する
			start.x = TILE_SIZE;
			start.y = TILE_SIZE*2;
			//スタートのタイルを、tilemapに追加して、とお願いする
			tilemap.add( start );

			//変数goalに、あなたはゴールのタイルですよ、と教える
			const goal = new Tile( 'img/goal.png' );
			//マップ左上からの座標を指定する
			goal.x = TILE_SIZE*98;
			goal.y = TILE_SIZE*98;
			//ゴールのタイルを、tilemapに追加して、とお願いする
			tilemap.add( goal );

			//変数yamadaに、あなたは山田先生のキャラクタータイルですよ、と教える
			const yamada = new CharacterTile( 'img/yamada.png' );
			//山田先生を画面の中央に配置
			yamada.x = yamada.y = TILE_SIZE*5 - TILE_SIZE/2;
			//タイルマップの動きと同期させない
			yamada.isSynchronize = false;
			//tilemapに、山田先生のタイルを追加して、とお願いする
			tilemap.add( yamada );

			//変数ricoに、あなたはりこちゃんのキャラクタータイルですよ、と教える
			const rico = new CharacterTile( 'img/rico.png' );
			//りこちゃんの位置を決める
			rico.x = TILE_SIZE*7 - TILE_SIZE/2;
			rico.y = TILE_SIZE*5 - TILE_SIZE/2;
			//タイルマップの動きと同期させない
			rico.isSynchronize = false;
			//tilemapに、りこちゃんのキャラクタータイルを追加して、とお願いする
			tilemap.add( rico );

			//変数aruに、あなたはアルくんのキャラクタータイルですよ、と教える
			const aru = new CharacterTile( 'img/aru.png' );
			//アルくんの位置を決める
			aru.x = TILE_SIZE*7 - TILE_SIZE/2;
			aru.y = TILE_SIZE*6 - TILE_SIZE/2;
			//タイルマップの動きと同期させない
			aru.isSynchronize = false;
			//tilemapに、アルくんのキャラクタータイルを追加して、とお願いする
			tilemap.add( aru );

			//変数partyに、あなたは山田先生とりこちゃんとアルくんのパーティですよ、と教える
			const party = new Party( yamada, rico, aru );
			//パーティの歩く速さに、WALKING_SPEEDの値を代入する
			party.speed = WALKING_SPEED;

			//変数dpadに、あなたはD-Padですよ、と教える
			const dpad = new DPad( 'img/dpad.png', 80 );
			//D-Padの位置を指定する
			dpad.x = 10;
			dpad.y = 230;
			//sceneに、D-Padを追加して、とお願いする
			scene.add( dpad );

			//シーンが切り替わったときに、一度だけ呼ばれる
			scene.onchangescene = () => {
				//start.mp3をストップ
				game.sounds[ 'sound/start.mp3' ].stop();
				//bgm.mp3をループ再生
				game.sounds[ 'sound/bgm.mp3' ].loop();
			}

			//キャラクターのアニメーションのための変数
			let toggleForAnimation = 0;
			//ゴールのテキストが表示されているかどうかの変数
			let hasDisplayedGoalText = false;
			//移動可能かどうかの変数
			let isMovable = true;

			//ループから常に呼び出される
			scene.onenterframe = () => {
				//タイルマップの位置がタイルのサイズで割り切れるとき
				if ( ( tilemap.x - TILE_SIZE/2 ) % TILE_SIZE === 0 && ( tilemap.y - TILE_SIZE/2 ) % TILE_SIZE === 0 ) {
					//タイルマップの移動速度に0を代入する
					tilemap.vx = tilemap.vy = 0;
					//パーティ全員の数だけ繰り返す
					for ( let i in party.member ) {
						//パーティ全員の移動速度を0にする
						party.member[i].vx = party.member[i].vy = 0;
						//パーティ全員の画像を切り替える
						party.member[i].animation = 1;
					}

					//山田先生のタイルがゴールのタイルと重なっているとき、イベントを発生させる
					if ( yamada.isOverlapped( goal ) ) {
						//ゴールのテキストが表示されていないとき
						if ( !hasDisplayedGoalText ) {
							//変数goalTextに、あなたは「ゴールだべ!」というテキストだよ、と教える
							const goalText = new Text( 'ゴールだべ!' );
							//テキストサイズを変更
							goalText.size = 50;
							//テキストを上下左右中央の位置にする
							goalText.center().middle();
							//シーンにテキストを追加
							scene.add( goalText );
							//ゴールのテキストが表示されているかどうかの変数にtrueを代入
							hasDisplayedGoalText = true;
							//移動ができないようにする
							isMovable = false;
							//bgm.mp3をストップ
							game.sounds[ 'sound/bgm.mp3' ].stop();
							//clear.mp3を再生
							game.sounds[ 'sound/clear.mp3' ].start();
							//6秒たったら、タイトルシーンに切り替える
							setTimeout( () => {
								game.currentScene = titleScene();
							}, 6000 );
						}
					}

					//移動可能なとき
					if ( isMovable ) {
						//方向キー、もしくはD-Padが押されているときは、setMemberVelocityメソッドを呼び出し、タイルマップの移動速度と、山田先生の向きに、それぞれの値を代入する
						if ( game.input.left || dpad.arrow.left ) {
							party.setMemberVelocity( 'left' );
							tilemap.vx = WALKING_SPEED;
							yamada.direction = 1;
						}
						else if ( game.input.right || dpad.arrow.right ) {
							party.setMemberVelocity( 'right' );
							tilemap.vx = -1 * WALKING_SPEED;
							yamada.direction = 2;
						}
						else if ( game.input.up || dpad.arrow.up ) {
							party.setMemberVelocity( 'up' );
							tilemap.vy = WALKING_SPEED;
							yamada.direction = 3;
						}
						else if ( game.input.down || dpad.arrow.down ) {
							party.setMemberVelocity( 'down' );
							tilemap.vy = -1 * WALKING_SPEED;
							yamada.direction = 0;
						}

						//移動後のマップ座標を求める
						const yamadaCoordinateAfterMoveX = yamada.mapX - tilemap.vx/WALKING_SPEED;
						const yamadaCoordinateAfterMoveY = yamada.mapY - tilemap.vy/WALKING_SPEED;
						//もし移動後のマップ座標に障害物があるとき
						if ( tilemap.hasObstacle( yamadaCoordinateAfterMoveX, yamadaCoordinateAfterMoveY ) ) {
							//移動量に0を代入する
							tilemap.vx = tilemap.vy = 0;
							//パーティ全員の移動速度に0を代入する
							for ( let i in party.member ) {
								party.member[i].vx = party.member[i].vy = 0;
							}
						}

						//タイルマップが動いているとき、パーティメンバーの向きを変える
						if ( tilemap.vx !== 0 || tilemap.vy !== 0 ) party.setMemberDirection();
					}
				}
				//タイルマップのXとY座標両方がタイルのサイズで割り切れるとき以外で、タイルの半分のサイズで割り切れるとき
				else if ( ( tilemap.x + TILE_SIZE/2 ) % ( TILE_SIZE/2 ) === 0 && ( tilemap.y + TILE_SIZE/2 ) % ( TILE_SIZE/2 ) === 0 ) {
					//0と1を交互に取得できる
					toggleForAnimation ^= 1;
					//パーティメンバーの数だけ繰り返す
					for ( let i in party.member ) {
						//toggleForAnimationの数値によって、パーティ全員の画像を切り替える
						if ( toggleForAnimation === 0 ) party.member[i].animation = 2;
						else party.member[i].animation = 0;
					}
				}
			} //scene.onenterframe 終了

			//作ったシーンを返す
			return scene;

		} //mainScene() 終了

		//gameに、シーンを追加して、とお願いする
		game.add( titleScene() );
		game.add( mainScene() );

		//gameに、ゲームをスタートして、とお願いする
		game.start();

	} ); //main() 終了

} );

js/engine/game.js

'use strict'

/**
 * ゲームづくりの基本となるクラス
 */
class Game {

	/**
	 * 引数
	 * width : ゲームの横幅
	 * height : ゲームの縦幅
	 */
	constructor( width, height ) {
		//canvas要素を作成
		this.canvas = document.createElement( 'canvas' );
		//作成したcanvas要素をbodyタグに追加
		document.body.appendChild( this.canvas );
		//canvasの横幅(ゲームの横幅)を設定。もし横幅が指定されていなければ320を代入
		this.canvas.width = width || 320;
		//canvasの縦幅(ゲームの縦幅)を設定。もし縦幅が指定されていなければ320を代入
		this.canvas.height = height || 320;

		//シーンを入れておくための配列
		this.scenes = [];
		//現在のシーンをいれておくためのもの
		this.currentScene;

		//音声を入れておくためのもの
		this.sounds = [];
		//画面がすでにタッチされたかどうか
		this._isAlreadyTouched = false;
		//設定が終わったかどうか
		this._hasFinishedSetting = false;

		//プリロードは、ゲームのメイン部分が始まる前に動かしたいので、それを入れておくための配列
		this._preloadPromises = [];

		//現在のシーンを一時的に入れておくためのもの。シーンが切り替わったかどうかを判断するのに使う
		this._temporaryCurrentScene;

		//ゲームに使用するキーと、そのキーが押されているかどうかを入れるための連想配列
		//例 { up: false, down: false }
		this.input = {};
		//登録されたキーに割り当てられたプロパティ名と、キー名を、関連づけるための連想配列
		//例 { up: "ArrowUp", down: "ArrowDown" }
		this._keys = {};
	} //constructor() 終了

	/**
	 * プリロードのためのメソッド
	 *
	 * 引数には、使いたい素材を制限なく入れることができる
	 */
	preload() {
		//引数の素材を_assetsに追加
		const _assets = arguments;
		//素材の数だけ繰り返す
		for ( let i=0; i<_assets.length; i++ ) {
			//_preloadPromises[i]に、あなたはプリロードのプロミス(非同期処理をやりやすくする)だよ、と教える
			this._preloadPromises[i] = new Promise( ( resolve, reject ) => {
				//もしそのファイル拡張子が、jpg、jpeg、png、gifのどれかのとき
				if ( _assets[i].match( /\.(jpg|jpeg|png|gif)$/i ) ) {
					//_imgに、あなたは画像ですよ、と教える
					let _img = new Image();
					//img.srcに、引数で指定した画像ファイルを代入
					_img.src = _assets[i];

					//画像が読み込み終わったら、成功ということで、resolve()を呼び出す
					_img.addEventListener( 'load', () => {
						resolve();
					}, { passive: true, once: true } );

					//画像が読み込めなければ、エラーということで、reject()を呼び出す
					_img.addEventListener( 'error', () => {
						reject( `「${_assets[i]}」は読み込めないよ!` );
					}, { passive: true, once: true } );
				}
				//もしそのファイル拡張子が、wav、wave、mp3、oggのどれかのとき
				else if ( _assets[i].match( /\.(wav|wave|mp3|ogg)$/i ) ) {
					//_soundに、あなたはサウンドですよ、と教える
					let _sound = new Sound();
					//_sound.srcに、引数で指定した音声ファイルを代入
					_sound.src = _assets[i];
					//this.soundsに、読み込んだ音声を入れておく
					this.sounds[ _assets[i] ] = _sound;
					//音声を再生する準備をする
					this.sounds[ _assets[i] ].load();

					//サウンドが読み込み終わったら、成功ということで、resolve()を呼び出す
					_sound.addEventListener( 'canplaythrough', () => {
						resolve();
					}, { passive: true, once: true } );

					//サウンドが読み込めなければ、エラーということで、reject()を呼び出す
					_sound.addEventListener( 'error', () => {
						reject( `「${_assets[i]}」は読み込めないよ!` );
					}, { passive: true, once: true } );
				}
				//ファイル拡張子がどれでもないとき
				else {
					//エラーということで、reject()を呼び出す
					reject( `「${_assets[i]}」の形式は、プリロードに対応していないよ!` );
				}
			} );
		}
	} //preload() 終了

	/**
	 * プリロードなどの設定が終わったあとに実行する
	 *
	 * 引数
	 * callback : プリロードなどの設定が終わったあとに実行したいプログラム。今回はゲームのメイン部分
	 */
	main( callback ) {
		//ゲームが始まる前に実行しておきたいもの(今回はプリロード)が、すべて成功したあとに、実行したかったゲームのメイン部分「callback()」を実行
		//失敗したときはコンソールにエラーを表示
		Promise.all( this._preloadPromises ).then( result => {
			callback();
		} ).catch( reject => {
			console.error( reject );
		} );
	} //main() 終了

	/**
	 * startメソッドを呼び出すことで、メインループが開始される
	 */
	start() {
		//デフォルトのキーバインドを登録する(使いたいキーを登録する)
		this.keybind( 'up', 'ArrowUp' );
		this.keybind( 'down', 'ArrowDown' );
		this.keybind( 'right', 'ArrowRight' );
		this.keybind( 'left', 'ArrowLeft' );

		//現在のシーン(currentScene)になにも入っていないときは、scenes[0]を代入
		this.currentScene = this.currentScene || this.scenes[0];

		//ゲームがはじまったときと、ブラウザのサイズが変わったときに呼ばれる。縦横の比を変えずに、canvasを拡大縮小できる
		const _resizeEvent = () => {
			//ブラウザとcanvasの比率の、縦と横を計算し、小さいほうを_ratioに代入する
			const _ratio = Math.min( innerWidth / this.canvas.width, innerHeight / this.canvas.height );
			//canvasのサイズを、ブラウザに合わせて変更する
			this.canvas.style.width = this.canvas.width*_ratio + 'px';
			this.canvas.style.height = this.canvas.height*_ratio + 'px';
		} //_resizeEvent() 終了

		//ブラウザのサイズが変更されたとき、_resizeを呼び出す
		addEventListener( 'resize', _resizeEvent, { passive: true } );
		//_resizeを呼び出す
		_resizeEvent();

		//メインループを呼び出す
		this._mainLoop();

		//ユーザーの操作を待つためのメソッドを呼び出す
		this._waitUserManipulation();
		//イベントリスナーをセットする(削除)
		//this._setEventListener();(削除)
	} //start() 終了

	/**
	 * イベントリスナーをセットするためのメソッド
	 */
	_setEventListener() {
		//なにかキーが押されたときと、はなされたときに呼ばれる
		const _keyEvent = e => {
			//デフォルトのイベントを発生させない
			e.preventDefault();
			//_keysに登録された数だけ繰り返す
			for ( let key in this._keys ) {
				//イベントのタイプによって呼び出すメソッドを変える
				switch ( e.type ) {
					case 'keydown' :
						//押されたキーが、登録されたキーの中に存在するとき、inputのそのキーをtrueにする
						if ( e.key === this._keys[key] ) this.input[key] = true;
						break;
					case 'keyup' :
						//押されたキーが、登録されたキーの中に存在するとき、inputのそのキーをfalseにする
						if ( e.key === this._keys[key] ) this.input[key] = false;
						break;
				}
			}
		}
		//なにかキーが押されたとき
		addEventListener( 'keydown', _keyEvent, { passive: false } );
		//キーがはなされたとき
		addEventListener( 'keyup', _keyEvent, { passive: false } );

		//画面がタッチされたり、指が動いたりしたときなどに呼ばれる
		//シーンや、スプライトなどのオブジェクトの左上端から見た、それぞれの指の位置を取得できるようになる
		const _touchEvent = e => {
			//デフォルトのイベントを発生させない
			e.preventDefault();
			//タッチされた場所などの情報を取得
			const _touches = e.changedTouches[0];
			//ターゲット(今回はcanvas)のサイズ、ブラウザで表示されている部分の左上から見てどこにあるか、などの情報を取得
			const _rect = _touches.target.getBoundingClientRect();
			//タッチされた場所を計算
			const _fingerPosition = {
				x: ( _touches.clientX - _rect.left ) / _rect.width * this.canvas.width,
				y: ( _touches.clientY - _rect.top ) / _rect.height * this.canvas.height
			};
			//イベントのタイプを_eventTypeに代入
			const _eventType = e.type;
			//タッチイベントを割り当てるためのメソッドを呼び出す
			this.currentScene.assignTouchevent( _eventType, _fingerPosition );
		} //_touchEvent() 終了

		//タッチされたとき
		this.canvas.addEventListener( 'touchstart', _touchEvent, { passive: false } );
		//指が動かされたとき
		this.canvas.addEventListener( 'touchmove', _touchEvent, { passive: false } );
		//指がはなされたとき
		this.canvas.addEventListener( 'touchend', _touchEvent, { passive: false } );
	} //_setEventListener() 終了

	/**
	 * ユーザーからの操作を待つためのメソッド
	 */
	_waitUserManipulation() {
		//すべての音声を再生する
		const _playAllSounds = e => {
			//デフォルトのイベントを発生させない
			e.preventDefault();
			//画面にタッチされたかどうかの変数をtrueにする
			this._isAlreadyTouched = true;

			//音声を再生するためのプロミスを入れておく配列
			const _playPromises = [];

			//this.soundsの数だけ繰り返す
			//この繰り返しは、読み込まれた音声を、最初に全て同時に再生してしまおうというもの
			//こうすることで、スマホのブラウザなどの、音声を自動で流せないという制限を解決できる
			for ( let sound in this.sounds ) {
				//音声を再生する準備をする
				this.sounds[ sound ].load();
				//音声をミュートにする
				this.sounds[ sound ].muted = true;
				//音声を再生するメソッドはPromiseを返してくれるので、soundPromiseに追加
				_playPromises.push( this.sounds[ sound ].play() );
			}

			//Promiseが成功か失敗かのチェーン
			Promise.all( _playPromises ).then( () => {
				//成功した場合は全ての音をストップする
				for ( let sound in this.sounds ) {
					this.sounds[ sound ].stop();
				}
			} ).catch( err => {
				//失敗した場合はエラーを表示
				console.log( err );
			} );

			//音声を再生するときのエラーを防ぐために、すこしだけ待つ
			setTimeout( () => {
				//イベントリスナーをセットする
				this._setEventListener();
				this._hasFinishedSetting = true;
			}, 2000 );
		} //_playAllSounds() 終了

		//タッチされたときや、なにかキーが押されたとき、_playAllSoundsを呼び出す
		this.canvas.addEventListener( 'touchstart', _playAllSounds, { passive: false, once: true } );
		addEventListener( 'keydown', _playAllSounds, { passive: false, once: true } );
	} //_waitUserManipulation() 終了

	/**
	 * メインループ
	 */
	_mainLoop() {
		//画家さん(コンテキスト)を呼ぶ
		const ctx = this.canvas.getContext( '2d' );
		//塗りつぶしの色に、黒を指定する
		ctx.fillStyle = '#000000';
		//左上から、画面のサイズまでを、塗りつぶす
		ctx.fillRect( 0, 0, this.canvas.width, this.canvas.height );

		//もし、ユーザーがまだ画面をタッチしていない(画面を操作していない)とき、スタートパネルを表示
		if ( !this._isAlreadyTouched ) this.startPanel();
		//設定がすでに終了しているとき
		else if ( this._hasFinishedSetting ) {
			//現在のシーンのupdateメソッドを呼び出す
			this.currentScene.update();

			//一時的に入れておいたシーンが現在のシーンではないとき(シーンが切り替わったとき)、現在のシーンのonchangesceneメソッドを呼び出す
			if ( this._temporaryCurrentScene !== this.currentScene ) this.currentScene.onchangescene();

			//現在のシーンの、ゲームに登場する全てのもの(オブジェクト)の数だけ繰り返す
			for ( let i=0; i<this.currentScene.objs.length; i++ ) {
				//現在のシーンの、すべてのオブジェクトのupdateメソッドを呼び出す
				this.currentScene.objs[i].update( this.canvas );
			}

			//現在のシーンを覚えておいてもらう
			this._temporaryCurrentScene = this.currentScene;
		}

		//自分自身(_mainLoop)を呼び出して、ループさせる
		requestAnimationFrame( this._mainLoop.bind( this ) );
	} //_mainLoop() 終了

	/**
	 * ゲームを開始して一番最初に表示される画面をつくるメソッド。ここでユーザーに操作してもらい、音声を出せるようにする
	 */
	startPanel() {
		//表示したいテキストを_textに代入
		const _text = 'タップ、またはなにかキーを押してね!'
		//表示したいテキストのフォントを_fontに代入
		const _font = "游ゴシック体, 'Yu Gothic', YuGothic, sans-serif";
		//フォントサイズは、ゲーム画面の横幅を20で割ったもの。(今回は表示したい文字が18文字なので、左右の余白も考え、20で割る)
		const _fontSize = this.canvas.width/20;
		//画家さん(コンテキスト)を呼ぶ
		const _ctx = this.canvas.getContext( '2d' );
		//テキストの横幅を取得
		const _textWidth = _ctx.measureText( _text ).width;
		//フォントの設定
		_ctx.font = `normal ${_fontSize}px ${_font}`;
		//ベースラインを文字の中央にする
		_ctx.textBaseline = 'middle';
		//テキストの色をグレーに設定
		_ctx.fillStyle = '#aaaaaa';
		//テキストを上下左右中央の位置に表示
		_ctx.fillText( _text, ( this.canvas.width - _textWidth )/2, this.canvas.height/2 );
	} //startPanel() 終了

	/**
	 * ゲームにシーンに追加できるようになる、addメソッドを作成
	 *
	 * 引数
	 * scene : 追加したいシーン
	 */
	add( scene ) {
		//引数がSceneのとき、this.scenesの末尾にsceneを追加
		if ( scene instanceof Scene ) this.scenes.push( scene );
		//引数がSceneでなければ、コンソールにエラーを表示
		else console.error( 'Gameに追加できるのはSceneだけだよ!' );
	} //add()終了

	/**
	 * 使いたいキーを登録できるようになる、keybindメソッドを作成
	 *
	 * 引数
	 * name : キーにつける名前
	 * key : キーコード
	 */
	keybind( name, key ) {
		//キーの名前と、キーコードを関連づける
		this._keys[name] = key;
		//キーが押されているかどうかを入れておく変数に、まずはfalseを代入しておく
		this.input[name] = false;
	} //keybind() 終了

}

js/engine/sprite.js

'use strict'

/**
 * スプライトに関してのクラス
 */
class Sprite {

	/**
	 * 引数
	 * img : 画像ファイルまでのパス
	 * width : 画像の表示する範囲(横幅)
	 * height : 画像の表示する範囲(縦幅)
	 */
	constructor( img, width, height ) {
		//this.imgに、あなたは画像ですよ、と教える
		this.img = new Image();
		//this.img.srcに画像ファイルまでのパスを代入
		this.img.src = img;
		//画像の初期位置
		this.x = this.y = 0;
		//画像を表示する範囲の横幅。引数widthが指定されていない場合、this.widthに32を代入
		this.width = width || 32;
		//画像を表示する範囲の縦幅。引数heightが指定されていない場合、this.heightに32を代入
		this.height = height || 32;
		//何番目の画像を表示するか
		this.frame = 0;
		//数値によってスプライトを移動させることができる(移動速度)
		this.vx = this.vy = 0;
		//スプライトの位置を、数値の分、ずらすことができる
		this.shiftX = this.shiftY = 0;
		//スプライトの角度
		this.rotate = 0;
	} //constructor() 終了

	/**Gameクラスのメインループからずっと呼び出され続ける
	 *
	 * 引数
	 * canvas : 紙(キャンバス)
	 */
	update( canvas ) {
		//画像などを画面に表示するためのメソッドを呼び出す
		this.render( canvas );
		//スプライトを動かしたり、なにかのきっかけでイベントを発生させたりするために使うメソッドを呼び出す
		this.onenterframe();
		//スプライトを移動する
		this.x += this.vx;
		this.y += this.vy;
	} //update() 終了

	/**
	 * 画像などを画面に表示するためのメソッド
	 *
	 * 引数
	 * canvas : 紙(キャンバス)
	 */
	render( canvas ) {
		//キャンバスの外にスプライトがあるとき、ここでこのメソッドを終了する
		if ( this.x + this.shiftX < -1 * this.width || this.x + this.shiftX > canvas.width ) return;
		if ( this.y + this.shiftY < -1 * this.height || this.y + this.shiftY > canvas.height ) return;

		//X,Y方向に、何番目の画像か
		const _frameX = this.frame % ( this.img.width / this.width );
		const _frameY = ~~( this.frame / ( this.img.width / this.width ) );

		//画家さん(コンテキスト)を呼ぶ
		const _ctx = canvas.getContext( '2d' );
		//スプライトを回転させるときの中心位置を変更するための、canvasの原点の移動量
		const _translateX = this.x + this.width/2 + this.shiftX;
		const _translateY = this.y + this.height/2 + this.shiftY;
		//描画状態を保存する
		_ctx.save();
		//canvasの原点の移動
		_ctx.translate( _translateX, _translateY );
		//canvasを回転
		_ctx.rotate( this.rotate * Math.PI / 180 );
		//移動したcanvasの原点を戻す
		_ctx.translate( -1*_translateX, -1*_translateY );
		//画家さんに、絵を描いてとお願いする
		_ctx.drawImage(
			this.img,
			this.width * _frameX,
			this.height * _frameY,
			this.width,
			this.height,
			this.x + this.shiftX,
			this.y + this.shiftY,
			this.width,
			this.height
		);
		//保存しておいた描画状態に戻す
		_ctx.restore();
	} //render() 終了

	/**
	 * タッチした指の、相対的な位置(タッチしたオブジェクトの左上からの位置)を取得できるメソッド
	 *
	 * 引数
	 * fingerPosition : 指の位置の座標
	 */
	getRelactiveFingerPosition( fingerPosition ) {
		//タッチしたものの、左上部分からの座標
		const _relactiveFingerPosition = {
			x: fingerPosition.x - this.x - this.shiftX,
			y: fingerPosition.y - this.y - this.shiftY
		};

		//数値が範囲内にあるかどうかを取得できる関数
		const inRange = ( num, min, max ) => {
			//数値が範囲内にあるかどうか
			const _inRange = ( min <= num && num <= max );
			//結果を返す
			return _inRange;
		}

		//タッチした位置がオブジェクトの上の場合、相対的な位置を返す
		if ( inRange( _relactiveFingerPosition.x, 0, this.width ) && inRange( _relactiveFingerPosition.y, 0, this.height ) ) return _relactiveFingerPosition;
		//オブジェクトから外れていれば、falseを返す
		return false;
	} //getRelactiveFingerPosition() 終了

	/**
	 * タッチイベントを割り当てるためのメソッド
	 *
	 * 引数
	 * eventType : イベントのタイプ
	 * fingerPosition : 指の位置
	 */
	assignTouchevent( eventType, fingerPosition ) {
		//相対的な座標(タッチしたオブジェクトの、左上からの座標)を取得
		const _relactiveFingerPosition = this.getRelactiveFingerPosition( fingerPosition );

		//イベントのタイプによって呼び出すメソッドを変える
		switch ( eventType ) {
			case 'touchstart' :
				//指の場所がスプライトの上にあるとき、ontouchstartメソッドを呼び出す
				if ( _relactiveFingerPosition ) this.ontouchstart( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
			case 'touchmove' :
				//指の場所がスプライトの上にあるとき、ontouchmoveメソッドを呼び出す
				if ( _relactiveFingerPosition ) this.ontouchmove( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
			case 'touchend' :
				//ontouchendメソッドを呼び出す
				this.ontouchend( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
		}
	} //assignTouchevent() 終了

	/**
	 * 常に呼び出され、スプライトの移動やイベントの発生などに使うメソッド。空なのはオーバーライド(上書き)して使うため
	 */
	onenterframe() {}

	/**
	 * タッチされたときに呼び出される
	 */
	ontouchstart() {}

	/**
	 * 指が動かされたときに呼び出される
	 */
	ontouchmove() {}

	/**
	 * 指がはなされたときに呼び出される
	 */
	ontouchend() {}

}

js/engine/scene.js

'use strict'

/**
 * シーンに関してのクラス
 */
class Scene {

	constructor() {
		this.objs = [];
	} //constructor() 終了

	/**
	 * シーンにオブジェクトを追加するときに呼び出されるメソッド
	 *
	 * 引数
	 * obj : スプライトやテキストなど(オブジェクト)
	 */
	add( obj ) {
		//引数がSprite、Text、Tilemapのとき、this.objsの末尾にobjを追加
		if ( obj instanceof Sprite || obj instanceof Text || obj instanceof Tilemap ) this.objs.push( obj );
		//引数がSprite、Text、Tilemapでなければ、コンソールにエラーを表示
		else console.error( 'Sceneに追加できるのはSprite、Text、Tilemapだけだよ!' );
	} //add() 終了

	/**Gameクラスのメインループからずっと呼び出され続ける
	 *
	 * 引数
	 * canvas : 紙(キャンバス)
	 */
	update( canvas ) {
		//スプライトを動かしたり、なにかのきっかけでイベントを発生させたりするために使うメソッドを呼び出す
		this.onenterframe();
	} //update() 終了

	/**
	 * タッチイベントを割り当てるためのメソッド
	 *
	 * 引数
	 * eventType : イベントのタイプ
	 * fingerPosition : 指の位置
	 */
	assignTouchevent( eventType, fingerPosition ) {
		//イベントのタイプによって呼び出すメソッドを変える
		switch ( eventType ) {
			case 'touchstart' :
				//現在のシーンのtouchstartメソッドを呼び出す
				this.ontouchstart( fingerPosition.x, fingerPosition.y );
				break;
			case 'touchmove' :
				//現在のシーンのtouchmoveメソッドを呼び出す
				this.ontouchmove( fingerPosition.x, fingerPosition.y );
				break;
			case 'touchend' :
				//現在のシーンのtouchendメソッドを呼び出す
				this.ontouchend( fingerPosition.x, fingerPosition.y );
				break;
		}

		//シーンにあるオブジェクトの数だけ繰り返す
		for ( let i=0; i<this.objs.length; i++ ) {
			//シーンにあるオブジェクトの、タッチイベントを割り当てるためのメソッドを呼び出す
			this.objs[i].assignTouchevent( eventType, fingerPosition );
		}
	} //assignTouchevent() 終了

	/**
	 * 常に呼び出され、スプライトの移動やイベントの発生などに使うメソッド。空なのはオーバーライド(上書き)して使うため
	 */
	onenterframe() {}

	/**
	 * タッチされたときに呼び出される
	 */
	ontouchstart() {}

	/**
	 * 指が動かされたときに呼び出される
	 */
	ontouchmove() {}

	/**
	 * 指がはなされたときに呼び出される
	 */
	ontouchend() {}

	/**
	 * シーンが切り替わったときに呼び出される
	 */
	onchangescene() {}

}

js/engine/tile.js

'use strict'

/**
 * タイルに関してのクラス
 */
class Tile extends Sprite {

	/**
	 * 引数
	 * img : 画像ファイルまでのパス
	 * size : タイルの大きさ
	 */
	constructor( img, size ) {
		//親クラスのコンストラクタを呼び出す
		super( img, size, size );
		//引数sizeが指定されていない場合、this.sizeに32を代入
		this.size = size || 32;
		//マップ座標に0を代入。(マップ座標は、タイルマップの左上から何番目のタイルの位置にあるのか、という意味でここでは使っています)
		this.mapX = this.mapY = 0;
		//タイルマップと同期して動くかどうか
		this.isSynchronize = true;
	} //constructor() 終了

	/**
	 * タイル同士が重なっているかどうかを取得できるメソッド
	 *
	 * 引数
	 * tile : 重なっているかを判定したいタイル
	 */
	isOverlapped( tile ) {
		//引数がTileのとき
		if ( tile instanceof Tile ) {
			//タイル同士が重なっているかどうか
			const _isOverlapped = ( this.mapX === tile.mapX && this.mapY === tile.mapY );
			//タイル同士が重なっているかどうかの結果を返す
			return _isOverlapped;
		}
		//引数がTileでなければ、コンソールにエラーを表示
		else console.error( 'Tilemapに追加できるのはTileだけだよ!' );
	} //isOverlapped() 終了

}

js/engine/charactertile.js

'use strict'

/**
 * キャラクタータイルに関するクラス
 */
class CharacterTile extends Tile {

	/**
	 * 引数
	 * img : 画像ファイルまでのパス
	 * size : タイルの一辺の長さ
	 *
	 * ※注意
	 * directionやanimationを指定すると自動的にスプライト画像も変更されるが、画像自体を対応したものにする必要がある
	 * CharacterTileクラスで、frameを使うことはできない
	 */
	constructor( img, size ) {
		//親クラスのコンストラクタを呼び出す
		super( img, size );
		//キャラクターの向き(0:正面 1:左 2:右 3:後ろ)
		this.direction = 0;
		//スプライトのアニメーション。1が通常。0~2を切り替えることで、歩いているアニメーションを作ることができる
		this.animation = 1;
	} //constructor() 終了

	/**
	 * 画像などを画面に表示するためのメソッド
	 *
	 * 引数
	 * canvas : 紙(キャンバス)
	 */
	render( canvas ) {
		//画面の外にスプライトがあるとき、表示しないようにする
		if ( this.x + this.shiftX < -1 * this.size || this.x + this.shiftX > canvas.width ) return;
		if ( this.y + this.shiftY < -1 * this.size || this.y + this.shiftY > canvas.height ) return;
		//画家さん(コンテキスト)を呼ぶ
		const _ctx = canvas.getContext( '2d' );
		//スプライトを回転させるときの中心位置を変更するための、canvasの原点の移動量
		const _translateX = this.x + this.width/2 + this.shiftX;
		const _translateY = this.y + this.height/2 + this.shiftY;
		//描画状態を保存する
		_ctx.save();
		//canvasの原点の移動
		_ctx.translate( _translateX, _translateY );
		//canvasを回転
		_ctx.rotate( this.rotate * Math.PI / 180 );
		//移動したcanvasの原点を戻す
		_ctx.translate( -1*_translateX, -1*_translateY );
		//画家さんに、絵を描いてとお願いする
		_ctx.drawImage(
			this.img,
			this.size * this.animation,
			this.size * this.direction,
			this.size,
			this.size,
			this.x + this.shiftX,
			this.y + this.shiftY,
			this.size,
			this.size
		);
		//保存しておいた描画状態に戻す
		_ctx.restore();
	} //render() 終了

}

js/engine/tilemap.js

'use strict'

/**
 * タイルマップに関するクラス
 */
class Tilemap {

	/**
	 * 引数
	 * img : 画像ファイルまでのパス
	 * size : タイルひとつの大きさ(一辺の長さ)
	 *
	 * タイルひとつは正方形にする
	 */
	constructor( img, size ) {
		//Imageのインスタンスを作成
		this.img = new Image();
		//this.img.srcに画像ファイルまでのパスを代入
		this.img.src = img;
		//画像の初期位置
		this.x = this.y = 0;
		//数値によってタイルマップを移動させることができる(移動速度)
		this.vx = this.vy = 0;
		//引数sizeが指定されていない場合、this.sizeに32を代入
		this.size = size || 32;
		//二次元配列で数値を入力すると、マップをつくることができる
		this.data = [];
		//タイルマップに重ねるように置きたいタイルを追加できる
		this.tiles = [];
		//壁や天井など、移動できないタイルを指定できる
		this.obstacles = [0];
	} //constructor() 終了

	/**
	 * タイルマップの上にタイルを重ねるように追加できるメソッド
	 *
	 * 引数
	 * tile : 追加したいタイル
	 */
	add( tile ) {
		//引数がTileのとき
		if ( tile instanceof Tile ) {
			//タイルのマップ座標を計算
			tile.mapX = tile.x / this.size;
			tile.mapY = tile.y / this.size;
			//もし、タイルがタイルマップと同期していないときは、マップ座標を計算しなおす
			if ( !tile.isSynchronize ) {
				tile.mapX = ( tile.x - this.x ) / this.size;
				tile.mapY = ( tile.y - this.y ) / this.size;
			}
			//this.tilesの末尾にtileを追加
			this.tiles.push( tile );
		}
		//引数がTileでなければ、コンソールにエラーを表示
		else console.error( 'Tilemapに追加できるのはTileだけだよ!' );
	} //add() 終了

	/**
	 * 指定された場所のタイルが、移動できないかどうかを取得できるメソッド
	 *
	 * 引数
	 * mapX : タイルマップ上のX座標
	 * mapY : タイルマップ上のY座標
	 */
	hasObstacle( mapX, mapY ) {
		//指定された場所のタイルが、壁や天井など、移動できないかどうか
		const _isObstacleTile = this.obstacles.some( obstacle => obstacle === this.data[mapY][mapX] );
		//移動できないかどうかを返す
		return _isObstacleTile;
	} //hasObstacle() 終了

	/**Gameクラスのメインループからずっと呼び出され続ける
	 *
	 * 引数
	 * canvas : 紙(キャンバス)
	 */
	update( canvas ) {
		//画像などを画面に表示するためのメソッドを呼び出す
		this.render( canvas );
		//常に呼び出される、オーバーライド用のメソッドを呼び出す
		this.onenterframe();
		//タイルマップを移動する
		this.x += this.vx;
		this.y += this.vy;

		//タイルの数だけ繰り返す
		for ( let i=0; i<this.tiles.length; i++ ) {
			//タイルとタイルマップの位置を同期させるとき
			if ( this.tiles[i].isSynchronize ) {
				//タイルマップの位置の分、それぞれのタイルの位置をずらす
				this.tiles[i].shiftX = this.x;
				this.tiles[i].shiftY = this.y;
			}
			//それぞれのタイルのupdateメソッドを呼び出す
			this.tiles[i].update( canvas );

			//タイルのマップ座標を計算
			this.tiles[i].mapX = this.tiles[i].x / this.size;
			this.tiles[i].mapY = this.tiles[i].y / this.size;
			//もし、タイルがタイルマップと同期していないときは、マップ座標を計算しなおす
			if ( !this.tiles[i].isSynchronize ) {
				this.tiles[i].mapX = ( this.tiles[i].x - this.x ) / this.size;
				this.tiles[i].mapY = ( this.tiles[i].y - this.y ) / this.size;
			}
		}
	} //update() 終了

	/**
	 * Gameクラスのメインループからずっと呼び出され続ける。画像を表示したりするためのメソッド
	 *
	 * 引数
	 * canvas : 紙(キャンバス)
	 */
	render( canvas ) {
		//マップの縦方向の数だけ繰り返す
		for (let y=0; y<this.data.length; y++) {
			//タイルの縦の位置
			const _tileY = this.size * y + this.y;
			//タイルが、画面から縦にはみ出しているとき、この下をスキップして、次から繰り返し
			if ( _tileY < -1 * this.size || _tileY > canvas.height ) continue;

			//マップの横方向の数だけ繰り返す
			for (let x=0; x<this.data[y].length; x++) {
				//タイルの横の位置
				const _tileX = this.size * x + this.x
				//タイルが、画面から横にはみ出しているとき、この下をスキップして、次から繰り返し
				if ( _tileX < -1 * this.size || _tileX > canvas.width ) continue;

				//X方向に、何番目の画像か
				const _frameX = this.data[y][x] % ( this.img.width / this.size );
				//Y方向に、何番目の画像か
				const _frameY = ~~( this.data[y][x] / ( this.img.width / this.size ) );

				//画家さん(コンテキスト)を呼ぶ
				const _ctx = canvas.getContext( '2d' );

				//タイルを表示
				_ctx.drawImage(
					this.img,
					this.size * _frameX,
					this.size * _frameY,
					this.size,
					this.size,
					_tileX,
					_tileY,
					this.size,
					this.size
				);
			}
		}
	} //render() 終了

	/**
	 * タッチした指の、相対的な位置(タッチしたオブジェクトの左上からの位置)を取得できるメソッド
	 *
	 * 引数
	 * fingerPositionX : 指の位置の座標
	 */
	getRelactiveFingerPosition( fingerPosition ) {
		//タッチしたものの、左上部分からの座標
		const _relactiveFingerPosition = {
			x: fingerPosition.x - this.x,
			y: fingerPosition.y - this.y
		};

		//数値が範囲内にあるかどうかを取得できる関数
		const inRange = ( num, min, max ) => {
			//数値が範囲内にあるかどうか
			const _inRange = ( min <= num && num <= max );
			//結果を返す
			return _inRange;
		}

		//タッチした位置がオブジェクトの上の場合、相対的な位置を返す
		if ( inRange( _relactiveFingerPosition.x, 0, this.size*this.data[0].length ) && inRange( _relactiveFingerPosition.y, 0, this.size*this.data.length ) ) return _relactiveFingerPosition;
		//オブジェクトから外れていれば、falseを返す
		return false;
	} //getRelactiveFingerPosition() 終了

	/**
	 * タッチイベントを割り当てるためのメソッド
	 *
	 * 引数
	 * eventType : イベントのタイプ
	 * fingerPosition : 指の位置
	 */
	assignTouchevent( eventType, fingerPosition ) {
		//相対的な座標(タッチしたオブジェクトの、左上からの座標)を取得
		const _relactiveFingerPosition = this.getRelactiveFingerPosition( fingerPosition );

		//目的のオブジェクト以外の場所がタッチされた場合は、この下をスキップして、次から繰り返し
		if ( !_relactiveFingerPosition ) return;

		//イベントのタイプによって呼び出すメソッドを変える
		switch ( eventType ) {
			case 'touchstart' :
				//現在のシーンのオブジェクトの、touchstartメソッドを呼び出す
				this.ontouchstart( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
			case 'touchmove' :
				//現在のシーンのオブジェクトの、touchmoveメソッドを呼び出す
				this.ontouchmove( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
			case 'touchend' :
				//現在のシーンのオブジェクトの、touchendメソッドを呼び出す
				this.ontouchend( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
		}

		//タイルマップの上の、タイルの数だけ繰り返す
		for ( let i=0; i<this.tiles.length; i++ ) {
			//タイルマップの上のタイルの、タッチイベントを割り当てるためのメソッドを呼び出す
			this.tiles[i].assignTouchevent( eventType, fingerPosition );
		}
	} //assignTouchevent() 終了

	/**
	 * 常に呼び出されるメソッド。空なのはオーバーライド(上書き)して使うため
	 */
	onenterframe() {}

	/**
	 * タッチされたときに呼び出される
	 */
	ontouchstart() {}

	/**
	 * 指が動かされたときに呼び出される
	 */
	ontouchmove() {}

	/**
	 * 指がはなされたときに呼び出される
	 */
	ontouchend() {}

}

js/engine/text.js

'use strict'

/**
 * テキストに関してのクラス
 */
class Text {

	/**
	 * 引数
	 * text : 表示する文字列
	 */
	constructor( text ) {
		//this.textに表示する文字列を代入
		this.text = text;
		//デフォルトのフォントを指定
		this.font = "游ゴシック体, 'Yu Gothic', YuGothic, sans-serif";
		//テキストを表示する位置
		this.x = this.y = 0;
		//数値によってテキストを移動させることができる(移動速度)
		this.vx = this.vy = 0;
		//テキストのベースラインの位置
		this.baseline = 'top';
		//テキストのサイズ
		this.size = 20;
		//テキストの色
		this.color = '#ffffff';
		//テキストの太さ
		this.weight = 'normal';
		//テキストの幅
		this._width = 0;
		//テキストの高さ
		this._height = 0;
		//テキストを左右中央の位置にするかどうか
		this._isCenter = false;
		//テキストを上下中央の位置にするかどうか
		this._isMiddle = false;
	} //constructor() 終了

	/**
	 * 呼び出すと、テキストを左右中央の位置に配置できるメソッド
	 */
	center() {
		//テキストを左右中央の位置に配置するかどうかのプロパティにtrueを代入
		this._isCenter = true;
		//thisを返すことで、メソッドをチェーンにすることができる
		return this;
	} //center() 終了

	/**
	 * 呼び出すと、テキストを上下中央の位置に配置できるメソッド
	 */
	middle() {
		//テキストのベースラインの位置を変更
		this.baseline = 'middle'
		//テキストを上下中央の位置に配置するかどうかのプロパティにtrueを代入
		this._isMiddle = true;
		//thisを返すことで、メソッドをチェーンにすることができる
		return this;
	} //middle() 終了

	/**Gameクラスのメインループからずっと呼び出され続ける
	 *
	 * 引数
	 * canvas : 紙(キャンバス)
	 */
	update( canvas ) {
		//画家さん(コンテキスト)を呼ぶ
		const _ctx = canvas.getContext( '2d' );

		//テキストの太さ、サイズ、フォントを設定
		_ctx.font = `${this.weight} ${this.size}px ${this.font}`;
		//テキストの色を設定
		_ctx.fillStyle = this.color;
		//テキストのベースラインの位置を設定
		_ctx.textBaseline = this.baseline;

		//テキストの幅を計算
		this._width = _ctx.measureText( this.text ).width;
		//テキストの高さを計算
		this._height = Math.abs( _ctx.measureText( this.text ).actualBoundingBoxAscent ) + Math.abs( _ctx.measureText( this.text ).actualBoundingBoxDescent );

		//テキストを左右中央に配置したいときの、X座標の計算
		if ( this._isCenter ) this.x = ( canvas.width - this._width ) / 2;
		//テキストを上下中央に配置したいときの、Y座標の計算
		if ( this._isMiddle ) this.y = canvas.height / 2;

		//画像などを画面に表示するためのメソッドを呼び出す
		this.render( canvas, _ctx );
		//テキストを動かしたりするために使うメソッドを呼び出す
		this.onenterframe();

		//テキストを移動する
		this.x += this.vx;
		this.y += this.vy;
	} //update() 終了

	/**
	 * テキストを画面に表示するためのメソッド
	 *
	 * 引数
	 * canvas : 紙(キャンバス)
	 */
	render( canvas, ctx ) {
		//画面の外にテキストがあるとき、表示しないようにする
		if ( this.x < -1 * this._width || this.x > canvas.width ) return;
		if ( this.y < -1 * this._height || this.y > canvas.height + this._height ) return;
		//テキストを表示
		ctx.fillText( this.text, this.x, this.y );
	} //render() 終了

	/**
	 * タッチした指の、相対的な位置(タッチしたオブジェクトの左上からの位置)を取得できるメソッド
	 *
	 * 引数
	 * fingerPositionX : 指の位置の座標
	 */
	getRelactiveFingerPosition( fingerPosition ) {
		//タッチしたテキストの、左上部分からの座標。テキストのbaselineによって位置を調節する
		let _relactiveFingerPosition = {
			x: fingerPosition.x - this.x,
			y: fingerPosition.y - this.y + this._height
		};
		if ( this.baseline === 'top' || this.baseline === 'hanging' ) {
			_relactiveFingerPosition = {
				x: fingerPosition.x - this.x,
				y: fingerPosition.y - this.y
			};
		}
		if ( this.baseline === 'middle' ) {
			_relactiveFingerPosition = {
				x: fingerPosition.x - this.x,
				y: fingerPosition.y - this.y + this._height/2
			};
		}

		//数値が範囲内にあるかどうかを取得できる関数
		const inRange = ( num, min, max ) => {
			//数値が範囲内にあるかどうか
			const _inRange = ( min <= num && num <= max );
			//結果を返す
			return _inRange;
		}

		//タッチした位置がオブジェクトの上の場合、相対的な位置を返す
		if ( inRange( _relactiveFingerPosition.x, 0, this._width ) && inRange( _relactiveFingerPosition.y, 0, this._height ) ) return _relactiveFingerPosition;
		//オブジェクトから外れていれば、falseを返す
		return false;
	} //getRelactiveFingerPosition() 終了

	/**
	 * タッチイベントを割り当てるためのメソッド
	 *
	 * 引数
	 * eventType : イベントのタイプ
	 * fingerPosition : 指の位置
	 */
	assignTouchevent( eventType, fingerPosition ) {
		//相対的な座標(タッチしたオブジェクトの、左上からの座標)を取得
		const _relactiveFingerPosition = this.getRelactiveFingerPosition( fingerPosition );

		//イベントのタイプによって呼び出すメソッドを変える
		switch ( eventType ) {
			case 'touchstart' :
				//指の場所がテキストの上にあるとき、ontouchstartメソッドを呼び出す
				if ( _relactiveFingerPosition ) this.ontouchstart( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
			case 'touchmove' :
				//指の場所がテキストの上にあるとき、ontouchmoveメソッドを呼び出す
				if ( _relactiveFingerPosition ) this.ontouchmove( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
			case 'touchend' :
				//ontouchendメソッドを呼び出す
				this.ontouchend( _relactiveFingerPosition.x, _relactiveFingerPosition.y );
				break;
		}
	} //assignTouchevent() 終了

	/**
	 * 常に呼び出されるメソッド。空なのはオーバーライド(上書き)して使うため
	 */
	onenterframe() {}

	/**
	 * タッチされたときに呼び出される
	 */
	ontouchstart() {}

	/**
	 * 指が動かされたときに呼び出される
	 */
	ontouchmove() {}

	/**
	 * 指がはなされたときに呼び出される
	 */
	ontouchend() {}

}

js/engine/dpad.js

'use strict'

/**
 * D-Padに関してのクラス
 */
class DPad extends Sprite {

	/**
	 * 引数
	 * img : 画像ファイルまでのパス
	 * size : D-Padの大きさ
	 */
	constructor( img, size ) {
		//親クラスのコンストラクタを呼び出す
		super( img, size, size );
		//this.sizeに、指定されたサイズを代入
		this.size = size;
		//方向ボタンが押されているかどうか
		this.arrow = {
			up: false,
			down: false,
			left: false,
			right: false
		};
	} //constructor() 終了

	/**
	 * 画面がタッチされたときに呼ばれるメソッド
	 *
	 * 引数
	 * fingerPositionX: タッチされたX座標
	 * fingerPositionY: タッチされたY座標
	 */
	ontouchstart( fingerPositionX, fingerPositionY ) {
		//_applyToDPadメソッドを呼び出す
		this._applyToDPad( fingerPositionX, fingerPositionY );
	} //ontouchstart() 終了

	/**
	 * タッチされた指が動かされたときに呼ばれるメソッド
	 *
	 * 引数
	 * fingerPositionX: 指が触れている部分のX座標
	 * fingerPositionY: 指が触れている部分のY座標
	 */
	ontouchmove( fingerPositionX, fingerPositionY ) {
		//_applyToDPadメソッドを呼び出す
		this._applyToDPad( fingerPositionX, fingerPositionY );
	} //ontouchmove() 終了

	/**
	 * 画面から指がはなされたときに呼ばれるメソッド
	 *
	 * 引数
	 * fingerPositionX: 指がはなされた部分のX座標
	 * fingerPositionY: 指がはなされた部分のY座標
	 */
	ontouchend( fingerPositionX, fingerPositionY ) {
		//画像を切り替える
		this.frame = 0;
		//ボタンを初期化
		this.arrow = {
			up: false,
			down: false,
			left: false,
			right: false
		};
	} //ontouchend() 終了

	/**
	* D-Padに反映させる
	*
	* 引数
	* fingerPositionX: 指が触れている部分のX座標
	* fingerPositionY: 指が触れている部分のY座標
	*/
	_applyToDPad( fingerPositionX, fingerPositionY ) {
		//画像を切り替える
		this.frame = 1;
		//ボタンを初期化
		this.arrow = {
			up: false,
			down: false,
			left: false,
			right: false
		};
		//上ボタンが押されたとき、arrow.upをtrueにし、D-Padの角度を0度にする
		if ( fingerPositionX > fingerPositionY && fingerPositionX < this.size - fingerPositionY ) {
			this.arrow.up = true;
			this.rotate = 0;
		}
		//下ボタンが押されたとき、arrow.downをtrueにし、D-Padの角度を180度にする
		else if ( fingerPositionX > this.size - fingerPositionY && fingerPositionX < fingerPositionY ) {
			this.arrow.down = true;
			this.rotate = 180;
		}
		//左ボタンが押されたとき、arrow.leftをtrueにし、D-Padの角度を270度にする
		else if ( fingerPositionY > fingerPositionX && fingerPositionY < this.size - fingerPositionX ) {
			this.arrow.left = true;
			this.rotate = 270;
		}
		//右ボタンが押されたとき、arrow.rightをtrueにし、D-Padの角度を90度にする
		else if ( fingerPositionY > this.size - fingerPositionX && fingerPositionY < fingerPositionX ) {
			this.arrow.right = true;
			this.rotate = 90;
		}
	} //_applyToDPad() 終了
}

js/engine/party.js

'use strict'

/**
 * パーティに関してのクラス
 */
class Party {

	/**
	 * 引数には、パーティのメンバーを制限なく入れることができる
	 */
	constructor() {
		//引数をthis.memberに追加
		this.member = arguments;
		//パーティの移動速度
		this.speed = 1;
	} //constructor() 終了

	/**
	 * 先頭以外のキャラの、向きを設定するためのメソッド
	 */
	setMemberDirection() {
		//先頭のキャラ以外の数だけ繰り返す
		for ( let i=1; i<this.member.length; i++ ) {
			//ひとつ前のキャラよりもX座標が大きいとき、左向きにする
			if ( this.member[i-1].mapX < this.member[i].mapX ) this.member[i].direction = 1;
			//ひとつ前のキャラよりもX座標が小さいとき、右向きにする
			else if ( this.member[i-1].mapX > this.member[i].mapX ) this.member[i].direction = 2;
			//ひとつ前のキャラよりもY座標が大きいとき、後ろ向きにする
			else if ( this.member[i-1].mapY < this.member[i].mapY ) this.member[i].direction = 3;
			//ひとつ前のキャラよりもY座標が小さいとき、前向きにする
			else if ( this.member[i-1].mapY > this.member[i].mapY ) this.member[i].direction = 0;
		}
	} //setMemberDirection() 終了

	/**
	 * 先頭以外のキャラの、移動速度を設定するためのメソッド
	 *
	 * 引数
	 * direction : 先頭のキャラの移動方向
	 */
	setMemberVelocity( direction ) {
		//先頭以外のキャラの数だけ繰り返す
		for ( let i=1; i<this.member.length; i++ ) {
			//ひとつ前のキャラとX座標が同じときの、計算用変数
			let _samePrevX;
			//ひとつ前のキャラとY座標が同じときの、計算用変数
			let _samePrevY;
			//ひとつ前のキャラよりもX座標が小さいときの、計算用変数
			let _lessThanPrevX;
			//ひとつ前のキャラよりもY座標が小さいときの、計算用変数
			let _lessThanPrevY;
			//ひとつ前のキャラよりもX座標大きいときの、計算用変数
			let _moreThanPrevX;
			//ひとつ前のキャラよりもY座標が大きいときの、計算用変数
			let _moreThanPrevY;
			//ひとつ前のキャラよりも、タイルひとつ分以上離れているときの計算用変数
			let _moreThanOneTile;

			//先頭のキャラの移動方向によって、それぞれの変数に値を代入する
			if ( direction === 'up' ) {
				_samePrevX = 0;
				_samePrevY = 1
				_lessThanPrevX = -1;
				_lessThanPrevY = 0;
				_moreThanPrevX = 1;
				_moreThanPrevY = 2;
				_moreThanOneTile = -1;
			}
			else if ( direction === 'down' ) {
				_samePrevX = 0;
				_samePrevY = -1;
				_lessThanPrevX = -1;
				_lessThanPrevY = -2;
				_moreThanPrevX = 1;
				_moreThanPrevY = 0;
				_moreThanOneTile = 1;
			}
			else if ( direction === 'left' ) {
				_samePrevX = 1;
				_samePrevY = 0;
				_lessThanPrevX = 0;
				_lessThanPrevY = -1;
				_moreThanPrevX = 2;
				_moreThanPrevY = 1;
				_moreThanOneTile = -1;
			}
			else if ( direction === 'right' ) {
				_samePrevX = -1;
				_samePrevY = 0;
				_lessThanPrevX = -2;
				_lessThanPrevY = -1;
				_moreThanPrevX = 0;
				_moreThanPrevY = 1;
				_moreThanOneTile = 1;
			}

			//ひとつ前のキャラとX,Y座標が同じとき
			if ( this.member[i-1].mapX === this.member[i].mapX ) this.member[i].vx = this.speed * _samePrevX;
			if ( this.member[i-1].mapY === this.member[i].mapY ) this.member[i].vy = this.speed * _samePrevY;

			//ひとつ前のキャラのほうが、X座標が小さいとき
			if ( this.member[i-1].mapX < this.member[i].mapX ) {
				this.member[i].vx = this.speed * _lessThanPrevX;
				//先頭のキャラの移動方向が左で、ひとつ前のキャラとのX座標の差が、タイルひとつよりも大きいとき
				if ( direction === 'left' && this.member[i].mapX - this.member[i-1].mapX > 1 ) this.member[i].vx = this.speed * _moreThanOneTile;
			}
			//ひとつ前のキャラのほうが、X座標が大きいとき
			if ( this.member[i-1].mapX > this.member[i].mapX ) {
				this.member[i].vx = this.speed * _moreThanPrevX;
				//先頭のキャラの移動方向が右で、ひとつ前のキャラとのX座標の差が、タイルひとつよりも大きいとき
				if ( direction === 'right' && this.member[i-1].mapX - this.member[i].mapX > 1 ) this.member[i].vx = this.speed * _moreThanOneTile;
			}
			//ひとつ前のキャラのほうが、Y座標が小さいとき
			if ( this.member[i-1].mapY < this.member[i].mapY ) {
				this.member[i].vy = this.speed * _lessThanPrevY;
				//先頭のキャラの移動方向が上で、ひとつ前のキャラとのY座標の差が、タイルひとつよりも大きいとき
				if ( direction === 'up' && this.member[i].mapY - this.member[i-1].mapY > 1 ) this.member[i].vy = this.speed * _moreThanOneTile;
			}
			//ひとつ前のキャラのほうが、Y座標が大きいとき
			if ( this.member[i-1].mapY > this.member[i].mapY ) {
				this.member[i].vy = this.speed * _moreThanPrevY;
				//先頭のキャラの移動方向が下で、ひとつ前のキャラとのY座標の差が、タイルひとつよりも大きいとき
				if ( direction === 'down' && this.member[i-1].mapY - this.member[i].mapY > 1 ) this.member[i].vy = this.speed * _moreThanOneTile;
			}
		}
	} //setMemberVelocity() 終了
}

js/engine/sound.js

'use strict'

/**
 * Audioを使いやすくしたSoundクラス
 * Gameクラスから呼び出して使うので、普段は使わない
 */
class Sound extends Audio {

	/**
	 * 引数
	 * src : 音声ファイルまでのパス
	 */
	constructor( src ) {
		//親クラスのコンストラクタを呼び出す
		super( src );
		//autoplayを無効にする
		this.autoplay = false;
	} //constructor() 終了

	/**
	 * 音声を再生するためのメソッド
	 */
	start() {
		//ミュートを無効にする
		this.muted = false;
		//音声を再生
		this.play();
	} //start() 終了

	/**
	 * 音声をループで再生するためのメソッド
	 */
	loop() {
		//ループ再生されるようにする(superを使っているのは、Soundクラスにloopメソッドがあるため)
		super.loop = true;
		//音声を再生するメソッドを呼び出す
		this.start();
	} //loop() 終了

	/**
	 * 音声をストップするためのメソッド
	 */
	stop() {
		//音声を一時停止する
		this.pause();
		//再生場所を最初に戻す
		this.currentTime = 0;
	} //stop() 終了

}
アル

でもさ、こんなにたくさんのファイルを読み込むのもたいへんだよね……なにかいい方法ないのかな

山田

ふっふっふ。そういうと思ったべ
そんなときは、webpackを使うと便利だべよ

りこ

webpack?

山田

たくさんのJSファイルをひとつにまとめてくれるべ
くわしくは「webpackを使ってゲームエンジンを作ろう!(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で、画像つきのおみくじゲームを作ろう!
オリジナルゲーム.com