小学生からのプログラミング講座、第10弾です。
前回はHTML5とCanvasを使って、キャラクターがキーボードの入力で移動するところまで、紹介しました。
さて、今回は迷路ゲームやRPGなどで使える、マップの作り方を紹介したいと思います。

今日はマップの作り方を教えてくれるのね!

そうだべ。やっぱりキャラが動いたら、マップが欲しいべな

やったー、ポケモンっぽくなるね!
マップを作る前準備
まずはマップを作るための準備として、画像を用意しましょう。

ではこれからマップを作っていくべよ。つかう画像はこれだべよ。右クリックして「名前を付けて保存」で、保存するべよ

なにこれ?

小型のUSBメモリじゃない? パソコンにさして、データを保存できるやつ

へぇ、すごい! そんなのがあるのかー。りこちゃん、よく知ってるね!

えっへん!

床と壁だべ

はっ! //////

……えっ?
先ほどの画像をgameフォルダのimgフォルダのなかに、map.pngという名前で保存してください。
他のフォルダやファイルは、前回とおなじです。
game ├ index.html ├ img/ │ ├ map.png (これ) │ └ rico.png └ js/ └ script.js
map.pngは、左側が床、右側が壁のマップチップです。USBメモリではありません。
画像を切り取って表示してみよう!
先ほどの画像は、左右が床と壁で、一枚になってしまっています。
そんなときは、画像のどこからどこまでを表示するのかを指定することができます。
drawImage( image, sx, sy, sw, sh, dx, dy, dw, dh )
sx, syで、画像を読み込む部分の、左上の位置、
sw, shで、画像を読み込む部分の、幅と高さ、
dx, dyで、画像を表示する、左上の位置、
dw, dhで、画像を表示するときの大きさ、
となります。
実際に使うと、このようになります。
//canvasの設定(せってい) var canvas = document.getElementById( 'canvas' ); //コンテキストを取得(しゅとく) var ctx = canvas.getContext( '2d' ); //画像(がぞう)のオブジェクトを作る var img = new Image(); img.src = 'img/map.png'; //画像(がぞう)を表示(ひょうじ)する addEventListener('load', function() { ctx.drawImage( img, 0, 0, 32, 32, 0, 0, 32, 32 ); ctx.drawImage( img, 32, 0, 32, 32, 0, 64, 32, 32 ); }, false);

こうやって一枚の画像を分けて表示できるんだね

左右で一枚ずつだったんだ……

マップチップの1枚目と2枚目を切り替えたいときは、左から2番目の数字(imgの右)を変更するだけだべ

なるほど、便利だ
さて、今回はマップを作っていきたいのですが、そのためには新しいお願い方法を覚えなければなりません。
配列と、繰り返しです。
配列を使ってみよう!
配列とは、変数に添字を使って、いくつも変数があるように扱えるものです。

なんか、よく分かんないよ

わたしもー

なんか、よく分かんないよ

難しく考える必要はないべよ。例えばりこちゃん、関ジャニのメンバーを全員言えるべか?

えっと、錦戸くんでしょ、丸山くんでしょ、大倉くん、村上くん、横山くん、安田くん……

では、関ジャニのメンバーを配列を使って表示してみるべ
関ジャニのメンバーは現在6人です。
では、メンバーをkanjaniという配列に覚えておいてもらいましょう。
var kanjani = [ '丸山くん', '大倉くん', '村上くん', '横山くん', '錦戸くん', '安田くん' ];

こうやって覚えておいてもらうと、なにか便利なの?

配列を使うと、このなかからかんたんにメンバーを呼び出せるんだべ
では、メンバーの中から、りこちゃんの大好きな「錦戸くん」をとりだしてみましょう。
とりだすには、kanjani[4]というように、添字を使います。4というのは、0から数えて4番目に「錦戸くん」のデータがあるからです。
var kanjani = [ '丸山くん', '大倉くん', '村上くん', '横山くん', '錦戸くん', '安田くん' ]; alert ( kanjani[4] );
じっさいにブラウザで見てみると、このようになります。
また、メンバーの人数を見ることもできます。
kanjaniという配列が、データをいくつ覚えているかを見ればいいので、length
を使います。
var kanjani = [ '丸山くん', '大倉くん', '村上くん', '横山くん', '錦戸くん', '安田くん' ]; alert ( kanjani.length );
じっさいにブラウザで見てみると、このようになります。

つまり、配列は変数の横に数字をつけて、いくつもの変数があるように使えるものなんだべ。間違えやすい部分は、1から数えるんじゃなく、0から数えるというところだべ

kanjaniっていう変数ひとつで、関ジャニのメンバー全員のデータを覚えておいてもらうことができるのね!

さらに、こんなこともできるんだべ。りこちゃんは関ジャニ以外で好きなグループはいるべか?

え、えっと……Sexy Zone!

そのなかでは、誰が好きだべ?

