小学生からのプログラミング講座、今回もはじめていきましょう!
前回はプログラミングにおける、クラスの使い方を学びました。
しかし、まだクラスをどうやって使えばいいのか、ピンときていないかもしれません。
そこで今回は、これまで作成してきたゲームを、クラスを使ったものに書き換えていきたいと思います。

クラスを使うと、プログラムがとても見やすいものになるんだべ

どうプログラムが変わっていくんだろう? 楽しみ!
スプライトクラスを作ろう!
スプライトは「動かしたい画像」のことです。
Scratchにもあったスプライトと同じです。ではスプライトのためのクラスを作ってみましょう。
class Sprite {
	constructor( img, left, top ) {
		this.left = left || 0;
		this.top = top || 0;
		this.img = new Image();
		this.img.src = img;
		this.width = 32;
		this.height = 32;
	}
}2行目、コンストラクタの部分に、img、left、topというふうに書かれています。
これは「どの画像」の「左から何px」「上から何px」の部分かを指定するものです。
では次の画像を使うとします。

りこちゃん、山田先生、アル君が、1つの画像のなかにあります。
この中から、アル君のスプライトを作りたいとします。
するとアル君は左から65px、上から0pxの場所にありますので、その場所を指定してあげます。

スプライトを作りたいと思ったら、さっき作ったスプライトクラスのメンバーに入れてあげれば、スプライトになるんだべ

どうやってやるんだっけ?

こんなふうにすればいいべ!
let aru = new Sprite( 'img/character.png', 65, 0 );letというのは ES6から使えるようになった、変数を使うよと宣言するためのコマンドです。
使い方はvarと同じですが、変数の有効範囲が異なります。
letでaruを宣言し、aruをSpriteクラスのメンバーに入れてあげます。
Spriteの後ろには、()をつけて、画像のパスと画像のどの部分をスプライトにするかを指定します。
そうすることで、アル君のスプライトが作られるのです。
今回は1つの画像を縦横32pxの大きさにあらかじめ決めてあるので、左と上のpx数だけ指定すればその画像が表示されます。

でもこれだとまだスプライトは表示されないよ

じつはそうなんだべ。そこでゲームクラスを作って、スプライトをゲーム上に表示できるようにするべ
ゲームクラスを作ろう!
さて、スプライトクラスには、ゲーム上にスプライトを表示させる機能をつけていません。
スプライトの表示はゲームクラスに作っていきます。
class Game {
	constructor( width, height ) {
		this.width = width || 320;
		this.height = height || 320;
 
		canvas = document.getElementById( 'canvas' );
		canvas.width = this.width;		//canvasの横幅(よこはば)
		canvas.height = this.height;		//canvasの縦幅(たてはば
 
		ctx = canvas.getContext( '2d' );
	}
	add( sprite, x, y ) {
		if ( typeof x === "undefined" ) sprite.x = 0;
		else sprite.x = x;
		if ( typeof y === "undefined" ) sprite.y = 0;
		else sprite.y = y;
		ctx.drawImage( sprite.img, sprite.left, sprite.top, sprite.width, sprite.height, sprite.x, sprite.y ,sprite.width, sprite.height );
	}
}ゲームクラスでは、実際のゲームで使うcanvasの表示や設定などを行います。
また、14〜20行目で、add()を使ってスプライトをゲーム上に表示できるようにしています。
以下のようにすると縦横640pxのゲームの画面をつくることができます。
let game = new Game( 640, 640 );りこちゃん、山田先生、アル君のオブジェクトを作成し、さきほどゲームクラスで作成したadd()を使って、メインループ内でスプライトを呼び出します。
〜省略(さきほど作ったクラスや、グローバル変数)〜
 
let game = new Game( 640, 640 );
 
let rico = new Sprite( 'img/character.png' );
let yamada = new Sprite( 'img/character.png', 33, 0 );
let aru = new Sprite( 'img/character.png', 65, 0 );
 
function main() {
	//キャラクターのスプライトを表示
	game.add( rico, 0, 0 );
	game.add( aru, 32, 64 )
	game.add( yamada, 96, 96 );
 
	requestAnimationFrame( main );
}
addEventListener('load', main(), false);
あらかじめクラスを作っておけば、こんなに簡単にゲームの画面やスプライトを表示できるようになるのね!


