1. HOME
  2. »
  3. プログラミング・Web
  4. »
  5. JavaScript
  6. »
  7. JavaScript|ノベルゲーム風にキー入力で文字を切り替える方法!

JavaScript|ノベルゲーム風にキー入力で文字を切り替える方法!

小学生からのJavaScript講座です。

前回、文字を一文字づつ表示させる方法と改行の方法を紹介しました。
今回はこのプログラムに、キー入力によって文字を切り替えられる機能をつけてみましょう。

アル

ゲームはやっぱりキー入力で順番に物語を読んでいきたいよね


りこ

今日はそれを教えてもらえるんでしょ? 山田先生のところに行ってみようよ!


アル

うん!

前回までのプログラムについて

前回までで、文字を一文字ずつ表示させ、改行するプログラムができています。

javascript

山田

こんなプログラムだったべな……でも、長い文章を入力した場合、画面が文字で埋まってしまうんだべよ


りこ

そうならないようにキー入力で次の文章に切り替えられるようにして、一文ずつ表示されるようにしたいね!

配列を使って文章を作っていこう

文字を切り替えられるようにするには、配列(はいれつ)を使って文章を入力しておくと便利です。

山田

小学生からのJavaScript。迷路やRPGで使えるマップを作ってみよう!で紹介した、配列の使い方は覚えてるべか?


アル

そういえば、そんなのがあったような……


山田

忘れてしまったならば、そのページで復習してからこの先へ進んでいくべよ

まず、配列を使わない場合、文字を変数に代入するには以下のようにします。

const str = '吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。';

上を配列を使うとこのようになります。
ここでは、切り替えたい文章ごとに区切っています。

const str = [
	'吾輩は猫である。',
	'名前はまだ無い。',
	'どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。'
];

アル

配列って、ジャニーズのメンバーを覚えさせておくだけじゃなくて、こんな使い方もできるんだね。


りこ

配列の何番目かによって文字を切り替えるのね!

上の配列を使った例では、つまりこのように代入されていることになります。

str[0] : 吾輩は猫である。
str[1] : 名前はまだ無い。
str[2] : どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。

つまり、配列の添字(そえじ)を指定することで、文字が切り替わるというふうになります。
なので、スペースキーで文字を切り替えたい時は、スペースキーが押された時に添字の数値を1増やすというふうに作ります。

配列からのデータを表示できるようにしてみよう!

このままだとまだ画面に文字は表示されません。
game.jsファイルをなおして、画面に配列からのデータを表示できるようにしてみましょう。

前回作ったgame.jsファイルのLabelクラスを変更していきます。
変更した場所は5,6行目、19行目、23行目、30行目、33行目です。

//Labelクラス
class Label {
  //Labelの初期設定
  constructor( label ) {
    //表示している場所の行数(追加)
    this._visibleLine = 0;
    //〜省略〜
  }
 
  //Labelを表示するための関数(メインループから呼び出される)
  render( ctx, frame ) {
    ctx.fillStyle = this.color;
    ctx.font = this.font;
    ctx.textBaseline = this.baseline;
 
    //文字を表示する間隔(はやさ)が0の場合は、文字を一気に表示
    if ( this.interval === 0 ) {
      //表示する文字数を、1行に表示する最大の文字数で割り、切り上げることで、その文字列が何行になるのかが分かる
      this._line = Math.ceil( this.label[ this._visibleLine ].length/this.maxLength ); //変更
      //文字列の行数だけ繰り返す
      for( var i=0; i<this._line; i++ ) {
        this._text[i] = this._text[i] || '';
        this._text[i] = this.label[ this._visibleLine ].substr( i*this.maxLength, this.maxLength ); //変更
        //文字列の表示
        ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
      }
    }
    //文字を表示する間隔(はやさ)が0以外の場合、一文字ずつ表示していく
    else {
      if( this._displayLength < this.label[ this._visibleLine ].length && frame%this.interval === 0 ) { //変更
        this._text[this._line] = this._text[this._line] || '';
        //this.labelに代入されている文字列を、this._text[this._line]に一文字ずつ入れていく
        this._text[this._line] += this.label[ this._visibleLine ].charAt( this._displayLength ); //変更
        this._displayLength++;
        if ( this._displayLength % this.maxLength === 0 ) {
          this._line++;
        }
      }
      for( var i=0; i<this._line+1; i++ ) {
        this._text[i] = this._text[i] || '';
        ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
      }
    }
  }
}

山田

上の例だとthis.label[0]を表示させていることになるんだべ


りこ

this._visibleLineには0が代入されているからだね!

実際にブラウザで見ると、このようになります。
javascript

山田

ちなみに6行目でthis._visibleLineに1を代入すると「名前はまだ無い。」と表示され、2を代入すると「どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。」と表示されるんだべ


アル

キー入力があったらこの数値を切り替えるっていうプログラムを作ればいいんだね?

文字を切り替える関数を作ろう

文字を切り替える命令を書いていきたいのですが、今回は文字を切り替える為の関数を作る方法にしましょう。