うんと、佐藤くんかな
johnnysという配列をつくり、関ジャニのメンバーとSexy Zoneのメンバーを、2列に入力しました。
上に関ジャニのメンバー、下にSexy Zoneのメンバーです。
var johnnys = [ [ '丸山くん', '大倉くん', '村上くん', '横山くん', '錦戸くん', '安田くん' ], [ '中島くん', '菊池くん', '佐藤くん', '松島くん', 'マリウスくん' ] ]; alert ( johnnys[1][2] );
りこちゃんの好きな佐藤くんは、上から2番目、0から数えると1番目になります。
さらに左から3番目、0から数えると2番目になります。
なので、「佐藤くん」のデータを取り出したいときは、johnnys[1][2]
となります。
じっさいにブラウザで見てみると、このようになります。

こういうふうに、何重にもなった配列を多次元配列というから、覚えておくべ!
繰り返しを使ってみよう!
続いて、繰り返しについて学んでいきましょう。

繰り返しってこの前のメインループとは違うの?

あれは関数で自分自身を呼び出して無限ループしているんだべ。それとは別のやりかただべよ。いくつかやり方があるべけれども、今回はまず、この2つを覚えるべよ
for文を使ってみよう!
for文は、一番ポピュラーな繰り返しのお願いです。
for
のなかで、変数iを宣言します。i++
というのは、iに1ずつ足していく、ということです。
なので、iが5より小さい場合は1ずつ足していくことで、5回繰り返すという意味になります。
for (var i=0; i<5; i++) { alert( '5回繰り返すよ!' ); }
while文を使ってみよう!
whileは、条件がtrue(真)のときに繰り返すものです。
var x = 0; while ( x < 5 ) { alert( '5回繰り返すよ!' ); x++; }
上の例では、最初にxに0を覚えておいてもらい、その数が5よりも小さい場合は繰り返すというものです。x++
によって、xを1ずつ増やしているので、その数が5になったら繰り返しを終了します。

繰り返しをつかう時の注意点は、永遠に終わらない条件を作ってはいけないべよ

どういうこと?

例えば、以下のようにすると永遠に「xは0です」というアラートが表示されるべよ
var x = 0; while ( x === 0 ) { alert( 'xは0です' ); }

永遠の0だべよ……

なるほど……えっ?

えっ?

えっ?
マップを作ってみよう!
これまでの記事と、配列、繰り返しが分かれば、マップも自在につくることができます。
アル

マップってどうやってつくるのか、全然想像がつかないよ
山田

数字でマップを表現すればいいだべよ
りこ

数字で?
プログラミングでマップを表現するには、数字を使います。
マップチップの、左側を0、右側を1とします。
//canvasの設定(せってい) var canvas = document.getElementById( 'canvas' ); canvas.width = 640; //canvasの横幅(よこはば) canvas.height = 640; //canvasの縦幅(たてはば) //コンテキストを取得(しゅとく) var ctx = canvas.getContext( '2d' ); //マップチップのImageオブジェクトを作る var mapchip = new Image(); mapchip.src = 'img/map.png'; //マップの作成(さくせい) var map = [ [0, 0, 1, 0, 1, 0, 0, 0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0], [0, 1, 0, 0, 0, 1, 1, 1 ,0 ,1 ,0 ,1 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,0], [0, 0, 1, 1, 0, 0, 0, 1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0], [1, 0, 1, 0, 1, 1, 0, 0 ,0 ,1 ,1 ,1 ,1 ,1 ,0 ,0 ,1 ,0 ,1 ,0], [0, 0, 0, 0, 0, 1, 1, 1 ,0 ,1 ,0 ,0 ,0 ,0 ,1 ,1 ,0 ,1 ,1 ,0], [0, 1, 1, 1, 0, 0, 0, 0 ,0 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,0 ,0 ,0 ,0], [0, 1, 1, 1, 0, 1, 1, 1 ,1 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,0], [0, 0, 0, 1, 0, 0, 0, 0 ,1 ,0 ,0 ,1 ,0 ,1 ,1 ,0 ,0 ,0 ,1 ,0], [1, 1, 0, 1, 1, 1, 1, 1 ,1 ,0 ,1 ,1 ,0 ,0 ,1 ,1 ,1 ,0 ,1 ,1], [1, 0, 0, 0, 0, 0, 1, 1 ,0 ,0 ,0 ,0 ,1 ,0 ,1 ,1 ,0 ,0 ,1 ,0], [1, 0, 1, 1, 1, 0, 0, 0 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,1 ,0 ,0], [1, 0, 1, 0, 1, 1, 1, 0 ,1 ,0 ,1 ,1 ,0 ,1 ,1 ,0 ,0 ,0 ,0 ,1], [0, 0, 1, 0, 0, 1, 0, 0 ,1 ,0 ,0 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,0 ,0], [0, 1, 1, 1, 0, 1, 0, 1 ,0 ,0 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,0 ,1 ,0], [0, 0, 0, 1, 0, 1, 0, 0 ,1 ,0 ,1 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0], [1, 1, 0, 1, 0, 1, 0, 1 ,1 ,0 ,0 ,1 ,0 ,1 ,1 ,0 ,1 ,1 ,1 ,0], [0, 0, 0, 1, 0, 1, 1, 1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,0 ,0 ,0 ,1 ,0], [0, 1, 1, 1, 0, 1, 0, 0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,1 ,0 ,1 ,1], [0, 1, 0, 0, 0, 1, 0, 1 ,1 ,1 ,0 ,0 ,1 ,1 ,0 ,1 ,0 ,0 ,0 ,0], [0, 0, 0, 1, 0, 0, 0, 1 ,1 ,1 ,1 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,0] ]; //マップチップを表示(ひょうじ)する addEventListener('load', function() { for (var y=0; y<map.length; y++) { for (var x=0; x<map[y].length; x++) { if ( map[y][x] === 0 ) ctx.drawImage( mapchip, 0, 0, 32, 32, 32*x, 32*y, 32, 32 ); if ( map[y][x] === 1 ) ctx.drawImage( mapchip, 32, 0, 32, 32, 32*x, 32*y, 32, 32 ); } } }, false);
14行目で、mapという配列を作り、そこにマップを0と1で書いていきます。
実際にマップを表示するには、for
を使って、数字に該当する画像を表示していきます。
39行目のfor
でy座標のぶん繰り返し、40行目のfor
でx座標のぶん繰り返します。
それぞれ、map.length
やmap[y].length
とすることで、yやxにいくつマップチップのデータがあるかが分かります。これで、何回繰り返すのかを判断することができます。
41行目、42行目で、0か1かどちらの画像かを判断し、表示します。
マップチップ一枚の大きさは32pxなので、表示するとき、xやyに32をかけ算してあげることで、実際のマップの場所になります。
ブラウザで見てみると、このようになります。