わー、僕たち3人が表示されてる!
入力(Input)クラスを作ろう!
続いて、Inputクラスを作ってみます。
Inputは「入力する」という意味で、キー入力のためのクラスとします。
class Input {
	constructor() {
		this.up = false;
		this.left = false;
		this.down = false;
		this.right = false;
	}
	push_key() {
		addEventListener( "keydown", () => {
			const key_code = event.keyCode;
			if( key_code === 37 ) this.left = true;
			if( key_code === 38 ) this.up = true;
			if( key_code === 39 ) this.right = true;
			if( key_code === 40 ) this.down = true;
			event.preventDefault();		//方向キーでブラウザがスクロールしないようにする
		}, false);
		addEventListener( "keyup", () => {
			const key_code = event.keyCode;
			if( key_code === 37 ) this.left = false;
			if( key_code === 38 ) this.up = false;
			if( key_code === 39 ) this.right = false;
			if( key_code === 40 ) this.down = false;
		}, false);
	}
}このInputクラスは、あらかじめよく使うと思うボタンを設定しておいて、そのボタンが押されているかどうかを判断するものです。
今回はそれぞれの方向キーが押されているかどうかを判断できるようにしました。
inputオブジェクトを作ります。
let input = new Input();あとは、push_key()を呼び出し、条件分岐でキーが入力されたときにどうしたいのかを書いていきます。
例えばこのようにすると、左キーが押されている間xから6ずつ引いていくというプログラムになります。
function main() {
	input.push_key();
	if ( input.left === true ) x-=6;
	requestAnimationFrame( main );
}
addEventListener('load', main(), false);
これでキャラ移動もつくれそうだね!
プログラム全体をクラスを使って書いてみよう!
では、プログラム全体をクラスを使って書いてみます。
'use strict';
 
//グローバル変数
let canvas;
let ctx;
 
//マップの作成(さくせい)
let 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]
]
 
 
//スプライトクラス
//img : スプライトに使う画像
//left : 画像の左から何ピクセルの部分を使うか
//top : 画像の上から何ピクセルの部分を使うか
class Sprite {
	constructor( img, left, top ) {
		this.left = left || 0;
		this.top = top || 0;
		this.img = new Image();
		this.img.src = img;
		this.width = 32;
		this.height = 32;
	}
}
 
//ゲームクラス
//width : ゲーム全体の横幅
//height : ゲーム全体の縦幅
//
//add() : ゲームにスプライトを表示
class Game {
	constructor( width, height ) {
		this.width = width || 320;
		this.height = height || 320;
 
		canvas = document.getElementById( 'canvas' );
		canvas.width = this.width;		//canvasの横幅(よこはば)
		canvas.height = this.height;		//canvasの縦幅(たてはば
 
		ctx = canvas.getContext( '2d' );
	}
	add( sprite, x, y ) {
		if ( typeof x === "undefined" ) sprite.x = 0;
		else sprite.x = x;
		if ( typeof y === "undefined" ) sprite.y = 0;
		else sprite.y = y;
		ctx.drawImage( sprite.img, sprite.left, sprite.top, sprite.width, sprite.height, sprite.x, sprite.y ,sprite.width, sprite.height );
	}
}
 
//入力(Input)クラス
//up : 上キー
//left : 左キー
//down : 下キー
//right : 右キー
class Input {
	constructor() {
		this.up = false;
		this.left = false;
		this.down = false;
		this.right = false;
	}
	push_key() {
		addEventListener( "keydown", () => {
			const key_code = event.keyCode;
			if( key_code === 37 ) this.left = true;
			if( key_code === 38 ) this.up = true;
			if( key_code === 39 ) this.right = true;
			if( key_code === 40 ) this.down = true;
			event.preventDefault();		//方向キーでブラウザがスクロールしないようにする
		}, false);
		addEventListener( "keyup", () => {
			const key_code = event.keyCode;
			if( key_code === 37 ) this.left = false;
			if( key_code === 38 ) this.up = false;
			if( key_code === 39 ) this.right = false;
			if( key_code === 40 ) this.down = false;
		}, false);
	}
}
 