山田

文字を切り替える関数を作っていくべ!


アル

うん!


山田

今回は「次へ」ということで、「next()」という関数にしてみたべ

class Label {
	//Labelの初期設定
	constructor( label ) {
		//〜省略〜
	}
	
	//次の行への切り替え機能
	next() {
		this._visibleLine++;
		this._text = [];
		this._displayLength = 0;
	}

	//Labelを表示するための関数(メインループから呼び出される)
	render( ctx, frame ) {
		//〜省略〜
	}
}

このthis._visibleLine++;で次の行へ、this._text = [];this._displayLength = 0;で、今代入されている文字や数値を初期化しています。

山田

これで文章を切り替えられるようになったべ。でも3行しか入力していないべから、3回スペースキーを押すと、エラーになって何も表示されなくなってしまうべ。エラーはコンソールを見ると分かるべよ。
このエラーの回避(かいひ)方法はまた別の記事で学んでいくべ

枠内をクリックして、スペースキーを押してみてね!

全体のソース

最後に全体のソースを確認しておきましょう。

game.js

'use strict';

//Gameクラス
class Game {
	constructor( width, height ) {
		this.objs = [];

		this.frame = 0;

		//もしもwidthやheight何も代入されていなければ、320を代入する
		this.width = width || 320;
		this.height = height || 320;

		this.canvas = document.getElementById( 'canvas' );
		//canvasの横幅とたて幅
		canvas.width = this.width;
		canvas.height = this.height;

		this.ctx = canvas.getContext( '2d' );
	}

	//start()を呼び出すことで、メインループが開始される。
	start() {
		this._main();
	}

	//メインループ
	_main() {
		//背景を黒く塗りつぶす
		this.ctx.fillStyle = "#000";
		this.ctx.fillRect( 0, 0, this.width, this.height );

		//ゲームに登場するものの数だけ繰り返す
		for (let i=0; i<this.objs.length; i++) {
			//ゲームに登場するもののクラスから、render()を呼び出す
			this.objs[i].render( this.ctx, this.frame );
		}

		//フレーム
		this.frame++;

		//_main()を呼び出す(ループさせる)
		requestAnimationFrame(this._main.bind(this));
	}

	//ゲームにテキストなどを表示するための関数
	add( obj, x, y ) {
		obj.x = x || 0;
		obj.y = y || 0;
		this.objs.push( obj );
	}
}

//Labelクラス
class Label {
	//Labelの初期設定
	constructor( label ) {
		this._text = [];
		//表示している文字列の長さ
		this._displayLength = 0;
		//表示している場所の行数(追加)
		this._visibleLine = 0;
		this._line = 0;
		this.label = label;
		this.font = "20px 'ヒラギノ角ゴ Pro', 'Hiragino Kaku Gothic Pro', 'MS ゴシック', 'MS Gothic', sans-serif";
		this.color = '#fff';
		this.maxLength = 30;
		this.baseline = 'top';
		this.interval = 0;
	}

	//次の行への切り替え機能
	next() {
		this._visibleLine++;
		this._text = [];
		this._displayLength = 0;
	}

	//Labelを表示するための関数(メインループから呼び出される)
	render( ctx, frame ) {
		ctx.fillStyle = this.color;
		ctx.font = this.font;
		ctx.textBaseline = this.baseline;

		//文字を表示する間隔(はやさ)が0の場合は、文字を一気に表示
		if ( this.interval === 0 ) {
			//表示する文字数を、1行に表示する最大の文字数で割り、切り上げることで、その文字列が何行になるのかが分かる
			this._line = Math.ceil( this.label[ this._visibleLine ].length/this.maxLength );
			//文字列の行数だけ繰り返す
			for( var i=0; i<this._line; i++ ) {
				this._text[i] = this._text[i] || '';
				this._text[i] = this.label[ this._visibleLine ].substr( i*this.maxLength, this.maxLength );
				//文字列の表示
				ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
			}
		}
		//文字を表示する間隔(はやさ)が0以外の場合、一文字ずつ表示していく
		else {
			if( this._displayLength < this.label[ this._visibleLine ].length && frame%this.interval === 0 ) {
				this._text[this._line] = this._text[this._line] || '';
				//this.labelに代入されている文字列を、this._text[this._line]に一文字ずつ入れていく
				this._text[this._line] += this.label[ this._visibleLine ].charAt( this._displayLength );
				this._displayLength++;
				if ( this._displayLength % this.maxLength === 0 ) {
					this._line++;
				}
			}
			for( var i=0; i<this._line+1; i++ ) {
				this._text[i] = this._text[i] || '';
				ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
			}
		}
	}
}

script.js

'use strict';
 
const str = [
	'吾輩は猫である。',
	'名前はまだ無い。',
	'どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。'
];

//ゲームのオブジェクトを640×480サイズで作る
let game = new Game( 640, 480 );
 
//ラベルオブジェクトを作る
let label = new Label( str );
label.interval = 5;
label.maxLength = 32;
 
//add()を使って、ゲームにラベルを表示
game.add( label, 0, 0 );

