小学生からのプログラミング講座、今回もはじめていきましょう!
前回はプログラミングにおける、クラスの使い方を学びました。
しかし、まだクラスをどうやって使えばいいのか、ピンときていないかもしれません。
そこで今回は、これまで作成してきたゲームを、クラスを使ったものに書き換えていきたいと思います。
クラスを使うと、プログラムがとても見やすいものになるんだべ
どうプログラムが変わっていくんだろう? 楽しみ!
スプライトクラスを作ろう!
スプライトは「動かしたい画像」のことです。
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で、画像つきのおみくじゲームを作ろう!