//inputオブジェクトの作成
let input = new Input();
 
//プレイヤークラス
//x : プレイヤーのx座標
//y : プレイヤーのy座標
//move : プレイヤーをうまく動かすためのもの
//
//move_sp() : プレイヤーのスプライトを動かす
class Player {
	constructor(x, y) {
		this.sprite = new Sprite( 'img/character.png' );
		this.x = x;
		this.y = y;
		this.move = 0;
	}
	move_sp() {
		input.push_key();
		game.add( this.sprite, this.x, this.y );
		if ( this.move === 0 ) {
			if ( input.left === true ) {
				var x = this.x/32;
				var y = this.y/32;
				x--;
				if ( map[y][x] === 0 ) {
					this.move = 32;
					input.push = 'left';
				}
			}
			if ( input.up === true ) {
				var x = this.x/32;
				var y = this.y/32;
				if ( y > 0) {
					y--;
					if ( map[y][x] === 0 ) {
						this.move = 32;
						input.push = 'up';
					}
				}
			}
			if ( input.right === true ) {
				var x = this.x/32;
				var y = this.y/32;
				x++;
				if ( map[y][x] === 0 ) {
					this.move = 32;
					input.push = 'right';
				}
			}
			if ( input.down === true ) {
				var x = this.x/32;
				var y = this.y/32;
				if ( y < 19 ) {
					y++;
					if ( map[y][x] === 0 ) {
						this.move = 32;
						input.push = 'down';
					}
				}
			}
		}
 
		//this.moveが0より大きい場合は、4pxずつ移動(いどう)を続ける
		if (this.move > 0) {
			this.move -= 4;
			if ( input.push === 'left' ) this.x -= 4;
			if ( input.push === 'up' ) this.y -= 4;
			if ( input.push === 'right' ) this.x += 4;
			if ( input.push === 'down' ) this.y += 4;
		}
	}
}
 
//ゲームオブジェクトの作成
let game = new Game( 640, 640 );
 
//プレイヤーのオブジェクトを作成
let player = new Player( 0, 0 );
 
//キャラクターのオブジェクトを作成
let yamada = new Sprite( 'img/character.png', 33, 0 );
let aru = new Sprite( 'img/character.png', 65, 0 );
 
//床、壁のマップチップのオブジェクトを作成
let floor = new Sprite( 'img/map.png', 0, 0 );
let wall = new Sprite( 'img/map.png', 33, 0 );
 
//メインループ
function main() {
	//塗(ぬ)りつぶす色を指定(してい)
	ctx.fillStyle = "rgb( 0, 0, 0 )";
	//塗(ぬ)りつぶす
	ctx.fillRect(0, 0, 640, 640);
 
	//マップを表示する
	for (var y=0; y<map.length; y++) {
		for (var x=0; x<map[y].length; x++) {
			if ( map[y][x] === 0 ) game.add( floor, 32*x, 32*y );
			if ( map[y][x] === 1 ) game.add( wall, 32*x, 32*y );
		}
	}
 
	//キャラクターのスプライトを表示
	player.move_sp();
	game.add( aru, 32, 64 );
	game.add( yamada, 96, 96 );
 
	requestAnimationFrame( main );
}
addEventListener('load', main(), false);
まとめ
今回はプログラム全体を、クラスを使ったものに書き換えてみました。
クラスを使うことで、ソースコードが綺麗に整理され、後からみたときも分かりやすくなります。
ぜひクラス使い方をマスターしましょう!

スプライトクラスを作っておくと、簡単にスプライトをつくることができるべ。 クラスの便利さはわかってもらえたべか?

うん、クラスって便利なんだね

どこに何が書いてあったか悩むのも少なくなるね

今回はわだずやアル君のスプライトも表示したべけど、まだ突っ立っているだけなんだべよ

なにか喋ったりとかさせたいよね

みんなで一緒に冒険にでかけるのもいいべ。 どんどんゲームらしくなるから、今後の記事を楽しみにするべよ

はーい!

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