//キーボードが押された時
addEventListener( "keydown", () => {
	const key_code = event.keyCode;
	//先ほど登録したスペースキーが押された時、label.next()を実行
	if( key_code === 32) label.next();
	event.preventDefault();		//方向キーでブラウザがスクロールしないようにする
}, false);

//ゲームスタート
game.start();

まとめ

今回はキー入力で文字を切り替える方法を紹介しました。

アル

これで長い文章も順番に表示できるね!


りこ

これで私と錦戸くんのラブラブノベルゲームがつくれるのね! きゃー!


アル

またそれかよ……ちぇっ


りこ

夏は錦戸くんと海水浴、冬は私が編んだマフラーを錦戸くんにプレゼントするの


山田

毛糸なら、わたすの毛を使って作るといいべよ。うぇ……おぇ……。はぁすっきりだべ。ほら、毛玉が出てきたべよ。


りこ

……


アル

絶対いらない……

この企画の一覧はこちら

  1. 小学生からのプログラミング入門。JavaScriptでおみくじを作ろう!
  2. 小学生からのJavaScript入門。今月の残り日数を計算してみよう!
  3. 小学生からのJavaScript入門。画像の表示と移動をしてみよう!
  4. 小学生からのJavaScript入門。キー入力でキャラを動かしてみよう!
  5. 小学生からのJavaScript入門。ファイルを分けて管理してみよう!
  6. 小学生からのJavaScript入門。オブジェクトを使ってみよう!
  7. 小学生からのJavaScript入門。ゲームのメインループを作ってみよう!
  8. 小学生からのJavaScript入門。キャラを決まった間隔ずつ動かす!
  9. 小学生からのJavaScript。HTML5とCanvasを使ってみよう!
  10. 小学生からのJavaScript。迷路やRPGで使えるマップを作ってみよう!
  11. 小学生からのJavaScript。マップでキャラを動かせるようにしよう!
  12. 小学生からのJavaScript。クラスの概念をしっかりと理解しよう!
  13. 小学生からのJavaScript。プログラム全体をクラスを使って作ってみよう!
  14. 小学生からのJavaScript。文字を表示するクラスを作ってみよう!
  15. 小学生からのJavaScript。改行と一文字ずつ画面に表示する方法!
  16. JavaScript|ノベルゲーム風にキー入力で文字を切り替える方法!

スポンサードリンク

関連コンテンツ

オススメ記事

これから作る WordPress のテーマをローカルサイトに適用させる。

WordPress と AliExpress って混乱しますよね。@It_is_Rです。せーへんわ。 WordPress テーマ自作シリーズ、第三回目です。 前回までで、ローカルで Wor

FC2 blog customize

FC2ブログ ”最強” カスタマイズ入門講座。【準備編】

いつもどうもです。@It_is_Rです。 少し前まで、私は FC2ブログ を使っていました。 やはり個性を大切にしたい私にとって、用意されたテンプレートを使うことに抵抗がありました。 「

WordPress テーマ自作 | 本格的に作りたい人が揃えるべきツールや知識。

時計を見るとなぜか悲しくなります。@It_is_Rです。 今回から、いくつかの記事に渡って、 WordPress のテーマ(テンプレート)を自作する方法を紹介していきたいと思います。 しかし、

enchant.js

enchant.js でクラスを作る、激分かりやすい方法!

こんばんわ、ちょっと海外へ行っておりました@It_is_Rです。 前回までの enchant.js の記事で、画像の表示やキャラの移動など、ゲーム制作には欠かせない基礎知識が身についたのではない

【Gitの使い方 – その3】Gitで実際にバージョン管理してみよう!

お魚くわえた@It_is_Rです。 Gitの使い方第3回目の今回は、実際にGitを使ってバージョン管理をしてみようと思います。 [serif name="It is R"]りこ師匠

WordPress テーマ自作!投稿ページ、固定ページの作り方。

サンタは何故お爺さんなんでしょうか。@It_is_Rです。 今年からサンタのギャルにしましょう。 WordPress テーマ自作シリーズ第7回目です。 今回は、投稿ページと固定ページを作って

【Android Studio】レイアウト( Layout )の種類を覚えよう!

服に膝を入れるのが癖です。@It_is_Rです。 Androidアプリ開発、9回目となりました。 さて今回は、ボタンやテキストのレイアウトを整える方法を、解説していきたいと思います。

【CSS設計】ボタンを作って覚える。機能ごとに分けて作る重要性。

手が回らない、頭が回らない、口が回らない。@It_is_Rです。 CSSはある程度大雑把に書いても動かすことができます。しかし、CSSを覚える上で一番難しい部分と言えばCSS設計でしょう。 パ

Yarn

Yarn の使い方。インストールの方法から使い方まで解説します。

最近ドラクエにはまっている@It_is_Rです。PS1 のやつです。ドラクエⅦ。 関係ない話はさておき、今回は Yarn の使い方を解説していきたいと思います。 Yarn とは

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

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

コメントをどうぞ!

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