すごい! 迷路みたいなマップができてるよ!

ここを私が冒険するのね!

そうなんだべ。だけれども、ここでりこちゃんが歩くプログラムを加えても、まだ壁との衝突判定を作っていないから、壁の上を歩けてしまうんだべ

それはそれでかっこいいけど、ゲームにはならないよね

壁との衝突判定は、次回の記事で紹介していくから、おたのしみにするべ!
まとめ
今回は迷路ゲームやRPGでつかえる、マップの作り方について紹介しました。
プログラミングでマップを作成するときも、文字を使って作っていきます。
ちょっと難しいかもしれないのですが、これができればゲーム開発の幅がかなり広がります。
ぜひ、挑戦してみてください。

きゃー、私、こんなところを歩いたら、迷子になっちゃう!

なに言ってんだよ。ゲームなんだから

わだずなら、一瞬でクリアできるべ

ホント!?

すごーい!

ネコは壁なんてのぼればいいべからな

……

ずるい!

まぁまぁ。次回は壁との当たり判定を作っていくべよ!

はーい!

はーい!
この企画の一覧はこちら
- 小学生からのプログラミング入門。プログラミングってなぁに?
- Scratchの使い方と、ゲーム作りの基礎知識を学ぼう! 小学生からのプログラミング入門
- Scratchでじゃんけんゲームを作ろう! 小学生からのプログラミング入門
- Scratchでシューティングゲームを作ろう! 小学生からのプログラミング入門
- Scratchでピアノ鍵盤を作って音を鳴らそう! 小学生からのプログラミング入門
- JavaScriptでおみくじを作ろう! 小学生からのプログラミング入門
- JavaScriptで今月の残り日数を計算してみよう! 小学生からのプログラミング入門
- JavaScriptで画像を表示してみよう! 小学生からのプログラミング入門
- JavaScriptで画像を移動してみよう! 小学生からのプログラミング入門
- 【JavaScript】キー入力でキャラを動かしてみよう! 小学生からのプログラミング入門
- 【JavaScript】ファイルを分けて管理してみよう! 小学生からのプログラミング入門
- 【JavaScript】オブジェクトを使ってみよう! 小学生からのプログラミング入門
- 【JavaScript】ゲームのメインループを作ってみよう! 小学生からのプログラミング入門
- 【JavaScript】キャラを決まった間隔ずつ動かす! 小学生からのプログラミング入門
- HTML5とCanvasを使ってみよう! 小学生からのプログラミング入門
- 【JavaScript】迷路やRPGで使えるマップを作ってみよう! 小学生からのプログラミング入門
- 【JavaScript】マップでキャラを動かせるようにしよう! 小学生からのプログラミング入門
- 【JavaScript】クラスの概念をしっかりと理解しよう! 小学生からのプログラミング入門
- 【JavaScript】プログラム全体をクラスを使って作ってみよう! 小学生からのプログラミング入門
- 【JavaScript】文字を表示するクラスを作ってみよう! 小学生からのプログラミング入門
- 【JavaScript】改行と一文字ずつ画面に表示する方法! 小学生からのプログラミング入門
- 【JavaScript】ノベルゲーム風にキー入力で文字を切り替える方法! 小学生からのプログラミング入門
マップの配列の最後、セミコロン抜けてませんか?